Jelajahi Sumber

disable user vpn access when network roles are modified

abhishek9686 1 tahun lalu
induk
melakukan
015688d026
7 mengubah file dengan 249 tambahan dan 2 penghapusan
  1. 6 2
      controllers/user.go
  2. 2 0
      logic/auth.go
  3. 2 0
      logic/user_mgmt.go
  4. 16 0
      logic/users.go
  5. 15 0
      pro/controllers/users.go
  6. 1 0
      pro/initialize.go
  7. 207 0
      pro/logic/user_mgmt.go

+ 6 - 2
controllers/user.go

@@ -676,10 +676,14 @@ func deleteUser(w http.ResponseWriter, r *http.Request) {
 		}
 		for _, extclient := range extclients {
 			if extclient.OwnerID == user.UserName {
-				err = logic.DeleteExtClient(extclient.Network, extclient.ClientID)
+				err = logic.DeleteExtClientAndCleanup(extclient)
 				if err != nil {
 					slog.Error("failed to delete extclient",
-						"id", extclient.ClientID, "owner", user.UserName, "error", err)
+						"id", extclient.ClientID, "owner", username, "error", err)
+				} else {
+					if err := mq.PublishDeletedClientPeerUpdate(&extclient); err != nil {
+						slog.Error("error setting ext peers: " + err.Error())
+					}
 				}
 			}
 		}

+ 2 - 0
logic/auth.go

