mirror of
https://github.com/gravitl/netmaker.git
synced 2026-04-23 00:17:10 +08:00
Merge branch 'release-v1.5.0' into NM-258
This commit is contained in:
+86
-53
@@ -18,6 +18,7 @@ import (
|
||||
"github.com/gravitl/netmaker/database"
|
||||
"github.com/gravitl/netmaker/logger"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/gravitl/netmaker/servercfg"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -36,77 +37,63 @@ var ResetIDPSyncHook = func() {}
|
||||
|
||||
// HasSuperAdmin - checks if server has an superadmin/owner
|
||||
func HasSuperAdmin() (bool, error) {
|
||||
collection, err := database.FetchRecords(database.USERS_TABLE_NAME)
|
||||
users, err := GetUsersDB()
|
||||
if err != nil {
|
||||
if database.IsEmptyRecord(err) {
|
||||
return false, nil
|
||||
} else {
|
||||
return true, err
|
||||
}
|
||||
return true, err
|
||||
}
|
||||
for _, user := range users {
|
||||
if user.PlatformRoleID == models.SuperAdminRole {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
for _, value := range collection { // filter for isadmin true
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// GetUsersDB - gets users
|
||||
func GetUsersDB() ([]models.User, error) {
|
||||
if servercfg.CacheEnabled() {
|
||||
users := getUsersFromCache()
|
||||
if len(users) != 0 {
|
||||
return users, nil
|
||||
}
|
||||
}
|
||||
|
||||
var users []models.User
|
||||
collection, err := database.FetchRecords(database.USERS_TABLE_NAME)
|
||||
if err != nil {
|
||||
return users, err
|
||||
}
|
||||
|
||||
cacheMap := make(map[string]models.User, len(collection))
|
||||
for _, value := range collection {
|
||||
var user models.User
|
||||
err = json.Unmarshal([]byte(value), &user)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if user.PlatformRoleID == models.SuperAdminRole {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
return false, err
|
||||
}
|
||||
|
||||
// GetUsersDB - gets users
|
||||
func GetUsersDB() ([]models.User, error) {
|
||||
|
||||
var users []models.User
|
||||
|
||||
collection, err := database.FetchRecords(database.USERS_TABLE_NAME)
|
||||
|
||||
if err != nil {
|
||||
return users, err
|
||||
}
|
||||
|
||||
for _, value := range collection {
|
||||
|
||||
var user models.User
|
||||
err = json.Unmarshal([]byte(value), &user)
|
||||
if err != nil {
|
||||
continue // get users
|
||||
}
|
||||
users = append(users, user)
|
||||
cacheMap[user.UserName] = user
|
||||
}
|
||||
|
||||
return users, err
|
||||
if servercfg.CacheEnabled() {
|
||||
loadUsersIntoCache(cacheMap)
|
||||
}
|
||||
return users, nil
|
||||
}
|
||||
|
||||
// GetUsers - gets users
|
||||
func GetUsers() ([]models.ReturnUser, error) {
|
||||
|
||||
var users []models.ReturnUser
|
||||
|
||||
collection, err := database.FetchRecords(database.USERS_TABLE_NAME)
|
||||
|
||||
dbUsers, err := GetUsersDB()
|
||||
if err != nil {
|
||||
return users, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, value := range collection {
|
||||
|
||||
var user models.ReturnUser
|
||||
err = json.Unmarshal([]byte(value), &user)
|
||||
if err != nil {
|
||||
continue // get users
|
||||
}
|
||||
|
||||
user.IsSuperAdmin = user.PlatformRoleID == models.SuperAdminRole
|
||||
user.IsAdmin = user.PlatformRoleID == models.SuperAdminRole || user.PlatformRoleID == models.AdminRole
|
||||
users = append(users, user)
|
||||
users := make([]models.ReturnUser, 0, len(dbUsers))
|
||||
for _, u := range dbUsers {
|
||||
users = append(users, ToReturnUser(u))
|
||||
}
|
||||
|
||||
return users, err
|
||||
return users, nil
|
||||
}
|
||||
|
||||
// IsOauthUser - returns
|
||||
@@ -192,6 +179,9 @@ func CreateUser(user *models.User) error {
|
||||
logger.Log(0, "failed to insert user", err.Error())
|
||||
return err
|
||||
}
|
||||
if servercfg.CacheEnabled() {
|
||||
storeUserInCache(*user)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -273,7 +263,9 @@ func UpsertUser(user models.User) error {
|
||||
slog.Error("error inserting user", "user", user.UserName, "error", err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
if servercfg.CacheEnabled() {
|
||||
storeUserInCache(user)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -407,6 +399,12 @@ func UpdateUser(userchange, user *models.User) (*models.User, error) {
|
||||
if err = database.Insert(user.UserName, string(data), database.USERS_TABLE_NAME); err != nil {
|
||||
return &models.User{}, err
|
||||
}
|
||||
if servercfg.CacheEnabled() {
|
||||
if queryUser != user.UserName {
|
||||
deleteUserFromCache(queryUser)
|
||||
}
|
||||
storeUserInCache(*user)
|
||||
}
|
||||
logger.Log(1, "updated user", queryUser)
|
||||
return user, nil
|
||||
}
|
||||
@@ -446,6 +444,9 @@ func DeleteUser(user string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if servercfg.CacheEnabled() {
|
||||
deleteUserFromCache(user)
|
||||
}
|
||||
go RemoveUserFromAclPolicy(user)
|
||||
return (&schema.UserAccessToken{UserName: user}).DeleteAllUserTokens(db.WithContext(context.TODO()))
|
||||
}
|
||||
@@ -535,3 +536,35 @@ func IsStateValid(state string) (string, bool) {
|
||||
func delState(state string) error {
|
||||
return database.DeleteRecord(database.SSO_STATE_CACHE, state)
|
||||
}
|
||||
|
||||
// CleanExpiredSSOStates removes expired SSO state entries from the database
|
||||
// to prevent unbounded table growth that degrades FetchRecord performance.
|
||||
func CleanExpiredSSOStates() error {
|
||||
records, err := database.FetchRecords(database.SSO_STATE_CACHE)
|
||||
if err != nil {
|
||||
if database.IsEmptyRecord(err) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
for key, value := range records {
|
||||
var s models.SsoState
|
||||
if err := json.Unmarshal([]byte(value), &s); err != nil {
|
||||
_ = database.DeleteRecord(database.SSO_STATE_CACHE, key)
|
||||
continue
|
||||
}
|
||||
if s.IsExpired() {
|
||||
_ = database.DeleteRecord(database.SSO_STATE_CACHE, key)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddSSOStateCleanupHook registers a periodic cleanup of expired SSO states
|
||||
func AddSSOStateCleanupHook() {
|
||||
HookManagerCh <- models.HookDetails{
|
||||
ID: "sso-state-cleanup",
|
||||
Hook: WrapHook(CleanExpiredSSOStates),
|
||||
Interval: 15 * time.Minute,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -566,6 +566,7 @@ func getNameserversForNode(node *models.Node) (returnNsLi []models.Nameserver) {
|
||||
IPs: filteredIps,
|
||||
MatchDomain: domain.Domain,
|
||||
IsSearchDomain: domain.IsSearchDomain,
|
||||
IsADDomain: domain.IsADDomain,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -584,6 +585,7 @@ func getNameserversForNode(node *models.Node) (returnNsLi []models.Nameserver) {
|
||||
IPs: filteredIps,
|
||||
MatchDomain: domain.Domain,
|
||||
IsSearchDomain: domain.IsSearchDomain,
|
||||
IsADDomain: domain.IsADDomain,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -639,6 +641,7 @@ func getNameserversForHost(h *models.Host) (returnNsLi []models.Nameserver) {
|
||||
IPs: filteredIps,
|
||||
MatchDomain: domain.Domain,
|
||||
IsSearchDomain: domain.IsSearchDomain,
|
||||
IsADDomain: domain.IsADDomain,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -657,6 +660,7 @@ func getNameserversForHost(h *models.Host) (returnNsLi []models.Nameserver) {
|
||||
IPs: filteredIps,
|
||||
MatchDomain: domain.Domain,
|
||||
IsSearchDomain: domain.IsSearchDomain,
|
||||
IsADDomain: domain.IsADDomain,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -745,7 +745,7 @@ func getExtpeersExtraRoutes(node models.Node) (egressRoutes []models.EgressNetwo
|
||||
return
|
||||
}
|
||||
for _, extPeer := range extPeers {
|
||||
if len(extPeer.ExtraAllowedIPs) == 0 {
|
||||
if len(extPeer.ExtraAllowedIPs) == 0 || !extPeer.Enabled {
|
||||
continue
|
||||
}
|
||||
if ok, _ := IsNodeAllowedToCommunicate(extPeer.ConvertToStaticNode(), node, true); !ok {
|
||||
|
||||
+61
-21
@@ -4,14 +4,62 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"sort"
|
||||
"sync"
|
||||
|
||||
"github.com/gravitl/netmaker/database"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/gravitl/netmaker/servercfg"
|
||||
)
|
||||
|
||||
var (
|
||||
userCacheMutex = &sync.RWMutex{}
|
||||
usersCacheMap = make(map[string]models.User)
|
||||
)
|
||||
|
||||
func getUserFromCache(username string) (models.User, bool) {
|
||||
userCacheMutex.RLock()
|
||||
user, ok := usersCacheMap[username]
|
||||
userCacheMutex.RUnlock()
|
||||
return user, ok
|
||||
}
|
||||
|
||||
func getUsersFromCache() []models.User {
|
||||
userCacheMutex.RLock()
|
||||
users := make([]models.User, 0, len(usersCacheMap))
|
||||
for _, user := range usersCacheMap {
|
||||
users = append(users, user)
|
||||
}
|
||||
userCacheMutex.RUnlock()
|
||||
return users
|
||||
}
|
||||
|
||||
func storeUserInCache(user models.User) {
|
||||
userCacheMutex.Lock()
|
||||
usersCacheMap[user.UserName] = user
|
||||
userCacheMutex.Unlock()
|
||||
}
|
||||
|
||||
func deleteUserFromCache(username string) {
|
||||
userCacheMutex.Lock()
|
||||
delete(usersCacheMap, username)
|
||||
userCacheMutex.Unlock()
|
||||
}
|
||||
|
||||
func loadUsersIntoCache(users map[string]models.User) {
|
||||
userCacheMutex.Lock()
|
||||
usersCacheMap = users
|
||||
userCacheMutex.Unlock()
|
||||
}
|
||||
|
||||
// GetUser - gets a user
|
||||
// TODO support "masteradmin"
|
||||
func GetUser(username string) (*models.User, error) {
|
||||
if servercfg.CacheEnabled() {
|
||||
if user, ok := getUserFromCache(username); ok {
|
||||
user.IsSuperAdmin = user.PlatformRoleID == models.SuperAdminRole
|
||||
user.IsAdmin = user.PlatformRoleID == models.SuperAdminRole || user.PlatformRoleID == models.AdminRole
|
||||
return &user, nil
|
||||
}
|
||||
}
|
||||
var user models.User
|
||||
record, err := database.FetchRecord(database.USERS_TABLE_NAME, username)
|
||||
if err != nil {
|
||||
@@ -23,23 +71,19 @@ func GetUser(username string) (*models.User, error) {
|
||||
|
||||
user.IsSuperAdmin = user.PlatformRoleID == models.SuperAdminRole
|
||||
user.IsAdmin = user.PlatformRoleID == models.SuperAdminRole || user.PlatformRoleID == models.AdminRole
|
||||
if servercfg.CacheEnabled() {
|
||||
storeUserInCache(user)
|
||||
}
|
||||
return &user, err
|
||||
}
|
||||
|
||||
// GetReturnUser - gets a user
|
||||
func GetReturnUser(username string) (models.ReturnUser, error) {
|
||||
var user models.ReturnUser
|
||||
record, err := database.FetchRecord(database.USERS_TABLE_NAME, username)
|
||||
u, err := GetUser(username)
|
||||
if err != nil {
|
||||
return user, err
|
||||
}
|
||||
if err = json.Unmarshal([]byte(record), &user); err != nil {
|
||||
return models.ReturnUser{}, err
|
||||
}
|
||||
|
||||
user.IsSuperAdmin = user.PlatformRoleID == models.SuperAdminRole
|
||||
user.IsAdmin = user.PlatformRoleID == models.SuperAdminRole || user.PlatformRoleID == models.AdminRole
|
||||
return user, err
|
||||
return ToReturnUser(*u), nil
|
||||
}
|
||||
|
||||
// ToReturnUser - gets a user as a return user
|
||||
@@ -160,19 +204,15 @@ func ListPendingUsers() ([]models.User, error) {
|
||||
}
|
||||
|
||||
func GetUserMap() (map[string]models.User, error) {
|
||||
userMap := make(map[string]models.User)
|
||||
records, err := database.FetchRecords(database.USERS_TABLE_NAME)
|
||||
users, err := GetUsersDB()
|
||||
if err != nil && !database.IsEmptyRecord(err) {
|
||||
return userMap, err
|
||||
return nil, err
|
||||
}
|
||||
for _, record := range records {
|
||||
user := models.User{}
|
||||
err = json.Unmarshal([]byte(record), &user)
|
||||
if err == nil {
|
||||
user.IsSuperAdmin = user.PlatformRoleID == models.SuperAdminRole
|
||||
user.IsAdmin = user.PlatformRoleID == models.SuperAdminRole || user.PlatformRoleID == models.AdminRole
|
||||
userMap[user.UserName] = user
|
||||
}
|
||||
userMap := make(map[string]models.User, len(users))
|
||||
for _, user := range users {
|
||||
user.IsSuperAdmin = user.PlatformRoleID == models.SuperAdminRole
|
||||
user.IsAdmin = user.PlatformRoleID == models.SuperAdminRole || user.PlatformRoleID == models.AdminRole
|
||||
userMap[user.UserName] = user
|
||||
}
|
||||
return userMap, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user