mirror of
https://github.com/gravitl/netmaker.git
synced 2026-04-22 16:07:11 +08:00
167 lines
4.4 KiB
Go
167 lines
4.4 KiB
Go
package schema
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/gravitl/netmaker/db"
|
|
dbtypes "github.com/gravitl/netmaker/db/types"
|
|
"gorm.io/datatypes"
|
|
)
|
|
|
|
type AuthType string
|
|
|
|
var (
|
|
BasicAuth AuthType = "basic_auth"
|
|
OAuth AuthType = "oauth"
|
|
)
|
|
|
|
var (
|
|
ErrUserIdentifiersNotProvided = errors.New("user identifiers not provided")
|
|
)
|
|
|
|
type User struct {
|
|
ID string `gorm:"primaryKey" json:"id"`
|
|
Username string `gorm:"unique" json:"username"`
|
|
DisplayName string `json:"display_name"`
|
|
PlatformRoleID UserRoleID `json:"platform_role_id"`
|
|
ExternalIdentityProviderID string `json:"external_identity_provider_id"`
|
|
AccountDisabled bool `json:"account_disabled"`
|
|
AuthType AuthType `json:"auth_type"`
|
|
Password string `json:"password"`
|
|
IsMFAEnabled bool `json:"is_mfa_enabled"`
|
|
TOTPSecret string `json:"totp_secret"`
|
|
// NOTE: json tag is different from field name to ensure compatibility with the older model.
|
|
LastLoginAt time.Time `json:"last_login_time"`
|
|
// NOTE: json tag is different from field name to ensure compatibility with the older model.
|
|
UserGroups datatypes.JSONType[map[UserGroupID]struct{}] `json:"user_group_ids"`
|
|
CreatedBy string `json:"created_by"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
UpdatedAt time.Time `json:"updated_at"`
|
|
}
|
|
|
|
func (u *User) TableName() string {
|
|
return "users_v1"
|
|
}
|
|
|
|
func (u *User) SuperAdminExists(ctx context.Context) (bool, error) {
|
|
var exists bool
|
|
err := db.FromContext(ctx).Raw(
|
|
"SELECT EXISTS (SELECT 1 FROM users_v1 WHERE platform_role_id = ?)",
|
|
SuperAdminRole,
|
|
).Scan(&exists).Error
|
|
return exists, err
|
|
}
|
|
|
|
func (u *User) Create(ctx context.Context) error {
|
|
if u.ID == "" {
|
|
u.ID = uuid.NewString()
|
|
}
|
|
|
|
return db.FromContext(ctx).Model(&User{}).Create(u).Error
|
|
}
|
|
|
|
func (u *User) Get(ctx context.Context) error {
|
|
if u.ID == "" && u.Username == "" {
|
|
return ErrUserIdentifiersNotProvided
|
|
}
|
|
|
|
return db.FromContext(ctx).Model(&User{}).
|
|
Where("id = ? OR username = ?", u.ID, u.Username).
|
|
First(u).
|
|
Error
|
|
}
|
|
|
|
func (u *User) GetByExternalID(ctx context.Context) error {
|
|
if u.ExternalIdentityProviderID == "" {
|
|
return ErrUserIdentifiersNotProvided
|
|
}
|
|
|
|
return db.FromContext(ctx).Model(&User{}).
|
|
Where("external_identity_provider_id = ?", u.ExternalIdentityProviderID).
|
|
First(u).
|
|
Error
|
|
}
|
|
|
|
func (u *User) GetSuperAdmin(ctx context.Context) error {
|
|
return db.FromContext(ctx).Model(u).
|
|
Where("platform_role_id = ?", SuperAdminRole).
|
|
First(u).
|
|
Error
|
|
}
|
|
|
|
func (u *User) Count(ctx context.Context, options ...dbtypes.Option) (int, error) {
|
|
var count int64
|
|
query := db.FromContext(ctx).Model(&User{})
|
|
|
|
for _, option := range options {
|
|
query = option(query)
|
|
}
|
|
|
|
err := query.Count(&count).Error
|
|
return int(count), err
|
|
}
|
|
|
|
func (u *User) ListAll(ctx context.Context, options ...dbtypes.Option) ([]User, error) {
|
|
var users []User
|
|
query := db.FromContext(ctx).Model(&User{})
|
|
|
|
for _, option := range options {
|
|
query = option(query)
|
|
}
|
|
|
|
err := query.Find(&users).Error
|
|
return users, err
|
|
}
|
|
|
|
func (u *User) Update(ctx context.Context) error {
|
|
if u.ID == "" && u.Username == "" {
|
|
return ErrUserIdentifiersNotProvided
|
|
}
|
|
|
|
return db.FromContext(ctx).Model(&User{}).
|
|
Where("id = ? OR username = ?", u.ID, u.Username).
|
|
Updates(u).
|
|
Error
|
|
}
|
|
|
|
func (u *User) UpdateAccountStatus(ctx context.Context) error {
|
|
if u.ID == "" && u.Username == "" {
|
|
return ErrUserIdentifiersNotProvided
|
|
}
|
|
|
|
return db.FromContext(ctx).Model(&User{}).
|
|
Where("id = ? OR username = ?", u.ID, u.Username).
|
|
Updates(map[string]any{
|
|
"account_disabled": u.AccountDisabled,
|
|
}).
|
|
Error
|
|
}
|
|
|
|
func (u *User) UpdateMFA(ctx context.Context) error {
|
|
if u.ID == "" && u.Username == "" {
|
|
return ErrUserIdentifiersNotProvided
|
|
}
|
|
|
|
return db.FromContext(ctx).Model(&User{}).
|
|
Where("id = ? OR username = ?", u.ID, u.Username).
|
|
Updates(map[string]any{
|
|
"is_mfa_enabled": u.IsMFAEnabled,
|
|
"totp_secret": u.TOTPSecret,
|
|
}).
|
|
Error
|
|
}
|
|
|
|
func (u *User) Delete(ctx context.Context) error {
|
|
if u.ID == "" && u.Username == "" {
|
|
return ErrUserIdentifiersNotProvided
|
|
}
|
|
|
|
return db.FromContext(ctx).Model(&User{}).
|
|
Where("id = ? OR username = ?", u.ID, u.Username).
|
|
Delete(u).
|
|
Error
|
|
}
|