// Copyright (C) 2024 veypi // 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 }