@@ -295,6 +295,8 @@ func UpdateUser(userchange, user *models.User) (*models.User, error) {
 	if err := IsNetworkRolesValid(userchange.NetworkRoles); err != nil {
 		return userchange, errors.New("invalid network roles: " + err.Error())
 	}
+	// Reset Gw Access for service users
+	go UpdateUserGwAccess(*user, *userchange)
 	user.PlatformRoleID = userchange.PlatformRoleID
 	user.UserGroups = userchange.UserGroups
 	user.NetworkRoles = userchange.NetworkRoles

+ 2 - 0
logic/user_mgmt.go

@@ -43,6 +43,8 @@ var IsNetworkRolesValid = func(networkRoles map[models.NetworkID]map[models.User
 	return nil
 }
 
+var UpdateUserGwAccess = func(currentUser, changeUser models.User) {}
+
 var UpdateRole = func(r models.UserRolePermissionTemplate) error { return nil }
 
 var InitialiseRoles = userRolesInit

+ 16 - 0
logic/users.go

@@ -129,6 +129,22 @@ func ListPendingUsers() ([]models.ReturnUser, error) {
 	return pendingUsers, nil
 }
 
+func GetUserMap() (map[string]models.User, error) {
+	userMap := make(map[string]models.User)
+	records, err := database.FetchRecords(database.USERS_TABLE_NAME)
+	if err != nil && !database.IsEmptyRecord(err) {
+		return userMap, err
+	}
+	for _, record := range records {
+		u := models.User{}
+		err = json.Unmarshal([]byte(record), &u)
+		if err == nil {
+			userMap[u.UserName] = u
+		}
+	}
+	return userMap, nil
+}
+
 func InsertUserInvite(invite models.UserInvite) error {
 	data, err := json.Marshal(invite)
 	if err != nil {

+ 15 - 0
pro/controllers/users.go

@@ -421,6 +421,12 @@ func updateUserGroup(w http.ResponseWriter, r *http.Request) {
 		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
 		return
 	}
+	// fetch curr group
+	currUserG, err := proLogic.GetUserGroup(userGroup.ID)
+	if err != nil {
+		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
+		return
+	}
 	err = proLogic.ValidateUpdateGroupReq(userGroup)
 	if err != nil {
 		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
@@ -431,6 +437,8 @@ func updateUserGroup(w http.ResponseWriter, r *http.Request) {
 		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
 		return
 	}
+	// reset configs for service user
+	go proLogic.UpdatesUserGwAccessOnGrpUpdates(currUserG.NetworkRoles, userGroup.NetworkRoles)
 	logic.ReturnSuccessResponseWithJson(w, r, userGroup, "updated user group")
 }
 
@@ -561,6 +569,11 @@ func updateRole(w http.ResponseWriter, r *http.Request) {
 		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
 		return
 	}
+	currRole, err := logic.GetRole(userRole.ID)
+	if err != nil {
+		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
+		return
+	}
 	err = proLogic.ValidateUpdateRoleReq(&userRole)
 	if err != nil {
 		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
@@ -572,6 +585,8 @@ func updateRole(w http.ResponseWriter, r *http.Request) {
 		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
 		return
 	}
+	// reset configs for service user
+	go proLogic.UpdatesUserGwAccessOnRoleUpdates(currRole.NetworkLevelAccess, userRole.NetworkLevelAccess, string(userRole.NetworkID))
 	logic.ReturnSuccessResponseWithJson(w, r, userRole, "updated user role")
 }
 

+ 1 - 0
pro/initialize.go

@@ -131,6 +131,7 @@ func InitPro() {
 	logic.IsGroupsValid = proLogic.IsGroupsValid
 	logic.IsNetworkRolesValid = proLogic.IsNetworkRolesValid
 	logic.InitialiseRoles = proLogic.UserRolesInit
+	logic.UpdateUserGwAccess = proLogic.UpdateUserGwAccess
 }
 
 func retrieveProLogo() string {

+ 207 - 0
pro/logic/user_mgmt.go

@@ -9,6 +9,9 @@ import (
 	"github.com/gravitl/netmaker/logger"
 	"github.com/gravitl/netmaker/logic"
 	"github.com/gravitl/netmaker/models"
+	"github.com/gravitl/netmaker/mq"
+	"github.com/gravitl/netmaker/servercfg"
+	"golang.org/x/exp/slog"
 )
 
 var ServiceUserPermissionTemplate = models.UserRolePermissionTemplate{
@@ -836,3 +839,207 @@ func PrepareOauthUserFromInvite(in models.UserInvite) (models.User, error) {
 	}
 	return user, nil
 }
+
+func UpdatesUserGwAccessOnRoleUpdates(currNetworkAccess,
+	changeNetworkAccess map[models.RsrcType]map[models.RsrcID]models.RsrcPermissionScope, netID string) {
+	networkChangeMap := make(map[models.RsrcID]models.RsrcPermissionScope)
+	for rsrcType, RsrcPermsMap := range currNetworkAccess {
+		if rsrcType != models.RemoteAccessGwRsrc {
+			continue
+		}
+		if _, ok := changeNetworkAccess[rsrcType]; !ok {
+			for rsrcID, scope := range RsrcPermsMap {
+				networkChangeMap[rsrcID] = scope
+			}
+		} else {
+			for rsrcID, scope := range RsrcPermsMap {
+				if _, ok := changeNetworkAccess[rsrcType][rsrcID]; !ok {
+					networkChangeMap[rsrcID] = scope
+				}
+			}
+		}
+	}
+
+	extclients, err := logic.GetAllExtClients()
+	if err != nil {
+		slog.Error("failed to fetch extclients", "error", err)
+		return
+	}
+	userMap, err := logic.GetUserMap()
+	if err != nil {
+		return
+	}
+	for _, extclient := range extclients {
+		if extclient.Network != netID {
+			continue
+		}
+		if _, ok := networkChangeMap[models.AllRemoteAccessGwRsrcID]; ok {
+			if user, ok := userMap[extclient.OwnerID]; ok {
+				if user.PlatformRoleID != models.ServiceUser {
+					continue
+				}
+				err = logic.DeleteExtClientAndCleanup(extclient)
+				if err != nil {
+					slog.Error("failed to delete extclient",
+						"id", extclient.ClientID, "owner", user.UserName, "error", err)
+				} else {
+					if err := mq.PublishDeletedClientPeerUpdate(&extclient); err != nil {
+						slog.Error("error setting ext peers: " + err.Error())
+					}
+				}
+			}
+			continue
+		}
+		if _, ok := networkChangeMap[models.RsrcID(extclient.IngressGatewayID)]; ok {
+			if user, ok := userMap[extclient.OwnerID]; ok {
+				if user.PlatformRoleID != models.ServiceUser {
+					continue
+				}
+				err = logic.DeleteExtClientAndCleanup(extclient)
+				if err != nil {
+					slog.Error("failed to delete extclient",
+						"id", extclient.ClientID, "owner", user.UserName, "error", err)
+				} else {
+					if err := mq.PublishDeletedClientPeerUpdate(&extclient); err != nil {
+						slog.Error("error setting ext peers: " + err.Error())
+					}
+				}
+			}
+
+		}
+
+	}
+	if servercfg.IsDNSMode() {
+		logic.SetDNS()
+	}
+}
+
+func UpdatesUserGwAccessOnGrpUpdates(currNetworkRoles, changeNetworkRoles map[models.NetworkID]map[models.UserRoleID]struct{}) {
+	networkChangeMap := make(map[models.NetworkID]map[models.UserRoleID]struct{})
+	for netID, networkUserRoles := range currNetworkRoles {
+		if _, ok := changeNetworkRoles[netID]; !ok {
+			for netRoleID := range networkUserRoles {
+				if _, ok := networkChangeMap[netID]; !ok {
+					networkChangeMap[netID] = make(map[models.UserRoleID]struct{})
+				}
+				networkChangeMap[netID][netRoleID] = struct{}{}
+			}
+		} else {
+			for netRoleID := range networkUserRoles {
+				if _, ok := changeNetworkRoles[netID][netRoleID]; !ok {
+					if _, ok := networkChangeMap[netID]; !ok {
+						networkChangeMap[netID] = make(map[models.UserRoleID]struct{})
+					}
+					networkChangeMap[netID][netRoleID] = struct{}{}
+				}
+			}
+		}
+	}
+	extclients, err := logic.GetAllExtClients()
+	if err != nil {
+		slog.Error("failed to fetch extclients", "error", err)
+		return
+	}
+	userMap, err := logic.GetUserMap()
+	if err != nil {
+		return
+	}
+	for _, extclient := range extclients {
+
+		if _, ok := networkChangeMap[models.NetworkID(extclient.Network)]; ok {
+			if user, ok := userMap[extclient.OwnerID]; ok {
+				if user.PlatformRoleID != models.ServiceUser {
+					continue
+				}
+				err = logic.DeleteExtClientAndCleanup(extclient)
+				if err != nil {
+					slog.Error("failed to delete extclient",
+						"id", extclient.ClientID, "owner", user.UserName, "error", err)
+				} else {
+					if err := mq.PublishDeletedClientPeerUpdate(&extclient); err != nil {
+						slog.Error("error setting ext peers: " + err.Error())
+					}
+				}
+			}
+
+		}
+
+	}
+	if servercfg.IsDNSMode() {
+		logic.SetDNS()
+	}
+
+}
+
+func UpdateUserGwAccess(currentUser, changeUser models.User) {
+	if changeUser.PlatformRoleID != models.ServiceUser {
+		return
+	}
+
+	networkChangeMap := make(map[models.NetworkID]map[models.UserRoleID]struct{})
+	for netID, networkUserRoles := range currentUser.NetworkRoles {
+		if _, ok := changeUser.NetworkRoles[netID]; !ok {
+			for netRoleID := range networkUserRoles {
+				if _, ok := networkChangeMap[netID]; !ok {
+					networkChangeMap[netID] = make(map[models.UserRoleID]struct{})
+				}
+				networkChangeMap[netID][netRoleID] = struct{}{}
+			}
+		} else {
+			for netRoleID := range networkUserRoles {
+				if _, ok := changeUser.NetworkRoles[netID][netRoleID]; !ok {
+					if _, ok := networkChangeMap[netID]; !ok {
+						networkChangeMap[netID] = make(map[models.UserRoleID]struct{})
+					}
+					networkChangeMap[netID][netRoleID] = struct{}{}
+				}
+			}
+		}
+	}
+	for gID := range currentUser.UserGroups {
+		if _, ok := changeUser.UserGroups[gID]; ok {
+			continue
+		}
+		userG, err := GetUserGroup(gID)
+		if err == nil {
+			for netID, networkUserRoles := range userG.NetworkRoles {
+				for netRoleID := range networkUserRoles {
+					if _, ok := networkChangeMap[netID]; !ok {
+						networkChangeMap[netID] = make(map[models.UserRoleID]struct{})
+					}
+					networkChangeMap[netID][netRoleID] = struct{}{}
+				}
+			}
+		}
+	}
+	if len(networkChangeMap) == 0 {
+		return
+	}
+	// TODO - cleanup gw access when role and groups are updated
+	//removedGwAccess
+	extclients, err := logic.GetAllExtClients()
+	if err != nil {
+		slog.Error("failed to fetch extclients", "error", err)
+		return
+	}
+	for _, extclient := range extclients {
+		if extclient.OwnerID == currentUser.UserName {
+			if _, ok := networkChangeMap[models.NetworkID(extclient.Network)]; ok {
+				err = logic.DeleteExtClientAndCleanup(extclient)
+				if err != nil {
+					slog.Error("failed to delete extclient",
+						"id", extclient.ClientID, "owner", changeUser.UserName, "error", err)
+				} else {
+					if err := mq.PublishDeletedClientPeerUpdate(&extclient); err != nil {
+						slog.Error("error setting ext peers: " + err.Error())
+					}
+				}
+			}
+
+		}
+	}
+	if servercfg.IsDNSMode() {
+		logic.SetDNS()
+	}
+
+}