init bootstrap
This commit is contained in:
276
local/model/permission.go
Normal file
276
local/model/permission.go
Normal file
@@ -0,0 +1,276 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// Permission represents a permission in the system
|
||||
type Permission struct {
|
||||
BaseModel
|
||||
Name string `json:"name" gorm:"unique;not null;type:varchar(100)"`
|
||||
Description string `json:"description" gorm:"type:text"`
|
||||
Category string `json:"category" gorm:"type:varchar(50)"`
|
||||
Active bool `json:"active" gorm:"default:true"`
|
||||
System bool `json:"system" gorm:"default:false"` // System permissions cannot be deleted
|
||||
Roles []Role `json:"-" gorm:"many2many:role_permissions;"`
|
||||
}
|
||||
|
||||
// PermissionCreateRequest represents the request to create a new permission
|
||||
type PermissionCreateRequest struct {
|
||||
Name string `json:"name" validate:"required,min=3,max=100"`
|
||||
Description string `json:"description" validate:"max=500"`
|
||||
Category string `json:"category" validate:"required,max=50"`
|
||||
}
|
||||
|
||||
// PermissionUpdateRequest represents the request to update a permission
|
||||
type PermissionUpdateRequest struct {
|
||||
Name *string `json:"name,omitempty" validate:"omitempty,min=3,max=100"`
|
||||
Description *string `json:"description,omitempty" validate:"omitempty,max=500"`
|
||||
Category *string `json:"category,omitempty" validate:"omitempty,max=50"`
|
||||
Active *bool `json:"active,omitempty"`
|
||||
}
|
||||
|
||||
// PermissionInfo represents public permission information
|
||||
type PermissionInfo struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Category string `json:"category"`
|
||||
Active bool `json:"active"`
|
||||
System bool `json:"system"`
|
||||
RoleCount int64 `json:"roleCount"`
|
||||
DateCreated string `json:"dateCreated"`
|
||||
}
|
||||
|
||||
// BeforeCreate is called before creating a permission
|
||||
func (p *Permission) BeforeCreate(tx *gorm.DB) error {
|
||||
p.BaseModel.BeforeCreate()
|
||||
|
||||
// Normalize fields
|
||||
p.Name = strings.ToLower(strings.TrimSpace(p.Name))
|
||||
p.Description = strings.TrimSpace(p.Description)
|
||||
p.Category = strings.ToLower(strings.TrimSpace(p.Category))
|
||||
|
||||
return p.Validate()
|
||||
}
|
||||
|
||||
// BeforeUpdate is called before updating a permission
|
||||
func (p *Permission) BeforeUpdate(tx *gorm.DB) error {
|
||||
p.BaseModel.BeforeUpdate()
|
||||
|
||||
// Normalize fields if they're being updated
|
||||
if p.Name != "" {
|
||||
p.Name = strings.ToLower(strings.TrimSpace(p.Name))
|
||||
}
|
||||
if p.Description != "" {
|
||||
p.Description = strings.TrimSpace(p.Description)
|
||||
}
|
||||
if p.Category != "" {
|
||||
p.Category = strings.ToLower(strings.TrimSpace(p.Category))
|
||||
}
|
||||
|
||||
return p.Validate()
|
||||
}
|
||||
|
||||
// BeforeDelete is called before deleting a permission
|
||||
func (p *Permission) BeforeDelete(tx *gorm.DB) error {
|
||||
if p.System {
|
||||
return errors.New("system permissions cannot be deleted")
|
||||
}
|
||||
|
||||
// Check if permission is assigned to any roles
|
||||
var roleCount int64
|
||||
if err := tx.Model(&Role{}).Where("permissions.id = ?", p.ID).Joins("JOIN role_permissions ON roles.id = role_permissions.role_id").Count(&roleCount).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if roleCount > 0 {
|
||||
return errors.New("cannot delete permission that is assigned to roles")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Validate validates permission data
|
||||
func (p *Permission) Validate() error {
|
||||
if p.Name == "" {
|
||||
return errors.New("permission name is required")
|
||||
}
|
||||
|
||||
if len(p.Name) < 3 || len(p.Name) > 100 {
|
||||
return errors.New("permission name must be between 3 and 100 characters")
|
||||
}
|
||||
|
||||
if !isValidPermissionName(p.Name) {
|
||||
return errors.New("permission name must follow the format 'resource:action' (e.g., 'user:create')")
|
||||
}
|
||||
|
||||
if p.Category == "" {
|
||||
return errors.New("permission category is required")
|
||||
}
|
||||
|
||||
if len(p.Category) > 50 {
|
||||
return errors.New("permission category must not exceed 50 characters")
|
||||
}
|
||||
|
||||
if len(p.Description) > 500 {
|
||||
return errors.New("permission description must not exceed 500 characters")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ToPermissionInfo converts Permission to PermissionInfo (public information)
|
||||
func (p *Permission) ToPermissionInfo() PermissionInfo {
|
||||
return PermissionInfo{
|
||||
ID: p.ID,
|
||||
Name: p.Name,
|
||||
Description: p.Description,
|
||||
Category: p.Category,
|
||||
Active: p.Active,
|
||||
System: p.System,
|
||||
DateCreated: p.DateCreated.Format("2006-01-02T15:04:05Z"),
|
||||
}
|
||||
}
|
||||
|
||||
// GetResource extracts the resource part from a permission name (e.g., "user:create" -> "user")
|
||||
func (p *Permission) GetResource() string {
|
||||
parts := strings.Split(p.Name, ":")
|
||||
if len(parts) > 0 {
|
||||
return parts[0]
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// GetAction extracts the action part from a permission name (e.g., "user:create" -> "create")
|
||||
func (p *Permission) GetAction() string {
|
||||
parts := strings.Split(p.Name, ":")
|
||||
if len(parts) > 1 {
|
||||
return parts[1]
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// isValidPermissionName validates permission name format
|
||||
func isValidPermissionName(name string) bool {
|
||||
// Permission names should follow the format "resource:action"
|
||||
parts := strings.Split(name, ":")
|
||||
if len(parts) != 2 {
|
||||
return false
|
||||
}
|
||||
|
||||
resource := parts[0]
|
||||
action := parts[1]
|
||||
|
||||
// Validate resource part
|
||||
if len(resource) < 2 || len(resource) > 50 {
|
||||
return false
|
||||
}
|
||||
|
||||
// Validate action part
|
||||
if len(action) < 2 || len(action) > 50 {
|
||||
return false
|
||||
}
|
||||
|
||||
// Check if both parts contain only valid characters
|
||||
return isValidIdentifier(resource) && isValidIdentifier(action)
|
||||
}
|
||||
|
||||
// isValidIdentifier checks if a string is a valid identifier (letters, numbers, underscores)
|
||||
func isValidIdentifier(str string) bool {
|
||||
for _, char := range str {
|
||||
if !((char >= 'a' && char <= 'z') ||
|
||||
(char >= 'A' && char <= 'Z') ||
|
||||
(char >= '0' && char <= '9') ||
|
||||
char == '_') {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Common permission categories
|
||||
const (
|
||||
PermissionCategoryUser = "user"
|
||||
PermissionCategoryRole = "role"
|
||||
PermissionCategorySystem = "system"
|
||||
PermissionCategoryContent = "content"
|
||||
PermissionCategoryReport = "report"
|
||||
)
|
||||
|
||||
// Common permission patterns
|
||||
const (
|
||||
PermissionCreate = "create"
|
||||
PermissionRead = "read"
|
||||
PermissionUpdate = "update"
|
||||
PermissionDelete = "delete"
|
||||
PermissionManage = "manage"
|
||||
PermissionAdmin = "admin"
|
||||
)
|
||||
|
||||
// GetStandardPermissions returns a list of standard permissions for a resource
|
||||
func GetStandardPermissions(resource string) []Permission {
|
||||
return []Permission{
|
||||
{
|
||||
Name: resource + ":" + PermissionCreate,
|
||||
Description: "Create new " + resource + " records",
|
||||
Category: resource,
|
||||
Active: true,
|
||||
},
|
||||
{
|
||||
Name: resource + ":" + PermissionRead,
|
||||
Description: "Read " + resource + " records",
|
||||
Category: resource,
|
||||
Active: true,
|
||||
},
|
||||
{
|
||||
Name: resource + ":" + PermissionUpdate,
|
||||
Description: "Update " + resource + " records",
|
||||
Category: resource,
|
||||
Active: true,
|
||||
},
|
||||
{
|
||||
Name: resource + ":" + PermissionDelete,
|
||||
Description: "Delete " + resource + " records",
|
||||
Category: resource,
|
||||
Active: true,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Common system permissions
|
||||
const (
|
||||
ServerView = "server:view"
|
||||
ServerUpdate = "server:update"
|
||||
ServerStart = "server:start"
|
||||
ServerStop = "server:stop"
|
||||
ConfigView = "config:view"
|
||||
ConfigUpdate = "config:update"
|
||||
)
|
||||
|
||||
// AllPermissions returns all available permissions in the system
|
||||
var AllPermissions = []string{
|
||||
"user:create",
|
||||
"user:read",
|
||||
"user:update",
|
||||
"user:delete",
|
||||
"role:create",
|
||||
"role:read",
|
||||
"role:update",
|
||||
"role:delete",
|
||||
"permission:create",
|
||||
"permission:read",
|
||||
"permission:update",
|
||||
"permission:delete",
|
||||
ServerView,
|
||||
ServerUpdate,
|
||||
ServerStart,
|
||||
ServerStop,
|
||||
ConfigView,
|
||||
ConfigUpdate,
|
||||
"audit:read",
|
||||
"system:admin",
|
||||
}
|
||||
Reference in New Issue
Block a user