| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237 | package logicimport (	"encoding/json"	"errors"	"fmt"	"time"	"github.com/gravitl/netmaker/database"	"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{	ID:                  models.ServiceUser,	Default:             true,	FullAccess:          false,	DenyDashboardAccess: true,}var PlatformUserUserPermissionTemplate = models.UserRolePermissionTemplate{	ID:         models.PlatformUser,	Default:    true,	FullAccess: false,}var NetworkAdminAllPermissionTemplate = models.UserRolePermissionTemplate{	ID:         models.UserRoleID(fmt.Sprintf("global-%s", models.NetworkAdmin)),	Name:       "Network Admins",	MetaData:   "can manage configuration of all networks",	Default:    true,	FullAccess: true,	NetworkID:  models.AllNetworks,}var NetworkUserAllPermissionTemplate = models.UserRolePermissionTemplate{	ID:         models.UserRoleID(fmt.Sprintf("global-%s", models.NetworkUser)),	Name:       "Network Users",	MetaData:   "cannot access the admin console, but can connect to nodes in your networks via Remote Access Client.",	Default:    true,	FullAccess: false,	NetworkID:  models.AllNetworks,	NetworkLevelAccess: map[models.RsrcType]map[models.RsrcID]models.RsrcPermissionScope{		models.RemoteAccessGwRsrc: {			models.AllRemoteAccessGwRsrcID: models.RsrcPermissionScope{				Read:      true,				VPNaccess: true,			},		},		models.ExtClientsRsrc: {			models.AllExtClientsRsrcID: models.RsrcPermissionScope{				Read:     true,				Create:   true,				Update:   true,				Delete:   true,				SelfOnly: true,			},		},	},}func UserRolesInit() {	d, _ := json.Marshal(logic.SuperAdminPermissionTemplate)	database.Insert(logic.SuperAdminPermissionTemplate.ID.String(), string(d), database.USER_PERMISSIONS_TABLE_NAME)	d, _ = json.Marshal(logic.AdminPermissionTemplate)	database.Insert(logic.AdminPermissionTemplate.ID.String(), string(d), database.USER_PERMISSIONS_TABLE_NAME)	d, _ = json.Marshal(ServiceUserPermissionTemplate)	database.Insert(ServiceUserPermissionTemplate.ID.String(), string(d), database.USER_PERMISSIONS_TABLE_NAME)	d, _ = json.Marshal(PlatformUserUserPermissionTemplate)	database.Insert(PlatformUserUserPermissionTemplate.ID.String(), string(d), database.USER_PERMISSIONS_TABLE_NAME)	d, _ = json.Marshal(NetworkAdminAllPermissionTemplate)	database.Insert(NetworkAdminAllPermissionTemplate.ID.String(), string(d), database.USER_PERMISSIONS_TABLE_NAME)	d, _ = json.Marshal(NetworkUserAllPermissionTemplate)	database.Insert(NetworkUserAllPermissionTemplate.ID.String(), string(d), database.USER_PERMISSIONS_TABLE_NAME)}func UserGroupsInit() {	// create default network groups	var NetworkGlobalAdminGroup = models.UserGroup{		ID:       models.UserGroupID(fmt.Sprintf("global-%s-grp", models.NetworkAdmin)),		Default:  true,		Name:     "All Networks Admin Group",		MetaData: "can manage configuration of all networks",		NetworkRoles: map[models.NetworkID]map[models.UserRoleID]struct{}{			models.AllNetworks: {				models.UserRoleID(fmt.Sprintf("global-%s", models.NetworkAdmin)): {},			},		},	}	var NetworkGlobalUserGroup = models.UserGroup{		ID:      models.UserGroupID(fmt.Sprintf("global-%s-grp", models.NetworkUser)),		Name:    "All Networks User Group",		Default: true,		NetworkRoles: map[models.NetworkID]map[models.UserRoleID]struct{}{			models.NetworkID(models.AllNetworks): {				models.UserRoleID(fmt.Sprintf("global-%s", models.NetworkUser)): {},			},		},		MetaData: "cannot access the admin console, but can connect to nodes in your networks via Remote Access Client.",	}	d, _ := json.Marshal(NetworkGlobalAdminGroup)	database.Insert(NetworkGlobalAdminGroup.ID.String(), string(d), database.USER_GROUPS_TABLE_NAME)	d, _ = json.Marshal(NetworkGlobalUserGroup)	database.Insert(NetworkGlobalUserGroup.ID.String(), string(d), database.USER_GROUPS_TABLE_NAME)}func CreateDefaultNetworkRolesAndGroups(netID models.NetworkID) {	if netID.String() == "" {		return	}	var NetworkAdminPermissionTemplate = models.UserRolePermissionTemplate{		ID:                 models.UserRoleID(fmt.Sprintf("%s-%s", netID, models.NetworkAdmin)),		Name:               fmt.Sprintf("%s Admin", netID),		MetaData:           fmt.Sprintf("can manage your network `%s` configuration.", netID),		Default:            true,		NetworkID:          netID,		FullAccess:         true,		NetworkLevelAccess: make(map[models.RsrcType]map[models.RsrcID]models.RsrcPermissionScope),	}	var NetworkUserPermissionTemplate = models.UserRolePermissionTemplate{		ID:                  models.UserRoleID(fmt.Sprintf("%s-%s", netID, models.NetworkUser)),		Name:                fmt.Sprintf("%s User", netID),		MetaData:            fmt.Sprintf("cannot access the admin console, but can connect to nodes in your network `%s` via Remote Access Client.", netID),		Default:             true,		FullAccess:          false,		NetworkID:           netID,		DenyDashboardAccess: false,		NetworkLevelAccess: map[models.RsrcType]map[models.RsrcID]models.RsrcPermissionScope{			models.RemoteAccessGwRsrc: {				models.AllRemoteAccessGwRsrcID: models.RsrcPermissionScope{					Read:      true,					VPNaccess: true,				},			},			models.ExtClientsRsrc: {				models.AllExtClientsRsrcID: models.RsrcPermissionScope{					Read:     true,					Create:   true,					Update:   true,					Delete:   true,					SelfOnly: true,				},			},		},	}	d, _ := json.Marshal(NetworkAdminPermissionTemplate)	database.Insert(NetworkAdminPermissionTemplate.ID.String(), string(d), database.USER_PERMISSIONS_TABLE_NAME)	d, _ = json.Marshal(NetworkUserPermissionTemplate)	database.Insert(NetworkUserPermissionTemplate.ID.String(), string(d), database.USER_PERMISSIONS_TABLE_NAME)	// create default network groups	var NetworkAdminGroup = models.UserGroup{		ID:   models.UserGroupID(fmt.Sprintf("%s-%s-grp", netID, models.NetworkAdmin)),		Name: fmt.Sprintf("%s Admin Group", netID),		NetworkRoles: map[models.NetworkID]map[models.UserRoleID]struct{}{			netID: {				models.UserRoleID(fmt.Sprintf("%s-%s", netID, models.NetworkAdmin)): {},			},		},		MetaData: fmt.Sprintf("can manage your network `%s` configuration including adding and removing devices.", netID),	}	var NetworkUserGroup = models.UserGroup{		ID:   models.UserGroupID(fmt.Sprintf("%s-%s-grp", netID, models.NetworkUser)),		Name: fmt.Sprintf("%s User Group", netID),		NetworkRoles: map[models.NetworkID]map[models.UserRoleID]struct{}{			netID: {				models.UserRoleID(fmt.Sprintf("%s-%s", netID, models.NetworkUser)): {},			},		},		MetaData: fmt.Sprintf("cannot access the admin console, but can connect to nodes in your network `%s` via Remote Access Client.", netID),	}	d, _ = json.Marshal(NetworkAdminGroup)	database.Insert(NetworkAdminGroup.ID.String(), string(d), database.USER_GROUPS_TABLE_NAME)	d, _ = json.Marshal(NetworkUserGroup)	database.Insert(NetworkUserGroup.ID.String(), string(d), database.USER_GROUPS_TABLE_NAME)}func DeleteNetworkRoles(netID string) {	users, err := logic.GetUsersDB()	if err != nil {		return	}	defaultUserGrp := fmt.Sprintf("%s-%s-grp", netID, models.NetworkUser)	defaultAdminGrp := fmt.Sprintf("%s-%s-grp", netID, models.NetworkAdmin)	for _, user := range users {		var upsert bool		if _, ok := user.NetworkRoles[models.NetworkID(netID)]; ok {			delete(user.NetworkRoles, models.NetworkID(netID))			upsert = true		}		if _, ok := user.UserGroups[models.UserGroupID(defaultUserGrp)]; ok {			delete(user.UserGroups, models.UserGroupID(defaultUserGrp))			upsert = true		}		if _, ok := user.UserGroups[models.UserGroupID(defaultAdminGrp)]; ok {			delete(user.UserGroups, models.UserGroupID(defaultAdminGrp))			upsert = true		}		if upsert {			logic.UpsertUser(user)		}	}	database.DeleteRecord(database.USER_GROUPS_TABLE_NAME, defaultUserGrp)	database.DeleteRecord(database.USER_GROUPS_TABLE_NAME, defaultAdminGrp)	userGs, _ := ListUserGroups()	for _, userGI := range userGs {		if _, ok := userGI.NetworkRoles[models.NetworkID(netID)]; ok {			delete(userGI.NetworkRoles, models.NetworkID(netID))			UpdateUserGroup(userGI)		}	}	roles, _ := ListNetworkRoles()	for _, role := range roles {		if role.NetworkID.String() == netID {			database.DeleteRecord(database.USER_PERMISSIONS_TABLE_NAME, role.ID.String())		}	}}// ListNetworkRoles - lists user network roles permission templatesfunc ListNetworkRoles() ([]models.UserRolePermissionTemplate, error) {	data, err := database.FetchRecords(database.USER_PERMISSIONS_TABLE_NAME)	if err != nil && !database.IsEmptyRecord(err) {		return []models.UserRolePermissionTemplate{}, err	}	userRoles := []models.UserRolePermissionTemplate{}	for _, dataI := range data {		userRole := models.UserRolePermissionTemplate{}		err := json.Unmarshal([]byte(dataI), &userRole)		if err != nil {			continue		}		if userRole.NetworkID == "" {			continue		}		userRoles = append(userRoles, userRole)	}	return userRoles, nil}func ValidateCreateRoleReq(userRole *models.UserRolePermissionTemplate) error {	// check if role exists with this id	_, err := logic.GetRole(userRole.ID)	if err == nil {		return fmt.Errorf("role with id `%s` exists already", userRole.ID.String())	}	if len(userRole.NetworkLevelAccess) > 0 {		for rsrcType := range userRole.NetworkLevelAccess {			if _, ok := models.RsrcTypeMap[rsrcType]; !ok {				return errors.New("invalid rsrc type " + rsrcType.String())			}			if rsrcType == models.RemoteAccessGwRsrc {				userRsrcPermissions := userRole.NetworkLevelAccess[models.RemoteAccessGwRsrc]				var vpnAccess bool				for _, scope := range userRsrcPermissions {					if scope.VPNaccess {						vpnAccess = true						break					}				}				if vpnAccess {					userRole.NetworkLevelAccess[models.ExtClientsRsrc] = map[models.RsrcID]models.RsrcPermissionScope{						models.AllExtClientsRsrcID: {							Read:     true,							Create:   true,							Update:   true,							Delete:   true,							SelfOnly: true,						},					}				}			}		}	}	if userRole.NetworkID == "" {		return errors.New("only network roles are allowed to be created")	}	return nil}func ValidateUpdateRoleReq(userRole *models.UserRolePermissionTemplate) error {	roleInDB, err := logic.GetRole(userRole.ID)	if err != nil {		return err	}	if roleInDB.NetworkID != userRole.NetworkID {		return errors.New("network id mismatch")	}	if roleInDB.Default {		return errors.New("cannot update default role")	}	if len(userRole.NetworkLevelAccess) > 0 {		for rsrcType := range userRole.NetworkLevelAccess {			if _, ok := models.RsrcTypeMap[rsrcType]; !ok {				return errors.New("invalid rsrc type " + rsrcType.String())			}			if rsrcType == models.RemoteAccessGwRsrc {				userRsrcPermissions := userRole.NetworkLevelAccess[models.RemoteAccessGwRsrc]				var vpnAccess bool				for _, scope := range userRsrcPermissions {					if scope.VPNaccess {						vpnAccess = true						break					}				}				if vpnAccess {					userRole.NetworkLevelAccess[models.ExtClientsRsrc] = map[models.RsrcID]models.RsrcPermissionScope{						models.AllExtClientsRsrcID: {							Read:     true,							Create:   true,							Update:   true,							Delete:   true,							SelfOnly: true,						},					}				}			}		}	}	return nil}// CreateRole - inserts new role into DBfunc CreateRole(r models.UserRolePermissionTemplate) error {	// check if role already exists	if r.ID.String() == "" {		return errors.New("role id cannot be empty")	}	_, err := database.FetchRecord(database.USER_PERMISSIONS_TABLE_NAME, r.ID.String())	if err == nil {		return errors.New("role already exists")	}	d, err := json.Marshal(r)	if err != nil {		return err	}	return database.Insert(r.ID.String(), string(d), database.USER_PERMISSIONS_TABLE_NAME)}// UpdateRole - updates role templatefunc UpdateRole(r models.UserRolePermissionTemplate) error {	if r.ID.String() == "" {		return errors.New("role id cannot be empty")	}	_, err := database.FetchRecord(database.USER_PERMISSIONS_TABLE_NAME, r.ID.String())	if err != nil {		return err	}	d, err := json.Marshal(r)	if err != nil {		return err	}	return database.Insert(r.ID.String(), string(d), database.USER_PERMISSIONS_TABLE_NAME)}// DeleteRole - deletes user rolefunc DeleteRole(rid models.UserRoleID, force bool) error {	if rid.String() == "" {		return errors.New("role id cannot be empty")	}	users, err := logic.GetUsersDB()	if err != nil {		return err	}	role, err := logic.GetRole(rid)	if err != nil {		return err	}	if role.NetworkID == "" {		return errors.New("cannot delete platform role")	}	// allow deletion of default network roles if network doesn't exist	if role.NetworkID == models.AllNetworks {		return errors.New("cannot delete default network role")	}	// check if network exists	exists, _ := logic.NetworkExists(role.NetworkID.String())	if role.Default {		if exists && !force {			return errors.New("cannot delete default role")		}	}	for _, user := range users {		for userG := range user.UserGroups {			ug, err := GetUserGroup(userG)			if err == nil {				if role.NetworkID != "" {					for netID, networkRoles := range ug.NetworkRoles {						if _, ok := networkRoles[rid]; ok {							delete(networkRoles, rid)							ug.NetworkRoles[netID] = networkRoles							UpdateUserGroup(ug)						}					}				}			}		}		if user.PlatformRoleID == rid {			err = errors.New("active roles cannot be deleted.switch existing users to a new role before deleting")			return err		}		if role.NetworkID != "" {			for netID, networkRoles := range user.NetworkRoles {				if _, ok := networkRoles[rid]; ok {					delete(networkRoles, rid)					user.NetworkRoles[netID] = networkRoles					logic.UpsertUser(user)				}			}		}	}	return database.DeleteRecord(database.USER_PERMISSIONS_TABLE_NAME, rid.String())}func ValidateCreateGroupReq(g models.UserGroup) error {	// check if network roles are valid	for _, roleMap := range g.NetworkRoles {		for roleID := range roleMap {			role, err := logic.GetRole(roleID)			if err != nil {				return fmt.Errorf("invalid network role %s", roleID)			}			if role.NetworkID == "" {				return errors.New("platform role cannot be used as network role")			}		}	}	return nil}func ValidateUpdateGroupReq(g models.UserGroup) error {	for networkID := range g.NetworkRoles {		userRolesMap := g.NetworkRoles[networkID]		for roleID := range userRolesMap {			netRole, err := logic.GetRole(roleID)			if err != nil {				err = fmt.Errorf("invalid network role")				return err			}			if netRole.NetworkID == "" {				return errors.New("platform role cannot be used as network role")			}		}	}	return nil}// CreateUserGroup - creates new user groupfunc CreateUserGroup(g models.UserGroup) error {	// check if role already exists	if g.ID == "" {		return errors.New("group id cannot be empty")	}	_, err := database.FetchRecord(database.USER_GROUPS_TABLE_NAME, g.ID.String())	if err == nil {		return errors.New("group already exists")	}	d, err := json.Marshal(g)	if err != nil {		return err	}	return database.Insert(g.ID.String(), string(d), database.USER_GROUPS_TABLE_NAME)}// GetUserGroup - fetches user groupfunc GetUserGroup(gid models.UserGroupID) (models.UserGroup, error) {	d, err := database.FetchRecord(database.USER_GROUPS_TABLE_NAME, gid.String())	if err != nil {		return models.UserGroup{}, err	}	var ug models.UserGroup	err = json.Unmarshal([]byte(d), &ug)	if err != nil {		return ug, err	}	return ug, nil}// ListUserGroups - lists user groupsfunc ListUserGroups() ([]models.UserGroup, error) {	data, err := database.FetchRecords(database.USER_GROUPS_TABLE_NAME)	if err != nil && !database.IsEmptyRecord(err) {		return []models.UserGroup{}, err	}	userGroups := []models.UserGroup{}	for _, dataI := range data {		userGroup := models.UserGroup{}		err := json.Unmarshal([]byte(dataI), &userGroup)		if err != nil {			continue		}		userGroups = append(userGroups, userGroup)	}	return userGroups, nil}// UpdateUserGroup - updates new user groupfunc UpdateUserGroup(g models.UserGroup) error {	// check if group exists	if g.ID == "" {		return errors.New("group id cannot be empty")	}	_, err := database.FetchRecord(database.USER_GROUPS_TABLE_NAME, g.ID.String())	if err != nil {		return err	}	d, err := json.Marshal(g)	if err != nil {		return err	}	return database.Insert(g.ID.String(), string(d), database.USER_GROUPS_TABLE_NAME)}// DeleteUserGroup - deletes user groupfunc DeleteUserGroup(gid models.UserGroupID) error {	users, err := logic.GetUsersDB()	if err != nil {		return err	}	for _, user := range users {		delete(user.UserGroups, gid)		logic.UpsertUser(user)	}	return database.DeleteRecord(database.USER_GROUPS_TABLE_NAME, gid.String())}func HasNetworkRsrcScope(permissionTemplate models.UserRolePermissionTemplate, netid string, rsrcType models.RsrcType, rsrcID models.RsrcID, op string) bool {	if permissionTemplate.FullAccess {		return true	}	rsrcScope, ok := permissionTemplate.NetworkLevelAccess[rsrcType]	if !ok {		return false	}	_, ok = rsrcScope[rsrcID]	return ok}func GetUserRAGNodesV1(user models.User) (gws map[string]models.Node) {	gws = make(map[string]models.Node)	nodes, err := logic.GetAllNodes()	if err != nil {		return	}	if user.PlatformRoleID == models.AdminRole || user.PlatformRoleID == models.SuperAdminRole {		for _, node := range nodes {			if node.IsIngressGateway {				gws[node.ID.String()] = node			}		}	}	tagNodesMap := logic.GetTagMapWithNodes()	accessPolices := logic.ListUserPolicies(user)	for _, policyI := range accessPolices {		if !policyI.Enabled {			continue		}		for _, dstI := range policyI.Dst {			if dstI.Value == "*" {				networkNodes := logic.GetNetworkNodesMemory(nodes, policyI.NetworkID.String())				for _, node := range networkNodes {					if node.IsIngressGateway {						gws[node.ID.String()] = node					}				}			}			if nodes, ok := tagNodesMap[models.TagID(dstI.Value)]; ok {				for _, node := range nodes {					if node.IsIngressGateway {						gws[node.ID.String()] = node					}				}			}		}	}	return}func GetUserRAGNodes(user models.User) (gws map[string]models.Node) {	gws = make(map[string]models.Node)	userGwAccessScope := GetUserNetworkRolesWithRemoteVPNAccess(user)	logger.Log(3, fmt.Sprintf("User Gw Access Scope: %+v", userGwAccessScope))	_, allNetAccess := userGwAccessScope["*"]	nodes, err := logic.GetAllNodes()	if err != nil {		return	}	for _, node := range nodes {		if node.IsIngressGateway && !node.PendingDelete {			if allNetAccess {				gws[node.ID.String()] = node			} else {				gwRsrcMap := userGwAccessScope[models.NetworkID(node.Network)]				scope, ok := gwRsrcMap[models.AllRemoteAccessGwRsrcID]				if !ok {					if scope, ok = gwRsrcMap[models.RsrcID(node.ID.String())]; !ok {						continue					}				}				if scope.VPNaccess {					gws[node.ID.String()] = node				}			}		}	}	return}// GetUserNetworkRoles - get user network rolesfunc GetUserNetworkRolesWithRemoteVPNAccess(user models.User) (gwAccess map[models.NetworkID]map[models.RsrcID]models.RsrcPermissionScope) {	gwAccess = make(map[models.NetworkID]map[models.RsrcID]models.RsrcPermissionScope)	platformRole, err := logic.GetRole(user.PlatformRoleID)	if err != nil {		return	}	if platformRole.FullAccess {		gwAccess[models.NetworkID("*")] = make(map[models.RsrcID]models.RsrcPermissionScope)		return	}	if _, ok := user.NetworkRoles[models.AllNetworks]; ok {		gwAccess[models.NetworkID("*")] = make(map[models.RsrcID]models.RsrcPermissionScope)		return	}	if len(user.UserGroups) > 0 {		for gID := range user.UserGroups {			userG, err := GetUserGroup(gID)			if err != nil {				continue			}			if _, ok := userG.NetworkRoles[models.AllNetworks]; ok {				gwAccess[models.NetworkID("*")] = make(map[models.RsrcID]models.RsrcPermissionScope)				return			}			for netID, roleMap := range userG.NetworkRoles {				for roleID := range roleMap {					role, err := logic.GetRole(roleID)					if err == nil {						if role.FullAccess {							gwAccess[netID] = map[models.RsrcID]models.RsrcPermissionScope{								models.AllRemoteAccessGwRsrcID: {									Create:    true,									Read:      true,									Update:    true,									VPNaccess: true,									Delete:    true,								},								models.AllExtClientsRsrcID: {									Create: true,									Read:   true,									Update: true,									Delete: true,								},							}							break						}						if rsrcsMap, ok := role.NetworkLevelAccess[models.RemoteAccessGwRsrc]; ok {							if permissions, ok := rsrcsMap[models.AllRemoteAccessGwRsrcID]; ok && permissions.VPNaccess {								if len(gwAccess[netID]) == 0 {									gwAccess[netID] = make(map[models.RsrcID]models.RsrcPermissionScope)								}								gwAccess[netID][models.AllRemoteAccessGwRsrcID] = permissions								break							} else {								for gwID, scope := range rsrcsMap {									if scope.VPNaccess {										if len(gwAccess[netID]) == 0 {											gwAccess[netID] = make(map[models.RsrcID]models.RsrcPermissionScope)										}										gwAccess[netID][gwID] = scope									}								}							}						}					}				}			}		}	}	for netID, roleMap := range user.NetworkRoles {		for roleID := range roleMap {			role, err := logic.GetRole(roleID)			if err == nil {				if role.FullAccess {					gwAccess[netID] = map[models.RsrcID]models.RsrcPermissionScope{						models.AllRemoteAccessGwRsrcID: {							Create:    true,							Read:      true,							Update:    true,							VPNaccess: true,							Delete:    true,						},						models.AllExtClientsRsrcID: {							Create: true,							Read:   true,							Update: true,							Delete: true,						},					}					break				}				if rsrcsMap, ok := role.NetworkLevelAccess[models.RemoteAccessGwRsrc]; ok {					if permissions, ok := rsrcsMap[models.AllRemoteAccessGwRsrcID]; ok && permissions.VPNaccess {						if len(gwAccess[netID]) == 0 {							gwAccess[netID] = make(map[models.RsrcID]models.RsrcPermissionScope)						}						gwAccess[netID][models.AllRemoteAccessGwRsrcID] = permissions						break					} else {						for gwID, scope := range rsrcsMap {							if scope.VPNaccess {								if len(gwAccess[netID]) == 0 {									gwAccess[netID] = make(map[models.RsrcID]models.RsrcPermissionScope)								}								gwAccess[netID][gwID] = scope							}						}					}				}			}		}	}	return}func GetFilteredNodesByUserAccess(user models.User, nodes []models.Node) (filteredNodes []models.Node) {	nodesMap := make(map[string]struct{})	allNetworkRoles := make(map[models.UserRoleID]struct{})	defer func() {		filteredNodes = logic.AddStaticNodestoList(filteredNodes)	}()	if len(user.NetworkRoles) > 0 {		for _, netRoles := range user.NetworkRoles {			for netRoleI := range netRoles {				allNetworkRoles[netRoleI] = struct{}{}			}		}	}	if _, ok := user.NetworkRoles[models.AllNetworks]; ok {		filteredNodes = nodes		return	}	if len(user.UserGroups) > 0 {		for userGID := range user.UserGroups {			userG, err := GetUserGroup(userGID)			if err == nil {				if len(userG.NetworkRoles) > 0 {					if _, ok := userG.NetworkRoles[models.AllNetworks]; ok {						filteredNodes = nodes						return					}					for _, netRoles := range userG.NetworkRoles {						for netRoleI := range netRoles {							allNetworkRoles[netRoleI] = struct{}{}						}					}				}			}		}	}	for networkRoleID := range allNetworkRoles {		userPermTemplate, err := logic.GetRole(networkRoleID)		if err != nil {			continue		}		networkNodes := logic.GetNetworkNodesMemory(nodes, userPermTemplate.NetworkID.String())		if userPermTemplate.FullAccess {			for _, node := range networkNodes {				if _, ok := nodesMap[node.ID.String()]; ok {					continue				}				nodesMap[node.ID.String()] = struct{}{}				filteredNodes = append(filteredNodes, node)			}			continue		}		if rsrcPerms, ok := userPermTemplate.NetworkLevelAccess[models.RemoteAccessGwRsrc]; ok {			if _, ok := rsrcPerms[models.AllRemoteAccessGwRsrcID]; ok {				for _, node := range networkNodes {					if _, ok := nodesMap[node.ID.String()]; ok {						continue					}					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 {							nodesMap[gwNode.ID.String()] = struct{}{}							filteredNodes = append(filteredNodes, gwNode)						}					}				}			}		}	}	return}func FilterNetworksByRole(allnetworks []models.Network, user models.User) []models.Network {	platformRole, err := logic.GetRole(user.PlatformRoleID)	if err != nil {		return []models.Network{}	}	if !platformRole.FullAccess {		allNetworkRoles := make(map[models.NetworkID]struct{})		if len(user.NetworkRoles) > 0 {			for netID := range user.NetworkRoles {				if netID == models.AllNetworks {					return allnetworks				}				allNetworkRoles[netID] = struct{}{}			}		}		if len(user.UserGroups) > 0 {			for userGID := range user.UserGroups {				userG, err := GetUserGroup(userGID)				if err == nil {					if len(userG.NetworkRoles) > 0 {						for netID := range userG.NetworkRoles {							if netID == models.AllNetworks {								return allnetworks							}							allNetworkRoles[netID] = struct{}{}						}					}				}			}		}		filteredNetworks := []models.Network{}		for _, networkI := range allnetworks {			if _, ok := allNetworkRoles[models.NetworkID(networkI.NetID)]; ok {				filteredNetworks = append(filteredNetworks, networkI)			}		}		allnetworks = filteredNetworks	}	return allnetworks}func IsGroupsValid(groups map[models.UserGroupID]struct{}) error {	for groupID := range groups {		_, err := GetUserGroup(groupID)		if err != nil {			return fmt.Errorf("user group `%s` not found", groupID)		}	}	return nil}func IsGroupValid(groupID models.UserGroupID) error {	_, err := GetUserGroup(groupID)	if err != nil {		return fmt.Errorf("user group `%s` not found", groupID)	}	return nil}func IsNetworkRolesValid(networkRoles map[models.NetworkID]map[models.UserRoleID]struct{}) error {	for netID, netRoles := range networkRoles {		if netID != models.AllNetworks {			_, err := logic.GetNetwork(netID.String())			if err != nil {				return fmt.Errorf("failed to fetch network %s ", netID)			}		}		for netRoleID := range netRoles {			role, err := logic.GetRole(netRoleID)			if err != nil {				return fmt.Errorf("failed to fetch role %s ", netRoleID)			}			if role.NetworkID == "" {				return fmt.Errorf("cannot use platform as network role %s", netRoleID)			}		}	}	return nil}// PrepareOauthUserFromInvite - init oauth user before createfunc PrepareOauthUserFromInvite(in models.UserInvite) (models.User, error) {	var newPass, fetchErr = logic.FetchPassValue("")	if fetchErr != nil {		return models.User{}, fetchErr	}	user := models.User{		UserName: in.Email,		Password: newPass,	}	user.UserGroups = in.UserGroups	user.NetworkRoles = in.NetworkRoles	user.PlatformRoleID = models.UserRoleID(in.PlatformRoleID)	if user.PlatformRoleID == "" {		user.PlatformRoleID = models.ServiceUser	}	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()	}}func CreateDefaultUserPolicies(netID models.NetworkID) {	if netID.String() == "" {		return	}	if !logic.IsAclExists(fmt.Sprintf("%s.%s-grp", netID, models.NetworkAdmin)) {		defaultUserAcl := models.Acl{			ID:        fmt.Sprintf("%s.%s-grp", netID, models.NetworkAdmin),			Name:      "Network Admin",			MetaData:  "This Policy allows all network admins to communicate with all remote access gateways",			Default:   true,			NetworkID: netID,			RuleType:  models.UserPolicy,			Src: []models.AclPolicyTag{				{					ID:    models.UserGroupAclID,					Value: fmt.Sprintf("%s-%s-grp", netID, models.NetworkAdmin),				},				{					ID:    models.UserGroupAclID,					Value: fmt.Sprintf("global-%s-grp", models.NetworkAdmin),				},			},			Dst: []models.AclPolicyTag{				{					ID:    models.DeviceAclID,					Value: fmt.Sprintf("%s.%s", netID, models.RemoteAccessTagName),				}},			AllowedDirection: models.TrafficDirectionUni,			Enabled:          true,			CreatedBy:        "auto",			CreatedAt:        time.Now().UTC(),		}		logic.InsertAcl(defaultUserAcl)	}	if !logic.IsAclExists(fmt.Sprintf("%s.%s-grp", netID, models.NetworkUser)) {		defaultUserAcl := models.Acl{			ID:        fmt.Sprintf("%s.%s-grp", netID, models.NetworkUser),			Name:      "Network User",			MetaData:  "This Policy allows all network users to communicate with all remote access gateways",			Default:   true,			NetworkID: netID,			RuleType:  models.UserPolicy,			Src: []models.AclPolicyTag{				{					ID:    models.UserGroupAclID,					Value: fmt.Sprintf("%s-%s-grp", netID, models.NetworkUser),				},				{					ID:    models.UserGroupAclID,					Value: fmt.Sprintf("global-%s-grp", models.NetworkUser),				},			},			Dst: []models.AclPolicyTag{				{					ID:    models.DeviceAclID,					Value: fmt.Sprintf("%s.%s", netID, models.RemoteAccessTagName),				}},			AllowedDirection: models.TrafficDirectionUni,			Enabled:          true,			CreatedBy:        "auto",			CreatedAt:        time.Now().UTC(),		}		logic.InsertAcl(defaultUserAcl)	}}func GetUserGroupsInNetwork(netID models.NetworkID) (networkGrps map[models.UserGroupID]models.UserGroup) {	groups, _ := ListUserGroups()	networkGrps = make(map[models.UserGroupID]models.UserGroup)	for _, grp := range groups {		if _, ok := grp.NetworkRoles[models.AllNetworks]; ok {			networkGrps[grp.ID] = grp			continue		}		if _, ok := grp.NetworkRoles[netID]; ok {			networkGrps[grp.ID] = grp		}	}	return}func AddGlobalNetRolesToAdmins(u models.User) {	if u.PlatformRoleID != models.SuperAdminRole && u.PlatformRoleID != models.AdminRole {		return	}	if u.UserGroups == nil {		u.UserGroups = make(map[models.UserGroupID]struct{})	}	u.UserGroups[models.UserGroupID(fmt.Sprintf("global-%s-grp", models.NetworkAdmin))] = struct{}{}	logic.UpsertUser(u)}
 |