init bootstrap
This commit is contained in:
182
local/model/role.go
Normal file
182
local/model/role.go
Normal file
@@ -0,0 +1,182 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// Role represents a role in the system
|
||||
type Role struct {
|
||||
BaseModel
|
||||
Name string `json:"name" gorm:"unique;not null;type:varchar(100)"`
|
||||
Description string `json:"description" gorm:"type:text"`
|
||||
Active bool `json:"active" gorm:"default:true"`
|
||||
System bool `json:"system" gorm:"default:false"` // System roles cannot be deleted
|
||||
Users []User `json:"-" gorm:"many2many:user_roles;"`
|
||||
Permissions []Permission `json:"permissions" gorm:"many2many:role_permissions;"`
|
||||
}
|
||||
|
||||
// RoleCreateRequest represents the request to create a new role
|
||||
type RoleCreateRequest struct {
|
||||
Name string `json:"name" validate:"required,min=3,max=100"`
|
||||
Description string `json:"description" validate:"max=500"`
|
||||
PermissionIDs []string `json:"permissionIds"`
|
||||
}
|
||||
|
||||
// RoleUpdateRequest represents the request to update a role
|
||||
type RoleUpdateRequest struct {
|
||||
Name *string `json:"name,omitempty" validate:"omitempty,min=3,max=100"`
|
||||
Description *string `json:"description,omitempty" validate:"omitempty,max=500"`
|
||||
Active *bool `json:"active,omitempty"`
|
||||
PermissionIDs []string `json:"permissionIds,omitempty"`
|
||||
}
|
||||
|
||||
// RoleInfo represents public role information
|
||||
type RoleInfo struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Active bool `json:"active"`
|
||||
System bool `json:"system"`
|
||||
Permissions []PermissionInfo `json:"permissions"`
|
||||
UserCount int64 `json:"userCount"`
|
||||
DateCreated string `json:"dateCreated"`
|
||||
}
|
||||
|
||||
// BeforeCreate is called before creating a role
|
||||
func (r *Role) BeforeCreate(tx *gorm.DB) error {
|
||||
r.BaseModel.BeforeCreate()
|
||||
|
||||
// Normalize name
|
||||
r.Name = strings.ToLower(strings.TrimSpace(r.Name))
|
||||
r.Description = strings.TrimSpace(r.Description)
|
||||
|
||||
return r.Validate()
|
||||
}
|
||||
|
||||
// BeforeUpdate is called before updating a role
|
||||
func (r *Role) BeforeUpdate(tx *gorm.DB) error {
|
||||
r.BaseModel.BeforeUpdate()
|
||||
|
||||
// Normalize fields if they're being updated
|
||||
if r.Name != "" {
|
||||
r.Name = strings.ToLower(strings.TrimSpace(r.Name))
|
||||
}
|
||||
if r.Description != "" {
|
||||
r.Description = strings.TrimSpace(r.Description)
|
||||
}
|
||||
|
||||
return r.Validate()
|
||||
}
|
||||
|
||||
// BeforeDelete is called before deleting a role
|
||||
func (r *Role) BeforeDelete(tx *gorm.DB) error {
|
||||
if r.System {
|
||||
return errors.New("system roles cannot be deleted")
|
||||
}
|
||||
|
||||
// Check if role is assigned to any users
|
||||
var userCount int64
|
||||
if err := tx.Model(&User{}).Where("roles.id = ?", r.ID).Joins("JOIN user_roles ON users.id = user_roles.user_id").Count(&userCount).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if userCount > 0 {
|
||||
return errors.New("cannot delete role that is assigned to users")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Validate validates role data
|
||||
func (r *Role) Validate() error {
|
||||
if r.Name == "" {
|
||||
return errors.New("role name is required")
|
||||
}
|
||||
|
||||
if len(r.Name) < 3 || len(r.Name) > 100 {
|
||||
return errors.New("role name must be between 3 and 100 characters")
|
||||
}
|
||||
|
||||
if !isValidRoleName(r.Name) {
|
||||
return errors.New("role name can only contain letters, numbers, underscores, and hyphens")
|
||||
}
|
||||
|
||||
if len(r.Description) > 500 {
|
||||
return errors.New("role description must not exceed 500 characters")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ToRoleInfo converts Role to RoleInfo (public information)
|
||||
func (r *Role) ToRoleInfo() RoleInfo {
|
||||
roleInfo := RoleInfo{
|
||||
ID: r.ID,
|
||||
Name: r.Name,
|
||||
Description: r.Description,
|
||||
Active: r.Active,
|
||||
System: r.System,
|
||||
Permissions: make([]PermissionInfo, len(r.Permissions)),
|
||||
DateCreated: r.DateCreated.Format("2006-01-02T15:04:05Z"),
|
||||
}
|
||||
|
||||
// Convert permissions
|
||||
for i, permission := range r.Permissions {
|
||||
roleInfo.Permissions[i] = permission.ToPermissionInfo()
|
||||
}
|
||||
|
||||
return roleInfo
|
||||
}
|
||||
|
||||
// HasPermission checks if the role has a specific permission
|
||||
func (r *Role) HasPermission(permissionName string) bool {
|
||||
for _, permission := range r.Permissions {
|
||||
if permission.Name == permissionName {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// AddPermission adds a permission to the role
|
||||
func (r *Role) AddPermission(permission Permission) {
|
||||
if !r.HasPermission(permission.Name) {
|
||||
r.Permissions = append(r.Permissions, permission)
|
||||
}
|
||||
}
|
||||
|
||||
// RemovePermission removes a permission from the role
|
||||
func (r *Role) RemovePermission(permissionName string) {
|
||||
for i, permission := range r.Permissions {
|
||||
if permission.Name == permissionName {
|
||||
r.Permissions = append(r.Permissions[:i], r.Permissions[i+1:]...)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// GetPermissionNames returns a slice of permission names
|
||||
func (r *Role) GetPermissionNames() []string {
|
||||
names := make([]string, len(r.Permissions))
|
||||
for i, permission := range r.Permissions {
|
||||
names[i] = permission.Name
|
||||
}
|
||||
return names
|
||||
}
|
||||
|
||||
// isValidRoleName validates role name format
|
||||
func isValidRoleName(name string) bool {
|
||||
// Allow letters, numbers, underscores, and hyphens
|
||||
for _, char := range name {
|
||||
if !((char >= 'a' && char <= 'z') ||
|
||||
(char >= 'A' && char <= 'Z') ||
|
||||
(char >= '0' && char <= '9') ||
|
||||
char == '_' || char == '-') {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
Reference in New Issue
Block a user