initial commit

This commit is contained in:
0xdcarns
2022-09-13 15:25:56 -04:00
parent 0da5c388b6
commit 88cd0a6497
79 changed files with 4146 additions and 160 deletions

View File

@@ -9,7 +9,9 @@ import (
"github.com/go-playground/validator/v10"
"github.com/gravitl/netmaker/database"
"github.com/gravitl/netmaker/logger"
"github.com/gravitl/netmaker/logic/pro"
"github.com/gravitl/netmaker/models"
"github.com/gravitl/netmaker/models/promodels"
"golang.org/x/crypto/bcrypt"
)
@@ -95,8 +97,7 @@ func CreateUser(user models.User) (models.User, error) {
// set password to encrypted password
user.Password = string(hash)
tokenString, _ := CreateUserJWT(user.UserName, user.Networks, user.IsAdmin)
tokenString, _ := CreateProUserJWT(user.UserName, user.Networks, user.Groups, user.IsAdmin)
if tokenString == "" {
// returnErrorResponse(w, r, errorResponse)
return user, err
@@ -108,8 +109,45 @@ func CreateUser(user models.User) (models.User, error) {
return user, err
}
err = database.Insert(user.UserName, string(data), database.USERS_TABLE_NAME)
if err != nil {
return user, err
}
return user, err
// == PRO == Add user to every network as network user ==
currentNets, err := GetNetworks()
if err != nil {
currentNets = []models.Network{}
}
for i := range currentNets {
newUser := promodels.NetworkUser{
ID: promodels.NetworkUserID(user.UserName),
Clients: []string{},
Nodes: []string{},
}
pro.AddProNetDefaults(&currentNets[i])
if pro.IsUserAllowed(&currentNets[i], user.UserName, user.Groups) {
newUser.AccessLevel = currentNets[i].ProSettings.DefaultAccessLevel
newUser.ClientLimit = currentNets[i].ProSettings.DefaultUserClientLimit
newUser.NodeLimit = currentNets[i].ProSettings.DefaultUserNodeLimit
} else {
newUser.AccessLevel = pro.NO_ACCESS
newUser.ClientLimit = 0
newUser.NodeLimit = 0
}
// legacy
if StringSliceContains(user.Networks, currentNets[i].NetID) {
newUser.AccessLevel = pro.NET_ADMIN
}
userErr := pro.CreateNetworkUser(&currentNets[i], &newUser)
if userErr != nil {
logger.Log(0, "failed to add network user data on network", currentNets[i].NetID, "for user", user.UserName)
}
}
// == END PRO ==
return user, nil
}
// CreateAdmin - creates an admin user
@@ -136,10 +174,10 @@ func VerifyAuthRequest(authRequest models.UserAuthParams) (string, error) {
//Search DB for node with Mac Address. Ignore pending nodes (they should not be able to authenticate with API until approved).
record, err := database.FetchRecord(database.USERS_TABLE_NAME, authRequest.UserName)
if err != nil {
return "", errors.New("incorrect credentials")
return "", errors.New("error retrieving user from db: " + err.Error())
}
if err = json.Unmarshal([]byte(record), &result); err != nil {
return "", errors.New("incorrect credentials")
return "", errors.New("error unmarshalling user json: " + err.Error())
}
// compare password from request to stored password in database
@@ -150,14 +188,15 @@ func VerifyAuthRequest(authRequest models.UserAuthParams) (string, error) {
}
//Create a new JWT for the node
tokenString, _ := CreateUserJWT(authRequest.UserName, result.Networks, result.IsAdmin)
tokenString, _ := CreateProUserJWT(authRequest.UserName, result.Networks, result.Groups, result.IsAdmin)
return tokenString, nil
}
// UpdateUserNetworks - updates the networks of a given user
func UpdateUserNetworks(newNetworks []string, isadmin bool, currentUser *models.User) error {
func UpdateUserNetworks(newNetworks, newGroups []string, isadmin bool, currentUser *models.ReturnUser) error {
// check if user exists
if returnedUser, err := GetUser(currentUser.UserName); err != nil {
returnedUser, err := GetUser(currentUser.UserName)
if err != nil {
return err
} else if returnedUser.IsAdmin {
return fmt.Errorf("can not make changes to an admin user, attempted to change %s", returnedUser.UserName)
@@ -166,18 +205,46 @@ func UpdateUserNetworks(newNetworks []string, isadmin bool, currentUser *models.
currentUser.IsAdmin = true
currentUser.Networks = nil
} else {
// == PRO ==
currentUser.Groups = newGroups
for _, n := range newNetworks {
if !StringSliceContains(currentUser.Networks, n) {
// make net admin of any network not previously assigned
pro.MakeNetAdmin(n, currentUser.UserName)
}
}
// Compare networks, find networks not in previous
for _, n := range currentUser.Networks {
if !StringSliceContains(newNetworks, n) {
// if user was removed from a network, re-assign access to net default level
if network, err := GetNetwork(n); err == nil {
if network.ProSettings != nil {
ok := pro.AssignAccessLvl(n, currentUser.UserName, network.ProSettings.DefaultAccessLevel)
if ok {
logger.Log(0, "changed", currentUser.UserName, "access level on network", network.NetID, "to", fmt.Sprintf("%d", network.ProSettings.DefaultAccessLevel))
}
}
}
}
}
if err := AdjustGroupPermissions(currentUser); err != nil {
logger.Log(0, "failed to update user", currentUser.UserName, "after group update", err.Error())
}
// == END PRO ==
currentUser.Networks = newNetworks
}
data, err := json.Marshal(currentUser)
if err != nil {
return err
}
if err = database.Insert(currentUser.UserName, string(data), database.USERS_TABLE_NAME); err != nil {
return err
}
_, err = UpdateUser(models.User{
UserName: currentUser.UserName,
Networks: currentUser.Networks,
IsAdmin: currentUser.IsAdmin,
Password: "",
Groups: currentUser.Groups,
}, returnedUser)
return nil
return err
}
// UpdateUser - updates a given user
@@ -187,11 +254,6 @@ func UpdateUser(userchange models.User, user models.User) (models.User, error) {
return models.User{}, err
}
err := ValidateUser(userchange)
if err != nil {
return models.User{}, err
}
queryUser := user.UserName
if userchange.UserName != "" {
@@ -200,6 +262,9 @@ func UpdateUser(userchange models.User, user models.User) (models.User, error) {
if len(userchange.Networks) > 0 {
user.Networks = userchange.Networks
}
if len(userchange.Groups) > 0 {
user.Groups = userchange.Groups
}
if userchange.Password != "" {
// encrypt that password so we never see it again
hash, err := bcrypt.GenerateFromPassword([]byte(userchange.Password), 5)
@@ -212,6 +277,12 @@ func UpdateUser(userchange models.User, user models.User) (models.User, error) {
user.Password = userchange.Password
}
err := ValidateUser(user)
if err != nil {
return models.User{}, err
}
if err = database.DeleteRecord(database.USERS_TABLE_NAME, queryUser); err != nil {
return models.User{}, err
}
@@ -256,6 +327,20 @@ func DeleteUser(user string) (bool, error) {
if err != nil {
return false, err
}
// == pro - remove user from all network user instances ==
currentNets, err := GetNetworks()
if err != nil {
return true, err
}
for i := range currentNets {
netID := currentNets[i].NetID
if err = pro.DeleteNetworkUser(netID, user); err != nil {
logger.Log(0, "failed to remove", user, "as network user from network", netID, err.Error())
}
}
return true, nil
}
@@ -313,6 +398,9 @@ func IsStateValid(state string) (string, bool) {
if s.Value != "" {
delState(state)
}
if err != nil {
logger.Log(2, "error retrieving oauth state:", err.Error())
}
return s.Value, err == nil
}
@@ -320,3 +408,51 @@ func IsStateValid(state string) (string, bool) {
func delState(state string) error {
return database.DeleteRecord(database.SSO_STATE_CACHE, state)
}
// PRO
// AdjustGroupPermissions - adjusts a given user's network access based on group changes
func AdjustGroupPermissions(user *models.ReturnUser) error {
networks, err := GetNetworks()
if err != nil {
return err
}
// UPDATE
// go through all networks and see if new group is in
// if access level of current user is greater (value) than network's default
// assign network's default
// DELETE
// if user not allowed on network a
for i := range networks {
AdjustNetworkUserPermissions(user, &networks[i])
}
return nil
}
// AdjustGroupPermissions - adjusts a given user's network access based on group changes
func AdjustNetworkUserPermissions(user *models.ReturnUser, network *models.Network) error {
networkUser, err := pro.GetNetworkUser(
network.NetID,
promodels.NetworkUserID(user.UserName),
)
if err == nil && network.ProSettings != nil {
if pro.IsUserAllowed(network, user.UserName, user.Groups) {
if networkUser.AccessLevel > network.ProSettings.DefaultAccessLevel {
networkUser.AccessLevel = network.ProSettings.DefaultAccessLevel
}
if networkUser.NodeLimit < network.ProSettings.DefaultUserNodeLimit {
networkUser.NodeLimit = network.ProSettings.DefaultUserNodeLimit
}
if networkUser.ClientLimit < network.ProSettings.DefaultUserClientLimit {
networkUser.ClientLimit = network.ProSettings.DefaultUserClientLimit
}
} else {
networkUser.AccessLevel = pro.NO_ACCESS
networkUser.NodeLimit = 0
networkUser.ClientLimit = 0
}
pro.UpdateNetworkUser(network.NetID, networkUser)
}
return err
}