mirror of
https://github.com/gravitl/netmaker.git
synced 2025-10-04 10:54:24 +08:00
Merge branch 'develop' of https://github.com/gravitl/netmaker into ACC-638
This commit is contained in:
commit
fc2fff9f9d
12 changed files with 530 additions and 486 deletions
|
@ -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[:])
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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
11
go.mod
|
@ -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
18
go.sum
|
@ -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=
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue