refactor(role): support incremental permission add and remove

- Add PermissionInput struct with scope, permission_id, and level fields
    - Support adding permissions individually with custom scope and level
    - Support removing permissions by ID via dedicated remove field
    - Keep legacy replace mode for backward compatibility
    - Default level to 7 (admin) and scope to "vb" when not specified
master
veypi 3 weeks ago
parent c21c766b6a
commit ac7a8d2108

@ -21,8 +21,15 @@ func getPermissions(x *vigo.X, req *GetPermissionsReq) ([]models.Permission, err
type UpdatePermissionsReq struct { type UpdatePermissionsReq struct {
RoleID string `src:"path@id" desc:"Role ID"` RoleID string `src:"path@id" desc:"Role ID"`
Scope string `json:"scope" src:"query" default:"vb" desc:"Permission Scope"` Permissions []PermissionInput `json:"permissions" src:"json" desc:"Permissions to add"`
PermissionIDs []string `json:"permission_ids" src:"json" desc:"List of Permission IDs"` Remove []string `json:"remove" src:"json" desc:"Permission IDs to remove"`
Replace []string `json:"permission_ids" src:"json" desc:"Full replace (legacy)"`
}
type PermissionInput struct {
Scope string `json:"scope"`
PermissionID string `json:"permission_id"`
Level int `json:"level"`
} }
func updatePermissions(x *vigo.X, req *UpdatePermissionsReq) error { func updatePermissions(x *vigo.X, req *UpdatePermissionsReq) error {
@ -31,31 +38,50 @@ func updatePermissions(x *vigo.X, req *UpdatePermissionsReq) error {
return vigo.ErrNotFound return vigo.ErrNotFound
} }
return cfg.DB().Transaction(func(tx *gorm.DB) error {
// Full replace (legacy mode)
if len(req.Replace) > 0 {
if role.IsSystem { if role.IsSystem {
return vigo.NewError("cannot modify permissions of system role").WithCode(40300) return vigo.NewError("cannot modify permissions of system role").WithCode(40300)
} }
if err := tx.Where("role_id = ?", req.RoleID).Delete(&models.Permission{}).Error; err != nil {
return err
}
for _, pid := range req.Replace {
if err := tx.Create(&models.Permission{
Scope: "vb", RoleID: &req.RoleID, PermissionID: pid, Level: 7,
}).Error; err != nil {
return err
}
}
return nil
}
return cfg.DB().Transaction(func(tx *gorm.DB) error { // Remove specific permissions
// Delete existing permissions for this role AND scope if len(req.Remove) > 0 {
if err := tx.Where("role_id = ? AND scope = ?", req.RoleID, req.Scope).Delete(&models.Permission{}).Error; err != nil { if err := tx.Where("role_id = ? AND id IN ?", req.RoleID, req.Remove).
Delete(&models.Permission{}).Error; err != nil {
return err return err
} }
}
// Add new permissions // Add new permissions
if len(req.PermissionIDs) > 0 { if len(req.Permissions) > 0 {
permissions := make([]models.Permission, 0, len(req.PermissionIDs)) for _, p := range req.Permissions {
for _, pid := range req.PermissionIDs { if p.Level == 0 {
permissions = append(permissions, models.Permission{ p.Level = 7
Scope: req.Scope, }
RoleID: &req.RoleID, if p.Scope == "" {
PermissionID: pid, p.Scope = "vb"
Level: 7, // Default to Admin level to ensure it passes checks
})
} }
if err := tx.Create(&permissions).Error; err != nil { if err := tx.Create(&models.Permission{
Scope: p.Scope, RoleID: &req.RoleID, PermissionID: p.PermissionID, Level: p.Level,
}).Error; err != nil {
return err return err
} }
} }
}
return nil return nil
}) })
} }

Loading…
Cancel
Save