Merge branch 'develop' of https://github.com/gravitl/netmaker into ACC-638

This commit is contained in:
abhishek9686 2024-08-22 12:43:38 +05:30
commit fc2fff9f9d
12 changed files with 530 additions and 486 deletions

View file

@ -81,49 +81,59 @@ func upgradeHost(w http.ResponseWriter, r *http.Request) {
func getHosts(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
currentHosts := []models.Host{}
username := r.Header.Get("user")
user, err := logic.GetUser(username)
if err != nil {
return
}
userPlatformRole, err := logic.GetRole(user.PlatformRoleID)
if err != nil {
return
}
respHostsMap := make(map[string]struct{})
if !userPlatformRole.FullAccess {
nodes, err := logic.GetAllNodes()
if err != nil {
logger.Log(0, "error fetching all nodes info: ", err.Error())
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
return
}
filteredNodes := logic.GetFilteredNodesByUserAccess(*user, nodes)
if len(filteredNodes) > 0 {
currentHostsMap, err := logic.GetHostsMap()
if err != nil {
logger.Log(0, r.Header.Get("user"), "failed to fetch hosts: ", err.Error())
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
return
}
for _, node := range filteredNodes {
if _, ok := respHostsMap[node.HostID.String()]; ok {
continue
}
if host, ok := currentHostsMap[node.HostID.String()]; ok {
currentHosts = append(currentHosts, host)
respHostsMap[host.ID.String()] = struct{}{}
}
}
}
} else {
var err error
if r.Header.Get("ismaster") == "yes" {
currentHosts, err = logic.GetAllHosts()
if err != nil {
logger.Log(0, r.Header.Get("user"), "failed to fetch hosts: ", err.Error())
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
return
}
} else {
username := r.Header.Get("user")
user, err := logic.GetUser(username)
if err != nil {
return
}
userPlatformRole, err := logic.GetRole(user.PlatformRoleID)
if err != nil {
return
}
respHostsMap := make(map[string]struct{})
if !userPlatformRole.FullAccess {
nodes, err := logic.GetAllNodes()
if err != nil {
logger.Log(0, "error fetching all nodes info: ", err.Error())
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
return
}
filteredNodes := logic.GetFilteredNodesByUserAccess(*user, nodes)
if len(filteredNodes) > 0 {
currentHostsMap, err := logic.GetHostsMap()
if err != nil {
logger.Log(0, r.Header.Get("user"), "failed to fetch hosts: ", err.Error())
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
return
}
for _, node := range filteredNodes {
if _, ok := respHostsMap[node.HostID.String()]; ok {
continue
}
if host, ok := currentHostsMap[node.HostID.String()]; ok {
currentHosts = append(currentHosts, host)
respHostsMap[host.ID.String()] = struct{}{}
}
}
}
} else {
currentHosts, err = logic.GetAllHosts()
if err != nil {
logger.Log(0, r.Header.Get("user"), "failed to fetch hosts: ", err.Error())
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
return
}
}
}
apiHosts := logic.GetAllHostsAPI(currentHosts[:])

View file

@ -58,13 +58,16 @@ func getNetworks(w http.ResponseWriter, r *http.Request) {
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
return
}
username := r.Header.Get("user")
user, err := logic.GetUser(username)
if err != nil {
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
return
if r.Header.Get("ismaster") != "yes" {
username := r.Header.Get("user")
user, err := logic.GetUser(username)
if err != nil {
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
return
}
allnetworks = logic.FilterNetworksByRole(allnetworks, *user)
}
allnetworks = logic.FilterNetworksByRole(allnetworks, *user)
logger.Log(2, r.Header.Get("user"), "fetched networks.")
logic.SortNetworks(allnetworks[:])
w.WriteHeader(http.StatusOK)

View file

@ -268,56 +268,59 @@ func getNetworkNodes(w http.ResponseWriter, r *http.Request) {
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
return
}
username := r.Header.Get("user")
user, err := logic.GetUser(username)
if err != nil {
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
return
}
userPlatformRole, err := logic.GetRole(user.PlatformRoleID)
if err != nil {
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
return
}
filteredNodes := []models.Node{}
if !userPlatformRole.FullAccess {
nodesMap := make(map[string]struct{})
networkRoles := user.NetworkRoles[models.NetworkID(networkName)]
for networkRoleID := range networkRoles {
userPermTemplate, err := logic.GetRole(networkRoleID)
if err != nil {
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
return
}
if userPermTemplate.FullAccess {
break
}
if rsrcPerms, ok := userPermTemplate.NetworkLevelAccess[models.RemoteAccessGwRsrc]; ok {
if _, ok := rsrcPerms[models.AllRemoteAccessGwRsrcID]; ok {
for _, node := range nodes {
if _, ok := nodesMap[node.ID.String()]; ok {
continue
if r.Header.Get("ismaster") != "yes" {
username := r.Header.Get("user")
user, err := logic.GetUser(username)
if err != nil {
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
return
}
userPlatformRole, err := logic.GetRole(user.PlatformRoleID)
if err != nil {
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
return
}
if !userPlatformRole.FullAccess {
nodesMap := make(map[string]struct{})
networkRoles := user.NetworkRoles[models.NetworkID(networkName)]
for networkRoleID := range networkRoles {
userPermTemplate, err := logic.GetRole(networkRoleID)
if err != nil {
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
return
}
if userPermTemplate.FullAccess {
break
}
if rsrcPerms, ok := userPermTemplate.NetworkLevelAccess[models.RemoteAccessGwRsrc]; ok {
if _, ok := rsrcPerms[models.AllRemoteAccessGwRsrcID]; ok {
for _, node := range nodes {
if _, ok := nodesMap[node.ID.String()]; ok {
continue
}
if node.IsIngressGateway {
nodesMap[node.ID.String()] = struct{}{}
filteredNodes = append(filteredNodes, node)
}
}
if node.IsIngressGateway {
nodesMap[node.ID.String()] = struct{}{}
filteredNodes = append(filteredNodes, node)
}
}
} else {
for gwID, scope := range rsrcPerms {
if _, ok := nodesMap[gwID.String()]; ok {
continue
}
if scope.Read {
gwNode, err := logic.GetNodeByID(gwID.String())
if err == nil && gwNode.IsIngressGateway {
filteredNodes = append(filteredNodes, gwNode)
} else {
for gwID, scope := range rsrcPerms {
if _, ok := nodesMap[gwID.String()]; ok {
continue
}
if scope.Read {
gwNode, err := logic.GetNodeByID(gwID.String())
if err == nil && gwNode.IsIngressGateway {
filteredNodes = append(filteredNodes, gwNode)
}
}
}
}
}
}
}
}
}
if len(filteredNodes) > 0 {
@ -348,18 +351,19 @@ func getAllNodes(w http.ResponseWriter, r *http.Request) {
return
}
username := r.Header.Get("user")
user, err := logic.GetUser(username)
if err != nil {
return
if r.Header.Get("ismaster") == "no" {
user, err := logic.GetUser(username)
if err != nil {
return
}
userPlatformRole, err := logic.GetRole(user.PlatformRoleID)
if err != nil {
return
}
if !userPlatformRole.FullAccess {
nodes = logic.GetFilteredNodesByUserAccess(*user, nodes)
}
}
userPlatformRole, err := logic.GetRole(user.PlatformRoleID)
if err != nil {
return
}
if !userPlatformRole.FullAccess {
nodes = logic.GetFilteredNodesByUserAccess(*user, nodes)
}
// return all the nodes in JSON/API format
apiNodes := logic.GetAllNodesAPI(nodes[:])
logger.Log(3, r.Header.Get("user"), "fetched all nodes they have access to")

View file

@ -1,376 +1,361 @@
package controller
import (
"bytes"
"io"
"net/http"
"net/http/httptest"
"testing"
// TODO: Need Update Tests for New User Mgmt
// func deleteAllUsers(t *testing.T) {
// t.Helper()
// users, _ := logic.GetUsers()
// for _, user := range users {
// if _, err := logic.DeleteUser(user.UserName); err != nil {
// t.Fatal(err)
// }
// }
// }
"github.com/go-jose/go-jose/v3/json"
"github.com/gorilla/mux"
// func TestGetUserNoHashedPassword(t *testing.T) {
// // prepare existing user base
// user := models.User{UserName: "freddie", Password: "password"}
// haveOnlyOneUser(t, user)
"github.com/stretchr/testify/assert"
// // prepare request
// rec, req := prepareUserRequest(t, models.User{}, user.UserName)
"github.com/gravitl/netmaker/logic"
"github.com/gravitl/netmaker/models"
)
// // test response
// getUser(rec, req)
// assertUserNameButNoPassword(t, rec.Body, user.UserName)
// }
func deleteAllUsers(t *testing.T) {
t.Helper()
users, _ := logic.GetUsers()
for _, user := range users {
if _, err := logic.DeleteUser(user.UserName); err != nil {
t.Fatal(err)
}
}
}
// func TestCreateAdminNoHashedPassword(t *testing.T) {
// // prepare existing user base
// deleteAllUsers(t)
func TestGetUserNoHashedPassword(t *testing.T) {
// prepare existing user base
user := models.User{UserName: "freddie", Password: "password"}
haveOnlyOneUser(t, user)
// // prepare request
// user := models.User{UserName: "jonathan", Password: "password"}
// rec, req := prepareUserRequest(t, user, "")
// prepare request
rec, req := prepareUserRequest(t, models.User{}, user.UserName)
// // test response
// createSuperAdmin(rec, req)
// assertUserNameButNoPassword(t, rec.Body, user.UserName)
// }
// test response
getUser(rec, req)
assertUserNameButNoPassword(t, rec.Body, user.UserName)
}
// func prepareUserRequest(t *testing.T, userForBody models.User, userNameForParam string) (*httptest.ResponseRecorder, *http.Request) {
// bits, err := json.Marshal(userForBody)
// assert.Nil(t, err)
// body := bytes.NewReader(bits)
// rec := httptest.NewRecorder()
// req := httptest.NewRequest("ANY", "https://example.com", body) // only the body matters here
// req = mux.SetURLVars(req, map[string]string{"username": userNameForParam})
// req.Header.Set("user", userForBody.UserName)
// return rec, req
// }
func TestCreateAdminNoHashedPassword(t *testing.T) {
// prepare existing user base
deleteAllUsers(t)
// func haveOnlyOneUser(t *testing.T, user models.User) {
// deleteAllUsers(t)
// var err error
// if user.PlatformRoleID == models.SuperAdminRole {
// err = logic.CreateSuperAdmin(&user)
// } else {
// err = logic.CreateUser(&user)
// }
// assert.Nil(t, err)
// }
// prepare request
user := models.User{UserName: "jonathan", Password: "password"}
rec, req := prepareUserRequest(t, user, "")
// func assertUserNameButNoPassword(t *testing.T, r io.Reader, userName string) {
// var resp models.User
// err := json.NewDecoder(r).Decode(&resp)
// assert.Nil(t, err)
// assert.Equal(t, userName, resp.UserName)
// assert.Empty(t, resp.Password)
// }
// test response
createSuperAdmin(rec, req)
assertUserNameButNoPassword(t, rec.Body, user.UserName)
}
func prepareUserRequest(t *testing.T, userForBody models.User, userNameForParam string) (*httptest.ResponseRecorder, *http.Request) {
bits, err := json.Marshal(userForBody)
assert.Nil(t, err)
body := bytes.NewReader(bits)
rec := httptest.NewRecorder()
req := httptest.NewRequest("ANY", "https://example.com", body) // only the body matters here
req = mux.SetURLVars(req, map[string]string{"username": userNameForParam})
req.Header.Set("user", userForBody.UserName)
return rec, req
}
func haveOnlyOneUser(t *testing.T, user models.User) {
deleteAllUsers(t)
var err error
if user.PlatformRoleID == models.SuperAdminRole {
err = logic.CreateSuperAdmin(&user)
} else {
err = logic.CreateUser(&user)
}
assert.Nil(t, err)
}
func assertUserNameButNoPassword(t *testing.T, r io.Reader, userName string) {
var resp models.User
err := json.NewDecoder(r).Decode(&resp)
assert.Nil(t, err)
assert.Equal(t, userName, resp.UserName)
assert.Empty(t, resp.Password)
}
func TestHasSuperAdmin(t *testing.T) {
// delete all current users
users, _ := logic.GetUsers()
for _, user := range users {
success, err := logic.DeleteUser(user.UserName)
assert.Nil(t, err)
assert.True(t, success)
}
t.Run("NoUser", func(t *testing.T) {
found, err := logic.HasSuperAdmin()
assert.Nil(t, err)
assert.False(t, found)
})
t.Run("No superadmin user", func(t *testing.T) {
var user = models.User{UserName: "nosuperadmin", Password: "password"}
err := logic.CreateUser(&user)
assert.Nil(t, err)
found, err := logic.HasSuperAdmin()
assert.Nil(t, err)
assert.False(t, found)
})
t.Run("superadmin user", func(t *testing.T) {
var user = models.User{UserName: "superadmin", Password: "password", PlatformRoleID: models.SuperAdminRole}
err := logic.CreateUser(&user)
assert.Nil(t, err)
found, err := logic.HasSuperAdmin()
assert.Nil(t, err)
assert.True(t, found)
})
t.Run("multiple superadmins", func(t *testing.T) {
var user = models.User{UserName: "superadmin1", Password: "password", PlatformRoleID: models.SuperAdminRole}
err := logic.CreateUser(&user)
assert.Nil(t, err)
found, err := logic.HasSuperAdmin()
assert.Nil(t, err)
assert.True(t, found)
})
}
func TestCreateUser(t *testing.T) {
deleteAllUsers(t)
user := models.User{UserName: "admin", Password: "password", PlatformRoleID: models.AdminRole}
t.Run("NoUser", func(t *testing.T) {
err := logic.CreateUser(&user)
assert.Nil(t, err)
})
t.Run("UserExists", func(t *testing.T) {
err := logic.CreateUser(&user)
assert.NotNil(t, err)
assert.EqualError(t, err, "user exists")
})
}
func TestCreateSuperAdmin(t *testing.T) {
deleteAllUsers(t)
logic.ClearSuperUserCache()
var user models.User
t.Run("NoSuperAdmin", func(t *testing.T) {
user.UserName = "admin"
user.Password = "password"
err := logic.CreateSuperAdmin(&user)
assert.Nil(t, err)
})
t.Run("SuperAdminExists", func(t *testing.T) {
user.UserName = "admin2"
user.Password = "password1"
err := logic.CreateSuperAdmin(&user)
assert.EqualError(t, err, "superadmin user already exists")
})
}
func TestDeleteUser(t *testing.T) {
deleteAllUsers(t)
t.Run("NonExistent User", func(t *testing.T) {
deleted, err := logic.DeleteUser("admin")
assert.EqualError(t, err, "user does not exist")
assert.False(t, deleted)
})
t.Run("Existing User", func(t *testing.T) {
user := models.User{UserName: "admin", Password: "password", PlatformRoleID: models.AdminRole}
if err := logic.CreateUser(&user); err != nil {
t.Fatal(err)
}
deleted, err := logic.DeleteUser("admin")
assert.Nil(t, err)
assert.True(t, deleted)
})
}
func TestValidateUser(t *testing.T) {
var user models.User
t.Run("Valid Create", func(t *testing.T) {
user.UserName = "admin"
user.Password = "validpass"
err := logic.ValidateUser(&user)
assert.Nil(t, err)
})
t.Run("Valid Update", func(t *testing.T) {
user.UserName = "admin"
user.Password = "password"
err := logic.ValidateUser(&user)
assert.Nil(t, err)
})
t.Run("Invalid UserName", func(t *testing.T) {
t.Skip()
user.UserName = "*invalid"
err := logic.ValidateUser(&user)
assert.Error(t, err)
// assert.Contains(t, err.Error(), "Field validation for 'UserName' failed")
})
t.Run("Short UserName", func(t *testing.T) {
t.Skip()
user.UserName = "1"
err := logic.ValidateUser(&user)
assert.NotNil(t, err)
// assert.Contains(t, err.Error(), "Field validation for 'UserName' failed")
})
t.Run("Empty UserName", func(t *testing.T) {
t.Skip()
user.UserName = ""
err := logic.ValidateUser(&user)
assert.EqualError(t, err, "some string")
// assert.Contains(t, err.Error(), "Field validation for 'UserName' failed")
})
t.Run("EmptyPassword", func(t *testing.T) {
user.Password = ""
err := logic.ValidateUser(&user)
assert.EqualError(t, err, "Key: 'User.Password' Error:Field validation for 'Password' failed on the 'required' tag")
})
t.Run("ShortPassword", func(t *testing.T) {
user.Password = "123"
err := logic.ValidateUser(&user)
assert.EqualError(t, err, "Key: 'User.Password' Error:Field validation for 'Password' failed on the 'min' tag")
})
}
func TestGetUser(t *testing.T) {
deleteAllUsers(t)
user := models.User{UserName: "admin", Password: "password", PlatformRoleID: models.AdminRole}
t.Run("NonExistantUser", func(t *testing.T) {
admin, err := logic.GetUser("admin")
assert.EqualError(t, err, "could not find any records")
assert.Equal(t, "", admin.UserName)
})
t.Run("UserExisits", func(t *testing.T) {
if err := logic.CreateUser(&user); err != nil {
t.Error(err)
}
admin, err := logic.GetUser("admin")
assert.Nil(t, err)
assert.Equal(t, user.UserName, admin.UserName)
})
}
func TestGetUsers(t *testing.T) {
deleteAllUsers(t)
adminUser := models.User{UserName: "admin", Password: "password", PlatformRoleID: models.AdminRole}
user := models.User{UserName: "admin", Password: "password", PlatformRoleID: models.AdminRole}
t.Run("NonExistantUser", func(t *testing.T) {
admin, err := logic.GetUsers()
assert.EqualError(t, err, "could not find any records")
assert.Equal(t, []models.ReturnUser(nil), admin)
})
t.Run("UserExisits", func(t *testing.T) {
user.UserName = "anotheruser"
if err := logic.CreateUser(&adminUser); err != nil {
t.Error(err)
}
admins, err := logic.GetUsers()
assert.Nil(t, err)
assert.Equal(t, adminUser.UserName, admins[0].UserName)
})
t.Run("MulipleUsers", func(t *testing.T) {
if err := logic.CreateUser(&user); err != nil {
t.Error(err)
}
admins, err := logic.GetUsers()
assert.Nil(t, err)
for _, u := range admins {
if u.UserName == "admin" {
assert.Equal(t, true, u.IsAdmin)
} else {
assert.Equal(t, user.UserName, u.UserName)
assert.Equal(t, user.PlatformRoleID, u.PlatformRoleID)
}
}
})
}
func TestUpdateUser(t *testing.T) {
deleteAllUsers(t)
user := models.User{UserName: "admin", Password: "password", PlatformRoleID: models.AdminRole}
newuser := models.User{UserName: "hello", Password: "world", PlatformRoleID: models.AdminRole}
t.Run("NonExistantUser", func(t *testing.T) {
admin, err := logic.UpdateUser(&newuser, &user)
assert.EqualError(t, err, "could not find any records")
assert.Equal(t, "", admin.UserName)
})
t.Run("UserExists", func(t *testing.T) {
if err := logic.CreateUser(&user); err != nil {
t.Error(err)
}
admin, err := logic.UpdateUser(&newuser, &user)
assert.Nil(t, err)
assert.Equal(t, newuser.UserName, admin.UserName)
})
}
// func TestValidateUserToken(t *testing.T) {
// t.Run("EmptyToken", func(t *testing.T) {
// err := ValidateUserToken("", "", false)
// assert.NotNil(t, err)
// assert.Equal(t, "Missing Auth Token.", err.Error())
// })
// t.Run("InvalidToken", func(t *testing.T) {
// err := ValidateUserToken("Bearer: badtoken", "", false)
// assert.NotNil(t, err)
// assert.Equal(t, "Error Verifying Auth Token", err.Error())
// })
// t.Run("InvalidUser", func(t *testing.T) {
// t.Skip()
// err := ValidateUserToken("Bearer: secretkey", "baduser", false)
// assert.NotNil(t, err)
// assert.Equal(t, "Error Verifying Auth Token", err.Error())
// //need authorization
// })
// t.Run("ValidToken", func(t *testing.T) {
// err := ValidateUserToken("Bearer: secretkey", "", true)
// func TestHasSuperAdmin(t *testing.T) {
// // delete all current users
// users, _ := logic.GetUsers()
// for _, user := range users {
// success, err := logic.DeleteUser(user.UserName)
// assert.Nil(t, err)
// assert.True(t, success)
// }
// t.Run("NoUser", func(t *testing.T) {
// found, err := logic.HasSuperAdmin()
// assert.Nil(t, err)
// assert.False(t, found)
// })
// t.Run("No superadmin user", func(t *testing.T) {
// var user = models.User{UserName: "nosuperadmin", Password: "password"}
// err := logic.CreateUser(&user)
// assert.Nil(t, err)
// found, err := logic.HasSuperAdmin()
// assert.Nil(t, err)
// assert.False(t, found)
// })
// t.Run("superadmin user", func(t *testing.T) {
// var user = models.User{UserName: "superadmin", Password: "password", PlatformRoleID: models.SuperAdminRole}
// err := logic.CreateUser(&user)
// assert.Nil(t, err)
// found, err := logic.HasSuperAdmin()
// assert.Nil(t, err)
// assert.True(t, found)
// })
// t.Run("multiple superadmins", func(t *testing.T) {
// var user = models.User{UserName: "superadmin1", Password: "password", PlatformRoleID: models.SuperAdminRole}
// err := logic.CreateUser(&user)
// assert.Nil(t, err)
// found, err := logic.HasSuperAdmin()
// assert.Nil(t, err)
// assert.True(t, found)
// })
// }
func TestVerifyAuthRequest(t *testing.T) {
deleteAllUsers(t)
user := models.User{UserName: "admin", Password: "password", PlatformRoleID: models.AdminRole}
var authRequest models.UserAuthParams
t.Run("EmptyUserName", func(t *testing.T) {
authRequest.UserName = ""
authRequest.Password = "Password"
jwt, err := logic.VerifyAuthRequest(authRequest)
assert.Equal(t, "", jwt)
assert.EqualError(t, err, "username can't be empty")
})
t.Run("EmptyPassword", func(t *testing.T) {
authRequest.UserName = "admin"
authRequest.Password = ""
jwt, err := logic.VerifyAuthRequest(authRequest)
assert.Equal(t, "", jwt)
assert.EqualError(t, err, "password can't be empty")
})
t.Run("NonExistantUser", func(t *testing.T) {
authRequest.UserName = "admin"
authRequest.Password = "password"
jwt, err := logic.VerifyAuthRequest(authRequest)
assert.Equal(t, "", jwt)
assert.EqualError(t, err, "incorrect credentials")
})
t.Run("Non-Admin", func(t *testing.T) {
user.PlatformRoleID = models.ServiceUser
user.Password = "somepass"
user.UserName = "nonadmin"
if err := logic.CreateUser(&user); err != nil {
t.Error(err)
}
authRequest := models.UserAuthParams{UserName: "nonadmin", Password: "somepass"}
jwt, err := logic.VerifyAuthRequest(authRequest)
assert.NotNil(t, jwt)
assert.Nil(t, err)
})
t.Run("WrongPassword", func(t *testing.T) {
user := models.User{UserName: "admin", Password: "password"}
if err := logic.CreateUser(&user); err != nil {
t.Error(err)
}
authRequest := models.UserAuthParams{UserName: "admin", Password: "badpass"}
jwt, err := logic.VerifyAuthRequest(authRequest)
assert.Equal(t, "", jwt)
assert.EqualError(t, err, "incorrect credentials")
})
t.Run("Success", func(t *testing.T) {
authRequest := models.UserAuthParams{UserName: "admin", Password: "password"}
jwt, err := logic.VerifyAuthRequest(authRequest)
assert.Nil(t, err)
assert.NotNil(t, jwt)
})
}
// func TestCreateUser(t *testing.T) {
// deleteAllUsers(t)
// user := models.User{UserName: "admin", Password: "password", PlatformRoleID: models.AdminRole}
// t.Run("NoUser", func(t *testing.T) {
// err := logic.CreateUser(&user)
// assert.Nil(t, err)
// })
// t.Run("UserExists", func(t *testing.T) {
// err := logic.CreateUser(&user)
// assert.NotNil(t, err)
// assert.EqualError(t, err, "user exists")
// })
// }
// func TestCreateSuperAdmin(t *testing.T) {
// deleteAllUsers(t)
// logic.ClearSuperUserCache()
// var user models.User
// t.Run("NoSuperAdmin", func(t *testing.T) {
// user.UserName = "admin"
// user.Password = "password"
// err := logic.CreateSuperAdmin(&user)
// assert.Nil(t, err)
// })
// t.Run("SuperAdminExists", func(t *testing.T) {
// user.UserName = "admin2"
// user.Password = "password1"
// err := logic.CreateSuperAdmin(&user)
// assert.EqualError(t, err, "superadmin user already exists")
// })
// }
// func TestDeleteUser(t *testing.T) {
// deleteAllUsers(t)
// t.Run("NonExistent User", func(t *testing.T) {
// deleted, err := logic.DeleteUser("admin")
// assert.EqualError(t, err, "user does not exist")
// assert.False(t, deleted)
// })
// t.Run("Existing User", func(t *testing.T) {
// user := models.User{UserName: "admin", Password: "password", PlatformRoleID: models.AdminRole}
// if err := logic.CreateUser(&user); err != nil {
// t.Fatal(err)
// }
// deleted, err := logic.DeleteUser("admin")
// assert.Nil(t, err)
// assert.True(t, deleted)
// })
// }
// func TestValidateUser(t *testing.T) {
// var user models.User
// t.Run("Valid Create", func(t *testing.T) {
// user.UserName = "admin"
// user.Password = "validpass"
// err := logic.ValidateUser(&user)
// assert.Nil(t, err)
// })
// t.Run("Valid Update", func(t *testing.T) {
// user.UserName = "admin"
// user.Password = "password"
// err := logic.ValidateUser(&user)
// assert.Nil(t, err)
// })
// t.Run("Invalid UserName", func(t *testing.T) {
// t.Skip()
// user.UserName = "*invalid"
// err := logic.ValidateUser(&user)
// assert.Error(t, err)
// // assert.Contains(t, err.Error(), "Field validation for 'UserName' failed")
// })
// t.Run("Short UserName", func(t *testing.T) {
// t.Skip()
// user.UserName = "1"
// err := logic.ValidateUser(&user)
// assert.NotNil(t, err)
// // assert.Contains(t, err.Error(), "Field validation for 'UserName' failed")
// })
// t.Run("Empty UserName", func(t *testing.T) {
// t.Skip()
// user.UserName = ""
// err := logic.ValidateUser(&user)
// assert.EqualError(t, err, "some string")
// // assert.Contains(t, err.Error(), "Field validation for 'UserName' failed")
// })
// t.Run("EmptyPassword", func(t *testing.T) {
// user.Password = ""
// err := logic.ValidateUser(&user)
// assert.EqualError(t, err, "Key: 'User.Password' Error:Field validation for 'Password' failed on the 'required' tag")
// })
// t.Run("ShortPassword", func(t *testing.T) {
// user.Password = "123"
// err := logic.ValidateUser(&user)
// assert.EqualError(t, err, "Key: 'User.Password' Error:Field validation for 'Password' failed on the 'min' tag")
// })
// }
// func TestGetUser(t *testing.T) {
// deleteAllUsers(t)
// user := models.User{UserName: "admin", Password: "password", PlatformRoleID: models.AdminRole}
// t.Run("NonExistantUser", func(t *testing.T) {
// admin, err := logic.GetUser("admin")
// assert.EqualError(t, err, "could not find any records")
// assert.Equal(t, "", admin.UserName)
// })
// t.Run("UserExisits", func(t *testing.T) {
// if err := logic.CreateUser(&user); err != nil {
// t.Error(err)
// }
// admin, err := logic.GetUser("admin")
// assert.Nil(t, err)
// assert.Equal(t, user.UserName, admin.UserName)
// })
// }
// func TestGetUsers(t *testing.T) {
// deleteAllUsers(t)
// adminUser := models.User{UserName: "admin", Password: "password", PlatformRoleID: models.AdminRole}
// user := models.User{UserName: "admin", Password: "password", PlatformRoleID: models.AdminRole}
// t.Run("NonExistantUser", func(t *testing.T) {
// admin, err := logic.GetUsers()
// assert.EqualError(t, err, "could not find any records")
// assert.Equal(t, []models.ReturnUser(nil), admin)
// })
// t.Run("UserExisits", func(t *testing.T) {
// user.UserName = "anotheruser"
// if err := logic.CreateUser(&adminUser); err != nil {
// t.Error(err)
// }
// admins, err := logic.GetUsers()
// assert.Nil(t, err)
// assert.Equal(t, adminUser.UserName, admins[0].UserName)
// })
// t.Run("MulipleUsers", func(t *testing.T) {
// if err := logic.CreateUser(&user); err != nil {
// t.Error(err)
// }
// admins, err := logic.GetUsers()
// assert.Nil(t, err)
// for _, u := range admins {
// if u.UserName == "admin" {
// assert.Equal(t, true, u.IsAdmin)
// } else {
// assert.Equal(t, user.UserName, u.UserName)
// assert.Equal(t, user.PlatformRoleID, u.PlatformRoleID)
// }
// }
// })
// }
// func TestUpdateUser(t *testing.T) {
// deleteAllUsers(t)
// user := models.User{UserName: "admin", Password: "password", PlatformRoleID: models.AdminRole}
// newuser := models.User{UserName: "hello", Password: "world", PlatformRoleID: models.AdminRole}
// t.Run("NonExistantUser", func(t *testing.T) {
// admin, err := logic.UpdateUser(&newuser, &user)
// assert.EqualError(t, err, "could not find any records")
// assert.Equal(t, "", admin.UserName)
// })
// t.Run("UserExists", func(t *testing.T) {
// if err := logic.CreateUser(&user); err != nil {
// t.Error(err)
// }
// admin, err := logic.UpdateUser(&newuser, &user)
// assert.Nil(t, err)
// assert.Equal(t, newuser.UserName, admin.UserName)
// })
// }
// // func TestValidateUserToken(t *testing.T) {
// // t.Run("EmptyToken", func(t *testing.T) {
// // err := ValidateUserToken("", "", false)
// // assert.NotNil(t, err)
// // assert.Equal(t, "Missing Auth Token.", err.Error())
// // })
// // t.Run("InvalidToken", func(t *testing.T) {
// // err := ValidateUserToken("Bearer: badtoken", "", false)
// // assert.NotNil(t, err)
// // assert.Equal(t, "Error Verifying Auth Token", err.Error())
// // })
// // t.Run("InvalidUser", func(t *testing.T) {
// // t.Skip()
// // err := ValidateUserToken("Bearer: secretkey", "baduser", false)
// // assert.NotNil(t, err)
// // assert.Equal(t, "Error Verifying Auth Token", err.Error())
// // //need authorization
// // })
// // t.Run("ValidToken", func(t *testing.T) {
// // err := ValidateUserToken("Bearer: secretkey", "", true)
// // assert.Nil(t, err)
// // })
// // }
// func TestVerifyAuthRequest(t *testing.T) {
// deleteAllUsers(t)
// user := models.User{UserName: "admin", Password: "password", PlatformRoleID: models.AdminRole}
// var authRequest models.UserAuthParams
// t.Run("EmptyUserName", func(t *testing.T) {
// authRequest.UserName = ""
// authRequest.Password = "Password"
// jwt, err := logic.VerifyAuthRequest(authRequest)
// assert.Equal(t, "", jwt)
// assert.EqualError(t, err, "username can't be empty")
// })
// t.Run("EmptyPassword", func(t *testing.T) {
// authRequest.UserName = "admin"
// authRequest.Password = ""
// jwt, err := logic.VerifyAuthRequest(authRequest)
// assert.Equal(t, "", jwt)
// assert.EqualError(t, err, "password can't be empty")
// })
// t.Run("NonExistantUser", func(t *testing.T) {
// authRequest.UserName = "admin"
// authRequest.Password = "password"
// jwt, err := logic.VerifyAuthRequest(authRequest)
// assert.Equal(t, "", jwt)
// assert.EqualError(t, err, "incorrect credentials")
// })
// t.Run("Non-Admin", func(t *testing.T) {
// user.PlatformRoleID = models.ServiceUser
// user.Password = "somepass"
// user.UserName = "nonadmin"
// if err := logic.CreateUser(&user); err != nil {
// t.Error(err)
// }
// authRequest := models.UserAuthParams{UserName: "nonadmin", Password: "somepass"}
// jwt, err := logic.VerifyAuthRequest(authRequest)
// assert.NotNil(t, jwt)
// assert.Nil(t, err)
// })
// t.Run("WrongPassword", func(t *testing.T) {
// user := models.User{UserName: "admin", Password: "password"}
// if err := logic.CreateUser(&user); err != nil {
// t.Error(err)
// }
// authRequest := models.UserAuthParams{UserName: "admin", Password: "badpass"}
// jwt, err := logic.VerifyAuthRequest(authRequest)
// assert.Equal(t, "", jwt)
// assert.EqualError(t, err, "incorrect credentials")
// })
// t.Run("Success", func(t *testing.T) {
// authRequest := models.UserAuthParams{UserName: "admin", Password: "password"}
// jwt, err := logic.VerifyAuthRequest(authRequest)
// assert.Nil(t, err)
// assert.NotNil(t, jwt)
// })
// }

11
go.mod
View file

@ -3,7 +3,7 @@ module github.com/gravitl/netmaker
go 1.19
require (
github.com/eclipse/paho.mqtt.golang v1.5.0
github.com/eclipse/paho.mqtt.golang v1.4.3
github.com/go-playground/validator/v10 v10.22.0
github.com/golang-jwt/jwt/v4 v4.5.0
github.com/google/uuid v1.6.0
@ -16,10 +16,10 @@ require (
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
github.com/stretchr/testify v1.9.0
github.com/txn2/txeh v1.5.5
golang.org/x/crypto v0.25.0
golang.org/x/net v0.27.0 // indirect
golang.org/x/crypto v0.23.0
golang.org/x/net v0.23.0 // indirect
golang.org/x/oauth2 v0.21.0
golang.org/x/sys v0.22.0 // indirect
golang.org/x/sys v0.21.0 // indirect
golang.org/x/text v0.16.0 // indirect
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20221104135756-97bc4ad4a1cb
gopkg.in/yaml.v3 v3.0.1
@ -28,7 +28,7 @@ require (
require (
filippo.io/edwards25519 v1.1.0
github.com/c-robinson/iplib v1.0.8
github.com/posthog/posthog-go v1.2.18
github.com/posthog/posthog-go v0.0.0-20211028072449-93c17c49e2b0
)
require (
@ -54,6 +54,7 @@ require (
github.com/rivo/uniseg v0.2.0 // indirect
github.com/seancfoley/bintree v1.3.1 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c // indirect
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
)

18
go.sum
View file

@ -2,14 +2,18 @@ cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2Qx
cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/c-robinson/iplib v1.0.8 h1:exDRViDyL9UBLcfmlxxkY5odWX5092nPsQIykHXhIn4=
github.com/c-robinson/iplib v1.0.8/go.mod h1:i3LuuFL1hRT5gFpBRnEydzw8R6yhGkF4szNDIbF8pgo=
github.com/coreos/go-oidc/v3 v3.9.0 h1:0J/ogVOd4y8P0f0xUh8l9t07xRP/d8tccvjHl2dcsSo=
github.com/coreos/go-oidc/v3 v3.9.0/go.mod h1:rTKz2PYwftcrtoCzV5g5kvfJoWcm0Mk8AF8y1iAQro4=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/eclipse/paho.mqtt.golang v1.4.3 h1:2kwcUGn8seMUfWndX0hGbvH8r7crgcJguQNCyp70xik=
github.com/eclipse/paho.mqtt.golang v1.4.3/go.mod h1:CSYvoAlsMkhYOXh/oKyxa8EcBci6dVkLCbo5tTC1RIE=
github.com/eclipse/paho.mqtt.golang v1.5.0 h1:EH+bUVJNgttidWFkLLVKaQPGmkTUfQQqjOsyvMGvD6o=
github.com/eclipse/paho.mqtt.golang v1.5.0/go.mod h1:du/2qNQVqJf/Sqs4MEL77kR8QTqANF7XU7Fk0aOTAgk=
github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk=
@ -59,6 +63,8 @@ github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posthog/posthog-go v0.0.0-20211028072449-93c17c49e2b0 h1:Y2hUrkfuM0on62KZOci/VLijlkdF/yeWU262BQgvcjE=
github.com/posthog/posthog-go v0.0.0-20211028072449-93c17c49e2b0/go.mod h1:oa2sAs9tGai3VldabTV0eWejt/O4/OOD7azP8GaikqU=
github.com/posthog/posthog-go v1.2.18 h1:2CBA0LOB0up+gon+xpeXuhFw69gZpjAYxQoBBGwiDWw=
github.com/posthog/posthog-go v1.2.18/go.mod h1:QjlpryJtfYLrZF2GUkAhejH4E7WlDbdKkvOi5hLmkdg=
github.com/resendlabs/resend-go v1.7.0 h1:DycOqSXtw2q7aB+Nt9DDJUDtaYcrNPGn1t5RFposas0=
@ -68,11 +74,13 @@ github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rqlite/gorqlite v0.0.0-20240122221808-a8a425b1a6aa h1:hxMLFbj+F444JAS5nUQxTDZwUxwCRqg3WkNqhiDzXrM=
github.com/rqlite/gorqlite v0.0.0-20240122221808-a8a425b1a6aa/go.mod h1:xF/KoXmrRyahPfo5L7Szb5cAAUl53dMWBh9cMruGEZg=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/seancfoley/bintree v1.3.1 h1:cqmmQK7Jm4aw8gna0bP+huu5leVOgHGSJBEpUx3EXGI=
github.com/seancfoley/bintree v1.3.1/go.mod h1:hIUabL8OFYyFVTQ6azeajbopogQc2l5C/hiXMcemWNU=
github.com/seancfoley/ipaddress-go v1.6.0 h1:9z7yGmOnV4P2ML/dlR/kCJiv5tp8iHOOetJvxJh/R5w=
github.com/seancfoley/ipaddress-go v1.6.0/go.mod h1:TQRZgv+9jdvzHmKoPGBMxyiaVmoI0rYpfEk8Q/sL/Iw=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0=
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M=
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
@ -85,10 +93,15 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/txn2/txeh v1.5.5 h1:UN4e/lCK5HGw/gGAi2GCVrNKg0GTCUWs7gs5riaZlz4=
github.com/txn2/txeh v1.5.5/go.mod h1:qYzGG9kCzeVEI12geK4IlanHWY8X4uy/I3NcW7mk8g4=
github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c h1:3lbZUMbMiGUW/LMkfsEABsc5zNT9+b1CvsJx47JzJ8g=
github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c/go.mod h1:UrdRz5enIKZ63MEE3IF9l2/ebyx59GyGgPi+tICQdmM=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc=
@ -100,6 +113,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs=
@ -117,6 +132,8 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
@ -145,6 +162,7 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/mail.v2 v2.3.1 h1:WYFn/oANrAGP2C0dcV6/pbkPzv8yGzqTjPmTeO7qoXk=
gopkg.in/mail.v2 v2.3.1/go.mod h1:htwXN1Qh09vZJ1NVKxQqHPBaCBbzKhp5GzuJEA4VJWw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View file

@ -165,24 +165,27 @@ func inviteUsers(w http.ResponseWriter, r *http.Request) {
return
}
callerUserName := r.Header.Get("user")
caller, err := logic.GetUser(callerUserName)
if err != nil {
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "notfound"))
return
}
if inviteReq.PlatformRoleID == models.SuperAdminRole.String() {
logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("super admin cannot be invited"), "badrequest"))
return
}
if inviteReq.PlatformRoleID == "" {
logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("platform role id cannot be empty"), "badrequest"))
return
}
if (inviteReq.PlatformRoleID == models.AdminRole.String() ||
inviteReq.PlatformRoleID == models.SuperAdminRole.String()) && caller.PlatformRoleID != models.SuperAdminRole {
logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("only superadmin can invite admin users"), "forbidden"))
return
if r.Header.Get("ismaster") != "yes" {
caller, err := logic.GetUser(callerUserName)
if err != nil {
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "notfound"))
return
}
if inviteReq.PlatformRoleID == models.SuperAdminRole.String() {
logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("super admin cannot be invited"), "badrequest"))
return
}
if inviteReq.PlatformRoleID == "" {
logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("platform role id cannot be empty"), "badrequest"))
return
}
if (inviteReq.PlatformRoleID == models.AdminRole.String() ||
inviteReq.PlatformRoleID == models.SuperAdminRole.String()) && caller.PlatformRoleID != models.SuperAdminRole {
logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("only superadmin can invite admin users"), "forbidden"))
return
}
}
//validate Req
err = proLogic.IsGroupsValid(inviteReq.UserGroups)
if err != nil {

View file

@ -18,12 +18,18 @@ const (
func init() {
switch EmailSenderType(servercfg.EmailSenderType()) {
case Smtp:
client = &SmtpSender{
smtpSender := &SmtpSender{
SmtpHost: servercfg.GetSmtpHost(),
SmtpPort: servercfg.GetSmtpPort(),
SenderEmail: servercfg.GetSenderEmail(),
SendUser: servercfg.GetSenderUser(),
SenderPass: servercfg.GetEmaiSenderAuth(),
}
if smtpSender.SendUser == "" {
smtpSender.SendUser = smtpSender.SenderEmail
}
client = smtpSender
case Resend:
client = NewResendEmailSenderFromConfig()
}

View file

@ -11,6 +11,7 @@ type SmtpSender struct {
SmtpHost string
SmtpPort int
SenderEmail string
SendUser string
SenderPass string
}
@ -27,7 +28,7 @@ func (s *SmtpSender) SendEmail(ctx context.Context, n Notification, e Mail) erro
// Set E-Mail body. You can set plain text or html with text/html
m.SetBody("text/html", e.GetBody(n))
// Settings for SMTP server
d := gomail.NewDialer(s.SmtpHost, s.SmtpPort, s.SenderEmail, s.SenderPass)
d := gomail.NewDialer(s.SmtpHost, s.SmtpPort, s.SendUser, s.SenderPass)
// This is only needed when SSL/TLS certificate is not valid on server.
// In production this should be set to false.

View file

@ -82,7 +82,9 @@ SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
# sender email
EMAIL_SENDER_ADDR=
# sender email auth
EMAIL_SENDER_AUTH=
# sender smtp user, if unset sender email will be used
EMAIL_SENDER_USER=
# sender smtp password
EMAIL_SENDER_PASSWORD=
# mail sender type (smtp or resend)
EMAIL_SENDER_TYPE=smtp
EMAIL_SENDER_TYPE=smtp

View file

@ -253,7 +253,8 @@ save_config() { (
"INSTALL_TYPE" "NODE_ID" "DNS_MODE" "NETCLIENT_AUTO_UPDATE" "API_PORT"
"CORS_ALLOWED_ORIGIN" "DISPLAY_KEYS" "DATABASE" "SERVER_BROKER_ENDPOINT" "VERBOSITY"
"DEBUG_MODE" "REST_BACKEND" "DISABLE_REMOTE_IP_CHECK" "TELEMETRY" "ALLOWED_EMAIL_DOMAINS" "AUTH_PROVIDER" "CLIENT_ID" "CLIENT_SECRET"
"FRONTEND_URL" "AZURE_TENANT" "OIDC_ISSUER" "EXPORTER_API_PORT" "JWT_VALIDITY_DURATION" "RAC_AUTO_DISABLE" "CACHING_ENABLED" "ENDPOINT_DETECTION")
"FRONTEND_URL" "AZURE_TENANT" "OIDC_ISSUER" "EXPORTER_API_PORT" "JWT_VALIDITY_DURATION" "RAC_AUTO_DISABLE" "CACHING_ENABLED" "ENDPOINT_DETECTION"
"SMTP_HOST" "SMTP_PORT" "EMAIL_SENDER_ADDR" "EMAIL_SENDER_USER" "EMAIL_SENDER_PASSWORD" "EMAIL_SENDER_TYPE")
for name in "${toCopy[@]}"; do
save_config_item $name "${!name}"
done

View file

@ -275,9 +275,19 @@ func GetSenderEmail() string {
return v
}
func GetSenderUser() string {
v := ""
if fromEnv := os.Getenv("EMAIL_SENDER_USER"); fromEnv != "" {
v = fromEnv
} else if fromCfg := config.Config.Server.EmailSenderAddr; fromCfg != "" {
v = fromCfg
}
return v
}
func GetEmaiSenderAuth() string {
v := ""
if fromEnv := os.Getenv("EMAIL_SENDER_AUTH"); fromEnv != "" {
if fromEnv := os.Getenv("EMAIL_SENDER_PASSWORD"); fromEnv != "" {
v = fromEnv
} else if fromCfg := config.Config.Server.EmailSenderAddr; fromCfg != "" {
v = fromCfg