Files
Abhishek Kondur 12cc967ba1 Fixes/v1.5.1 (#3938)
* fix(go): set persistent keep alive when registering host using sso;

* fix(go): run posture check violations on delete;

* fix(go): upsert node on approving pending host;

* fix(go): resolve concurrency issues during group delete cleanup;

* fix(go): update doc links;

* fix(go): add created and updated fields to host;

* fix(go): skip delete and update superadmin on sync users;

* fix(go): use conn directly for now;

* fix(go): remove acl for idp groups;

* fix(go): quote fields;

* fix(go): use filters with count;

* feat(go): add a search query;

* fix(go): cleanup acls;

* fix(go): review fixes;

* fix(go): remove additional loop;

* fix(go): fix

* v1.5.1: separate out idp sync and reset signals for HA

* v1.5.1: add grps with name for logging

* v1.5.1: clear posture check violations when all checks are deleted

* v1.5.1: set static when default host

* v1.5.1: fix db status check

* rm set max conns

* v1.5.1: reset auto assigned gw when disconnected

* fix(go): skip global network admin and user groups when splitting;

* v1.5.1: fix update node call from client

* fix(go): separate out migration from normal usage;

* fix(go): skip default groups;

* fix(go): create policies for existing groups on network create;

* fix(go): skip fatal log on clickhouse conn;

* fix(go): add posture check cleanup;

---------

Co-authored-by: VishalDalwadi <dalwadivishal26@gmail.com>
Co-authored-by: Vishal Dalwadi <51291657+VishalDalwadi@users.noreply.github.com>
2026-03-28 01:08:59 +05:30

222 lines
6.0 KiB
Go

package logic
import (
"context"
"encoding/json"
"errors"
"sort"
"github.com/gravitl/netmaker/database"
"github.com/gravitl/netmaker/db"
"github.com/gravitl/netmaker/models"
"github.com/gravitl/netmaker/schema"
"gorm.io/datatypes"
)
var SyncFromIDP = func() error { return nil }
// GetReturnUser - gets a user
func GetReturnUser(username string) (models.ReturnUser, error) {
_user := &schema.User{
Username: username,
}
err := _user.Get(db.WithContext(context.TODO()))
if err != nil {
return models.ReturnUser{}, err
}
return ToReturnUser(_user), nil
}
// ToReturnUser - gets a user as a return user
func ToReturnUser(user *schema.User) models.ReturnUser {
return models.ReturnUser{
UserName: user.Username,
ExternalIdentityProviderID: user.ExternalIdentityProviderID,
IsMFAEnabled: user.IsMFAEnabled,
DisplayName: user.DisplayName,
AccountDisabled: user.AccountDisabled,
IsAdmin: user.PlatformRoleID == schema.SuperAdminRole || user.PlatformRoleID == schema.AdminRole,
IsSuperAdmin: user.PlatformRoleID == schema.SuperAdminRole,
AuthType: user.AuthType,
// no need to set. field not in use.
RemoteGwIDs: nil,
UserGroups: user.UserGroups.Data(),
PlatformRoleID: user.PlatformRoleID,
// no need to set. field not in use.
NetworkRoles: nil,
LastLoginTime: user.LastLoginAt,
CreatedBy: user.CreatedBy,
CreatedAt: user.CreatedAt,
UpdatedAt: user.UpdatedAt,
}
}
// ToUserEventLog - converts a user to an event log entry with resolved group/role names
func ToUserEventLog(user *schema.User) models.UserEventLog {
log := models.UserEventLog{
ReturnUser: ToReturnUser(user),
UserGroupsWithNames: make(map[string]string),
}
for gID := range user.UserGroups.Data() {
grp, err := GetUserGroup(gID)
if err == nil {
log.UserGroupsWithNames[string(gID)] = grp.Name
} else {
log.UserGroupsWithNames[string(gID)] = string(gID)
}
}
return log
}
// SetUserDefaults - sets the defaults of a user to avoid empty fields
func SetUserDefaults(user *schema.User) {
if len(user.UserGroups.Data()) == 0 {
user.UserGroups = datatypes.NewJSONType(make(map[schema.UserGroupID]struct{}))
}
}
// SortUsers - Sorts slice of Users by username
func SortUsers(unsortedUsers []models.ReturnUser) {
sort.Slice(unsortedUsers, func(i, j int) bool {
return unsortedUsers[i].UserName < unsortedUsers[j].UserName
})
}
// GetSuperAdmin - fetches superadmin user
func GetSuperAdmin() (models.ReturnUser, error) {
_user := &schema.User{}
err := _user.GetSuperAdmin(db.WithContext(context.TODO()))
if err != nil {
return models.ReturnUser{}, err
}
return ToReturnUser(_user), nil
}
func InsertPendingUser(u *models.User) error {
data, err := json.Marshal(u)
if err != nil {
return err
}
return database.Insert(u.UserName, string(data), database.PENDING_USERS_TABLE_NAME)
}
func DeletePendingUser(username string) error {
return database.DeleteRecord(database.PENDING_USERS_TABLE_NAME, username)
}
func IsPendingUser(username string) bool {
records, err := database.FetchRecords(database.PENDING_USERS_TABLE_NAME)
if err != nil {
return false
}
for _, record := range records {
u := models.ReturnUser{}
err := json.Unmarshal([]byte(record), &u)
if err == nil && u.UserName == username {
return true
}
}
return false
}
func ListPendingReturnUsers() ([]models.ReturnUser, error) {
pendingUsers := []models.ReturnUser{}
records, err := database.FetchRecords(database.PENDING_USERS_TABLE_NAME)
if err != nil && !database.IsEmptyRecord(err) {
return pendingUsers, err
}
for _, record := range records {
user := models.ReturnUser{}
err = json.Unmarshal([]byte(record), &user)
if err == nil {
user.IsSuperAdmin = user.PlatformRoleID == schema.SuperAdminRole
user.IsAdmin = user.PlatformRoleID == schema.SuperAdminRole || user.PlatformRoleID == schema.AdminRole
pendingUsers = append(pendingUsers, user)
}
}
return pendingUsers, nil
}
func ListPendingUsers() ([]models.User, error) {
var pendingUsers []models.User
records, err := database.FetchRecords(database.PENDING_USERS_TABLE_NAME)
if err != nil && !database.IsEmptyRecord(err) {
return pendingUsers, err
}
for _, record := range records {
var user models.User
err = json.Unmarshal([]byte(record), &user)
if err == nil {
user.IsSuperAdmin = user.PlatformRoleID == schema.SuperAdminRole
user.IsAdmin = user.PlatformRoleID == schema.SuperAdminRole || user.PlatformRoleID == schema.AdminRole
pendingUsers = append(pendingUsers, user)
}
}
return pendingUsers, nil
}
func GetUserMap() (map[string]schema.User, error) {
users, err := (&schema.User{}).ListAll(db.WithContext(context.TODO()))
if err != nil {
return nil, err
}
userMap := make(map[string]schema.User, len(users))
for _, user := range users {
userMap[user.Username] = user
}
return userMap, nil
}
func InsertUserInvite(invite models.UserInvite) error {
data, err := json.Marshal(invite)
if err != nil {
return err
}
return database.Insert(invite.Email, string(data), database.USER_INVITES_TABLE_NAME)
}
func GetUserInvite(email string) (in models.UserInvite, err error) {
d, err := database.FetchRecord(database.USER_INVITES_TABLE_NAME, email)
if err != nil {
return
}
err = json.Unmarshal([]byte(d), &in)
return
}
func ListUserInvites() ([]models.UserInvite, error) {
invites := []models.UserInvite{}
records, err := database.FetchRecords(database.USER_INVITES_TABLE_NAME)
if err != nil && !database.IsEmptyRecord(err) {
return invites, err
}
for _, record := range records {
in := models.UserInvite{}
err = json.Unmarshal([]byte(record), &in)
if err == nil {
invites = append(invites, in)
}
}
return invites, nil
}
func DeleteUserInvite(email string) error {
return database.DeleteRecord(database.USER_INVITES_TABLE_NAME, email)
}
func ValidateAndApproveUserInvite(email, code string) error {
in, err := GetUserInvite(email)
if err != nil {
return err
}
if code != in.InviteCode {
return errors.New("invalid code")
}
return nil
}