You've already forked ionscale
mirror of
https://github.com/jsiebens/ionscale.git
synced 2026-04-05 12:32:58 +01:00
145 lines
3.6 KiB
Go
145 lines
3.6 KiB
Go
package domain
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"github.com/jsiebens/ionscale/internal/util"
|
|
"gorm.io/gorm"
|
|
"time"
|
|
)
|
|
|
|
type SystemRole string
|
|
|
|
const (
|
|
SystemRoleNone SystemRole = ""
|
|
SystemRoleAdmin SystemRole = "admin"
|
|
)
|
|
|
|
func (s SystemRole) IsAdmin() bool {
|
|
return s == SystemRoleAdmin
|
|
}
|
|
|
|
type UserType string
|
|
|
|
const (
|
|
UserTypeService UserType = "service"
|
|
UserTypePerson UserType = "person"
|
|
)
|
|
|
|
type UserRole string
|
|
|
|
const (
|
|
UserRoleNone UserRole = ""
|
|
UserRoleMember UserRole = "member"
|
|
UserRoleAdmin UserRole = "admin"
|
|
)
|
|
|
|
func (s UserRole) IsAdmin() bool {
|
|
return s == UserRoleAdmin
|
|
}
|
|
|
|
type UserRepository interface {
|
|
GetOrCreateServiceUser(ctx context.Context, tailnet *Tailnet) (*User, bool, error)
|
|
GetOrCreateUserWithAccount(ctx context.Context, tailnet *Tailnet, account *Account) (*User, bool, error)
|
|
GetUser(ctx context.Context, userID uint64) (*User, error)
|
|
DeleteUser(ctx context.Context, userID uint64) error
|
|
ListUsers(ctx context.Context, tailnetID uint64) (Users, error)
|
|
DeleteUsersByTailnet(ctx context.Context, tailnetID uint64) error
|
|
SetUserLastAuthenticated(ctx context.Context, userID uint64, timestamp time.Time) error
|
|
}
|
|
|
|
type User struct {
|
|
ID uint64 `gorm:"primary_key"`
|
|
Name string
|
|
UserType UserType
|
|
LastAuthenticated *time.Time
|
|
TailnetID uint64
|
|
Tailnet Tailnet
|
|
AccountID *uint64
|
|
Account *Account
|
|
}
|
|
|
|
type Users []User
|
|
|
|
func (r *repository) GetOrCreateServiceUser(ctx context.Context, tailnet *Tailnet) (*User, bool, error) {
|
|
user := &User{}
|
|
id := util.NextID()
|
|
|
|
query := User{Name: tailnet.Name, TailnetID: tailnet.ID, UserType: UserTypeService}
|
|
attrs := User{ID: id, Name: tailnet.Name, TailnetID: tailnet.ID, UserType: UserTypeService}
|
|
|
|
tx := r.withContext(ctx).Where(query).Attrs(attrs).FirstOrCreate(user)
|
|
|
|
if tx.Error != nil {
|
|
return nil, false, tx.Error
|
|
}
|
|
|
|
return user, user.ID == id, nil
|
|
}
|
|
|
|
func (r *repository) ListUsers(ctx context.Context, tailnetID uint64) (Users, error) {
|
|
var users = []User{}
|
|
|
|
tx := r.withContext(ctx).Where("tailnet_id = ? AND user_type = ?", tailnetID, UserTypePerson).Find(&users)
|
|
|
|
if tx.Error != nil {
|
|
return nil, tx.Error
|
|
}
|
|
|
|
return users, nil
|
|
}
|
|
|
|
func (r *repository) DeleteUsersByTailnet(ctx context.Context, tailnetID uint64) error {
|
|
tx := r.withContext(ctx).Where("tailnet_id = ?", tailnetID).Delete(&User{})
|
|
return tx.Error
|
|
}
|
|
|
|
func (r *repository) GetOrCreateUserWithAccount(ctx context.Context, tailnet *Tailnet, account *Account) (*User, bool, error) {
|
|
user := &User{}
|
|
id := util.NextID()
|
|
|
|
query := User{AccountID: &account.ID, TailnetID: tailnet.ID}
|
|
attrs := User{ID: id, Name: account.LoginName, TailnetID: tailnet.ID, AccountID: &account.ID, UserType: UserTypePerson}
|
|
|
|
tx := r.withContext(ctx).Where(query).Attrs(attrs).FirstOrCreate(user)
|
|
|
|
if tx.Error != nil {
|
|
return nil, false, tx.Error
|
|
}
|
|
|
|
return user, user.ID == id, nil
|
|
}
|
|
|
|
func (r *repository) GetUser(ctx context.Context, userID uint64) (*User, error) {
|
|
var m User
|
|
tx := r.withContext(ctx).Preload("Tailnet").Preload("Account").Take(&m, "id = ?", userID)
|
|
|
|
if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
|
|
return nil, nil
|
|
}
|
|
|
|
if tx.Error != nil {
|
|
return nil, tx.Error
|
|
}
|
|
|
|
return &m, nil
|
|
}
|
|
|
|
func (r *repository) DeleteUser(ctx context.Context, userID uint64) error {
|
|
tx := r.withContext(ctx).Delete(&User{ID: userID})
|
|
return tx.Error
|
|
}
|
|
|
|
func (r *repository) SetUserLastAuthenticated(ctx context.Context, userID uint64, timestamp time.Time) error {
|
|
tx := r.withContext(ctx).
|
|
Model(User{}).
|
|
Where("id = ?", userID).
|
|
Updates(map[string]interface{}{"last_authenticated": ×tamp})
|
|
|
|
if tx.Error != nil {
|
|
return tx.Error
|
|
}
|
|
|
|
return nil
|
|
}
|