diff --git a/api/server/router/auth/auth.go b/api/server/router/auth/auth.go index f87ce4b7..ef7183c1 100644 --- a/api/server/router/auth/auth.go +++ b/api/server/router/auth/auth.go @@ -52,5 +52,6 @@ func (a *authRouter) initRoutes(ge *gin.Engine) { bindingRoute := authRoute.Group(BindingSubPath) bindingRoute.POST("", a.createBinding) bindingRoute.DELETE("", a.deleteBinding) + bindingRoute.GET("", a.listBindings) } } diff --git a/api/server/router/auth/auth_routes.go b/api/server/router/auth/auth_routes.go index fd67f426..49eb07eb 100644 --- a/api/server/router/auth/auth_routes.go +++ b/api/server/router/auth/auth_routes.go @@ -75,6 +75,24 @@ func (a *authRouter) deletePolicy(c *gin.Context) { httputils.SetSuccess(c, r) } +func (a *authRouter) listBindings(c *gin.Context) { + r := httputils.NewResponse() + var ( + req types.ListGroupBindingRequest + err error + ) + if err = c.ShouldBindQuery(&req); err != nil { + httputils.SetFailed(c, r, err) + return + } + if r.Result, err = a.c.Auth().ListGroupBindings(c, &req); err != nil { + httputils.SetFailed(c, r, err) + return + } + + httputils.SetSuccess(c, r) +} + func (a *authRouter) createBinding(c *gin.Context) { r := httputils.NewResponse() var req types.GroupBindingRequest diff --git a/pkg/controller/auth/auth.go b/pkg/controller/auth/auth.go index 80665d88..0309a393 100644 --- a/pkg/controller/auth/auth.go +++ b/pkg/controller/auth/auth.go @@ -43,6 +43,7 @@ type ( CreateGroupBinding(ctx context.Context, req *types.GroupBindingRequest) error DeleteGroupBinding(ctx context.Context, req *types.GroupBindingRequest) error + ListGroupBindings(ctx context.Context, req *types.ListGroupBindingRequest) ([]types.RBACPolicy, error) } ) @@ -107,7 +108,7 @@ func (a *auth) CreateRBACPolicy(ctx context.Context, req *types.RBACPolicyReques ok, err := a.enforcer.AddPolicy(policy.Raw()) if err != nil { - klog.Errorf("failed to create policy %v: %v", policy, err) + klog.Errorf("failed to create policy %v: %v", policy.Raw(), err) return errors.ErrServerInternal } if !ok { @@ -141,7 +142,7 @@ func (a *auth) DeleteRBACPolicy(ctx context.Context, req *types.RBACPolicyReques ok, err := a.enforcer.RemovePolicy(policy.Raw()) if err != nil { - klog.Errorf("failed to delete policy %v: %v", policy, err) + klog.Errorf("failed to delete policy %v: %v", policy.Raw(), err) return errors.ErrServerInternal } if !ok { @@ -193,7 +194,7 @@ func (a *auth) CreateGroupBinding(ctx context.Context, req *types.GroupBindingRe ok, err := a.enforcer.AddGroupingPolicy(binding.Raw()) if err != nil { - klog.Errorf("failed to create binding %v", binding, err) + klog.Errorf("failed to create group binding %v: %v", binding.Raw(), err) return errors.ErrServerInternal } if !ok { @@ -211,7 +212,7 @@ func (a *auth) DeleteGroupBinding(ctx context.Context, req *types.GroupBindingRe ok, err := a.enforcer.RemoveGroupingPolicy(binding.Raw()) if err != nil { - klog.Errorf("failed to delete binding %v: %v", binding, err) + klog.Errorf("failed to delete group binding %v: %v", binding.Raw(), err) return errors.ErrServerInternal } if !ok { @@ -221,6 +222,46 @@ func (a *auth) DeleteGroupBinding(ctx context.Context, req *types.GroupBindingRe return nil } +func (a *auth) ListGroupBindings(ctx context.Context, req *types.ListGroupBindingRequest) ([]types.RBACPolicy, error) { + conds := make([]ctrlutil.BindingQueryCondition, 0) + if req.UserId != nil { + user, err := a.factory.User().Get(ctx, *req.UserId) + if err != nil { + klog.Errorf("failed to get user(%d): %v", *req.UserId, err) + return nil, errors.ErrServerInternal + } + if user == nil { + return nil, errors.NewError(fmt.Errorf("user(%d) is not found", *req.UserId), http.StatusBadRequest) + } + + conds = append(conds, ctrlutil.QueryWithUserName(user.Name)) + } + if req.GroupName != nil { + policy, err := ctrlutil.GetGroupPolicy(a.enforcer, *req.GroupName) + if err != nil { + klog.Errorf("failed to get group(%s): %v", *req.GroupName, err) + return nil, errors.ErrServerInternal + } + if policy == nil { + return nil, errors.NewError(fmt.Errorf("group(%s) is not found", *req.GroupName), http.StatusBadRequest) + } + + conds = append(conds, ctrlutil.QueryWithGroupName(*req.GroupName)) + } + + bindings, err := ctrlutil.GetGroupBindings(a.enforcer, conds...) + if err != nil { + klog.Errorf("failed to get group bindings: %v", *req.GroupName, err) + return nil, errors.ErrServerInternal + } + + bindingPolicies := make([]types.RBACPolicy, len(bindings)) + for i, binding := range bindings { + bindingPolicies[i] = *model2Type(binding) + } + return bindingPolicies, nil +} + func model2Type(policy model.Policy) *types.RBACPolicy { switch p := policy.(type) { case model.UserPolicy: @@ -237,9 +278,11 @@ func model2Type(policy model.Policy) *types.RBACPolicy { StringID: p.GetSID(), Operation: p.GetOperation(), } - case model.Policy: - // TODO: - return &types.RBACPolicy{} + case model.GroupBinding: + return &types.RBACPolicy{ + UserName: p.GetUserName(), + GroupName: p.GetGroupName(), + } } return nil diff --git a/pkg/controller/util/util.go b/pkg/controller/util/util.go index 187749fd..ea380da1 100644 --- a/pkg/controller/util/util.go +++ b/pkg/controller/util/util.go @@ -25,6 +25,7 @@ import ( "github.com/caoyingjunz/pixiu/api/server/httputils" "github.com/caoyingjunz/pixiu/pkg/db" "github.com/caoyingjunz/pixiu/pkg/db/model" + "github.com/caoyingjunz/pixiu/pkg/util" ) func MakeDbOptions(ctx context.Context) (opts []db.Options) { @@ -61,23 +62,33 @@ func SetIdRangeContext(c *gin.Context, enforcer *casbin.SyncedEnforcer, user *mo return nil } -type BindingQueryCondition func() (int, string) +type BindingQueryCondition func(c *policyConditions) (index int) func QueryWithGroupName(name string) BindingQueryCondition { - return func() (int, string) { - return 1, name + return func(c *policyConditions) int { + c.conds[1] = &name + return 1 } } func QueryWithUserName(name string) BindingQueryCondition { - return func() (int, string) { - return 0, name + return func(c *policyConditions) int { + c.conds[0] = &name + return 0 } } -func GetGroupBindings(enforcer *casbin.SyncedEnforcer, cond BindingQueryCondition) ([]model.GroupBinding, error) { - index, name := cond() - rp, err := enforcer.GetFilteredNamedGroupingPolicy("g", index, name) +func GetGroupBindings(enforcer *casbin.SyncedEnforcer, conds ...BindingQueryCondition) ([]model.GroupBinding, error) { + var index int + pc := &policyConditions{ + conds: [4]*string{}, + } + for _, cond := range conds { + i := cond(pc) + index = util.Less(i, index) + } + + rp, err := enforcer.GetFilteredNamedGroupingPolicy("g", index, pc.get()...) if err != nil { return nil, err } diff --git a/pkg/types/request.go b/pkg/types/request.go index 418c04f4..4dd8277f 100644 --- a/pkg/types/request.go +++ b/pkg/types/request.go @@ -158,6 +158,11 @@ type ( GroupName string `json:"group_name" binding:"required"` } + ListGroupBindingRequest struct { + UserId *int64 `form:"user_id" binding:"omitempty"` + GroupName *string `form:"group_name" binding:"omitempty"` + } + // PageRequest 分页配置 PageRequest struct { Page int `form:"page" json:"page"` // 页数,表示第几页 diff --git a/pkg/util/util.go b/pkg/util/util.go index ca364bbf..b1770ecb 100644 --- a/pkg/util/util.go +++ b/pkg/util/util.go @@ -150,3 +150,19 @@ func DeduplicateIntSlice(s []int64) (ret []int64) { return } + +// More returns the larger one. +func More(a, b int) int { + if a > b { + return a + } + return b +} + +// Less returns the smaller one. +func Less(a, b int) int { + if a < b { + return a + } + return b +}