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