You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
OneAuth/api/role/policy.go

130 lines
3.2 KiB
Go

// Copyright (C) 2024 veypi <i@veypi.com>
// 2025-03-04 16:08:06
// Distributed under terms of the MIT license.
package role
import (
"strings"
"github.com/veypi/vbase/cfg"
"github.com/veypi/vbase/models"
"github.com/veypi/vigo"
)
// ListPoliciesRequest 获取角色策略请求
type ListPoliciesRequest struct {
RoleID string `src:"path@role_id" desc:"角色ID"`
}
// listPolicies 获取角色关联的策略列表
func listPolicies(x *vigo.X, req *ListPoliciesRequest) ([]models.Policy, error) {
var role models.Role
if err := cfg.DB().First(&role, "id = ?", req.RoleID).Error; err != nil {
return nil, vigo.ErrNotFound
}
if role.PolicyIDs == "" {
return []models.Policy{}, nil
}
// 解析策略ID列表
policyIDs := strings.Split(role.PolicyIDs, ",")
var policies []models.Policy
if err := cfg.DB().Where("id IN ?", policyIDs).Find(&policies).Error; err != nil {
return nil, vigo.ErrInternalServer.WithError(err)
}
return policies, nil
}
// AddPolicyRequest 添加策略请求
type AddPolicyRequest struct {
RoleID string `src:"path@role_id" desc:"角色ID"`
PolicyID string `json:"policy_id" src:"json" desc:"策略ID"`
}
// addPolicy 为角色添加策略
func addPolicy(x *vigo.X, req *AddPolicyRequest) (*models.Role, error) {
var role models.Role
if err := cfg.DB().First(&role, "id = ?", req.RoleID).Error; err != nil {
return nil, vigo.ErrNotFound
}
// 验证策略是否存在
var policy models.Policy
if err := cfg.DB().First(&policy, "id = ?", req.PolicyID).Error; err != nil {
return nil, vigo.ErrArgInvalid.WithString("policy not found")
}
// 解析现有策略ID
existingIDs := map[string]bool{}
if role.PolicyIDs != "" {
for _, id := range strings.Split(role.PolicyIDs, ",") {
existingIDs[id] = true
}
}
// 检查是否已存在
if existingIDs[req.PolicyID] {
return nil, vigo.ErrArgInvalid.WithString("policy already added to this role")
}
// 添加新策略ID
if role.PolicyIDs != "" {
role.PolicyIDs += ","
}
role.PolicyIDs += req.PolicyID
if err := cfg.DB().Model(&role).Update("policy_ids", role.PolicyIDs).Error; err != nil {
return nil, vigo.ErrInternalServer.WithError(err)
}
return &role, nil
}
// RemovePolicyRequest 移除策略请求
type RemovePolicyRequest struct {
RoleID string `src:"path@role_id" desc:"角色ID"`
PolicyID string `src:"path@policy_id" desc:"策略ID"`
}
// removePolicy 从角色移除策略
func removePolicy(x *vigo.X, req *RemovePolicyRequest) (*models.Role, error) {
var role models.Role
if err := cfg.DB().First(&role, "id = ?", req.RoleID).Error; err != nil {
return nil, vigo.ErrNotFound
}
// 解析现有策略ID
if role.PolicyIDs == "" {
return nil, vigo.ErrArgInvalid.WithString("role has no policies")
}
existingIDs := strings.Split(role.PolicyIDs, ",")
newIDs := []string{}
found := false
for _, id := range existingIDs {
if id == req.PolicyID {
found = true
continue
}
newIDs = append(newIDs, id)
}
if !found {
return nil, vigo.ErrArgInvalid.WithString("policy not found in this role")
}
// 更新策略ID列表
role.PolicyIDs = strings.Join(newIDs, ",")
if err := cfg.DB().Model(&role).Update("policy_ids", role.PolicyIDs).Error; err != nil {
return nil, vigo.ErrInternalServer.WithError(err)
}
return &role, nil
}