add membership

This commit is contained in:
Fran Jurmanović
2025-06-26 00:51:54 +02:00
parent 69733e4940
commit 74df36cd0d
24 changed files with 863 additions and 83 deletions

19
local/model/permission.go Normal file
View File

@@ -0,0 +1,19 @@
package model
import (
"github.com/google/uuid"
"gorm.io/gorm"
)
// Permission represents an action that can be performed in the system.
type Permission struct {
ID uuid.UUID `json:"id" gorm:"type:uuid;primary_key;"`
Name string `json:"name" gorm:"unique_index;not null"`
}
// BeforeCreate is a GORM hook that runs before creating new credentials
func (s *Permission) BeforeCreate(tx *gorm.DB) error {
s.ID = uuid.New()
return nil
}

View File

@@ -0,0 +1,53 @@
package model
// Permission constants
const (
ServerView = "server.view"
ServerCreate = "server.create"
ServerUpdate = "server.update"
ServerDelete = "server.delete"
ServerStart = "server.start"
ServerStop = "server.stop"
ConfigView = "config.view"
ConfigUpdate = "config.update"
UserView = "user.view"
UserCreate = "user.create"
UserUpdate = "user.update"
UserDelete = "user.delete"
RoleView = "role.view"
RoleCreate = "role.create"
RoleUpdate = "role.update"
RoleDelete = "role.delete"
MembershipCreate = "membership.create"
MembershipView = "membership.view"
MembershipEdit = "membership.edit"
)
// AllPermissions returns a slice of all permission strings.
func AllPermissions() []string {
return []string{
ServerView,
ServerCreate,
ServerUpdate,
ServerDelete,
ServerStart,
ServerStop,
ConfigView,
ConfigUpdate,
UserView,
UserCreate,
UserUpdate,
UserDelete,
RoleView,
RoleCreate,
RoleUpdate,
RoleDelete,
MembershipCreate,
MembershipView,
MembershipEdit,
}
}

20
local/model/role.go Normal file
View File

@@ -0,0 +1,20 @@
package model
import (
"github.com/google/uuid"
"gorm.io/gorm"
)
// Role represents a user role in the system.
type Role struct {
ID uuid.UUID `json:"id" gorm:"type:uuid;primary_key;"`
Name string `json:"name" gorm:"unique_index;not null"`
Permissions []Permission `json:"permissions" gorm:"many2many:role_permissions;"`
}
// BeforeCreate is a GORM hook that runs before creating new credentials
func (s *Role) BeforeCreate(tx *gorm.DB) error {
s.ID = uuid.New()
return nil
}

View File

@@ -24,7 +24,7 @@ type Server struct {
Port int `gorm:"not null" json:"-"`
Path string `gorm:"not null" json:"path"` // e.g. "/acc/servers/server1/"
ServiceName string `gorm:"not null" json:"serviceName"` // Windows service name
State ServerState `gorm:"-" json:"state"`
State *ServerState `gorm:"-" json:"state"`
DateCreated time.Time `json:"dateCreated"`
FromSteamCMD bool `gorm:"not null; default:true" json:"-"`
}

70
local/model/user.go Normal file
View File

@@ -0,0 +1,70 @@
package model
import (
"errors"
"github.com/google/uuid"
"gorm.io/gorm"
)
// User represents a user account in the system.
type User struct {
ID uuid.UUID `json:"id" gorm:"type:uuid;primary_key;"`
Username string `json:"username" gorm:"unique_index;not null"`
Password string `json:"password" gorm:"not null"`
RoleID uuid.UUID `json:"role_id" gorm:"type:uuid"`
Role Role `json:"role"`
}
// BeforeCreate is a GORM hook that runs before creating new credentials
func (s *User) BeforeCreate(tx *gorm.DB) error {
s.ID = uuid.New()
// Encrypt password before saving
encrypted, err := EncryptPassword(s.Password)
if err != nil {
return err
}
s.Password = encrypted
return nil
}
// BeforeUpdate is a GORM hook that runs before updating credentials
func (s *User) BeforeUpdate(tx *gorm.DB) error {
// Only encrypt if password field is being updated
if tx.Statement.Changed("Password") {
encrypted, err := EncryptPassword(s.Password)
if err != nil {
return err
}
s.Password = encrypted
}
return nil
}
// AfterFind is a GORM hook that runs after fetching credentials
func (s *User) AfterFind(tx *gorm.DB) error {
// Decrypt password after fetching
if s.Password != "" {
decrypted, err := DecryptPassword(s.Password)
if err != nil {
return err
}
s.Password = decrypted
}
return nil
}
// Validate checks if the credentials are valid
func (s *User) Validate() error {
if s.Username == "" {
return errors.New("username is required")
}
if s.Password == "" {
return errors.New("password is required")
}
return nil
}