From 8d18fc3657cd45e329224bcadad96282bd805411 Mon Sep 17 00:00:00 2001 From: hongming Date: Sun, 12 Apr 2020 18:56:33 +0800 Subject: [PATCH] update Signed-off-by: hongming --- .../authorization/authorizerfactory/opa.go | 55 +++++++++++-------- pkg/kapis/iam/v1alpha2/register.go | 10 ++-- pkg/kapis/resources/v1alpha2/register.go | 2 +- pkg/kapis/resources/v1alpha3/register.go | 4 +- pkg/kapis/tenant/v1alpha2/register.go | 7 --- 5 files changed, 41 insertions(+), 37 deletions(-) diff --git a/pkg/apiserver/authorization/authorizerfactory/opa.go b/pkg/apiserver/authorization/authorizerfactory/opa.go index b6ea752ba..6897f6555 100644 --- a/pkg/apiserver/authorization/authorizerfactory/opa.go +++ b/pkg/apiserver/authorization/authorizerfactory/opa.go @@ -32,10 +32,17 @@ type opaAuthorizer struct { am am.AccessManagementInterface } +const ( + permissionUndefined = "permission undefined" + defaultRegoQuery = "data.authz.allow" +) + // Make decision by request attributes func (o *opaAuthorizer) Authorize(attr authorizer.Attributes) (authorized authorizer.Decision, reason string, err error) { // Make decisions based on the authorization policy of different levels of roles + // Error returned when an internal error occurs + // Reason must be returned when access is denied globalRole, err := o.am.GetRoleOfUserInTargetScope(iamv1alpha2.GlobalScope, "", attr.GetUser().GetName()) if err != nil { if errors.IsNotFound(err) { @@ -46,12 +53,12 @@ func (o *opaAuthorizer) Authorize(attr authorizer.Attributes) (authorized author // check platform role policy rules if authorized, reason, err = o.makeDecision(globalRole, attr); authorized == authorizer.DecisionAllow { - return authorized, reason, err + return authorized, reason, nil } // it's not in cluster resource, permission denied if attr.GetCluster() == "" { - return authorizer.DecisionDeny, "permission undefined", nil + return authorizer.DecisionDeny, permissionUndefined, nil } clusterRole, err := o.am.GetRoleOfUserInTargetScope(iamv1alpha2.ClusterScope, attr.GetCluster(), attr.GetUser().GetName()) @@ -63,13 +70,15 @@ func (o *opaAuthorizer) Authorize(attr authorizer.Attributes) (authorized author } // check cluster role policy rules - if a, r, e := o.makeDecision(clusterRole, attr); a == authorizer.DecisionAllow { - return a, r, e + if authorized, reason, err := o.makeDecision(clusterRole, attr); authorized == authorizer.DecisionAllow { + return authorized, reason, nil + } else if err != nil { + return authorizer.DecisionDeny, "", err } // it's not in cluster resource, permission denied if attr.GetWorkspace() == "" && attr.GetNamespace() == "" { - return authorizer.DecisionDeny, "permission undefined", nil + return authorizer.DecisionDeny, permissionUndefined, nil } workspaceRole, err := o.am.GetRoleOfUserInTargetScope(iamv1alpha2.WorkspaceScope, attr.GetWorkspace(), attr.GetUser().GetName()) @@ -81,30 +90,32 @@ func (o *opaAuthorizer) Authorize(attr authorizer.Attributes) (authorized author } // check workspace role policy rules - if a, r, e := o.makeDecision(workspaceRole, attr); a == authorizer.DecisionAllow { - return a, r, e + if authorized, reason, err := o.makeDecision(workspaceRole, attr); authorized == authorizer.DecisionAllow { + return authorized, reason, err + } else if err != nil { + return authorizer.DecisionDeny, "", err } // it's not in workspace resource, permission denied if attr.GetNamespace() == "" { - return authorizer.DecisionDeny, "permission undefined", nil + return authorizer.DecisionDeny, permissionUndefined, nil } - if attr.GetNamespace() != "" { - namespaceRole, err := o.am.GetRoleOfUserInTargetScope(iamv1alpha2.NamespaceScope, attr.GetNamespace(), attr.GetUser().GetName()) - if err != nil { - if errors.IsNotFound(err) { - return authorizer.DecisionDeny, err.Error(), nil - } - return authorizer.DecisionDeny, "", err - } - // check namespace role policy rules - if a, r, e := o.makeDecision(namespaceRole, attr); a == authorizer.DecisionAllow { - return a, r, e + namespaceRole, err := o.am.GetRoleOfUserInTargetScope(iamv1alpha2.NamespaceScope, attr.GetNamespace(), attr.GetUser().GetName()) + if err != nil { + if errors.IsNotFound(err) { + return authorizer.DecisionDeny, err.Error(), nil } + return authorizer.DecisionDeny, "", err + } + // check namespace role policy rules + if authorized, reason, err := o.makeDecision(namespaceRole, attr); authorized == authorizer.DecisionAllow { + return authorized, reason, err + } else if err != nil { + return authorizer.DecisionDeny, "", err } - return authorizer.DecisionDeny, "", nil + return authorizer.DecisionDeny, permissionUndefined, nil } // Make decision base on role @@ -120,7 +131,7 @@ func (o *opaAuthorizer) makeDecision(role *iamv1alpha2.Role, a authorizer.Attrib } // Call the rego.New function to create an object that can be prepared or evaluated // After constructing a new rego.Rego object you can call PrepareForEval() to obtain an executable query - query, err := rego.New(rego.Query("data.authz.allow"), rego.Module("authz.rego", rule.Rego)).PrepareForEval(context.Background()) + query, err := rego.New(rego.Query(defaultRegoQuery), rego.Module("authz.rego", rule.Rego)).PrepareForEval(context.Background()) if err != nil { klog.Errorf("rule syntax error:%s", err) @@ -140,7 +151,7 @@ func (o *opaAuthorizer) makeDecision(role *iamv1alpha2.Role, a authorizer.Attrib } } - return authorizer.DecisionDeny, "permission undefined", nil + return authorizer.DecisionDeny, permissionUndefined, nil } func NewOPAAuthorizer(am am.AccessManagementInterface) *opaAuthorizer { diff --git a/pkg/kapis/iam/v1alpha2/register.go b/pkg/kapis/iam/v1alpha2/register.go index 4a4fb3cfc..9a9ce7b09 100644 --- a/pkg/kapis/iam/v1alpha2/register.go +++ b/pkg/kapis/iam/v1alpha2/register.go @@ -22,7 +22,7 @@ import ( "github.com/emicklei/go-restful-openapi" "k8s.io/apimachinery/pkg/runtime/schema" "kubesphere.io/kubesphere/pkg/api" - iamvealpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2" + iamv1alpha2 "kubesphere.io/kubesphere/pkg/apis/iam/v1alpha2" authoptions "kubesphere.io/kubesphere/pkg/apiserver/authentication/options" "kubesphere.io/kubesphere/pkg/apiserver/runtime" "kubesphere.io/kubesphere/pkg/constants" @@ -46,28 +46,28 @@ func AddToContainer(container *restful.Container, im im.IdentityManagementInterf To(handler.DescribeUser). Doc("Retrieve user details."). Param(ws.PathParameter("user", "username")). - Returns(http.StatusOK, api.StatusOK, iamvealpha2.UserDetail{}). + Returns(http.StatusOK, api.StatusOK, iamv1alpha2.UserDetail{}). Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) ws.Route(ws.GET("/users/{user}/workspaceroles"). To(handler.ListRolesOfUser). Doc("Retrieve user roles in workspaces."). Param(ws.PathParameter("user", "username")). - Returns(http.StatusOK, api.StatusOK, iamvealpha2.RoleList{}). + Returns(http.StatusOK, api.StatusOK, iamv1alpha2.RoleList{}). Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) ws.Route(ws.GET("/users/{user}/clusterroles"). To(handler.ListRolesOfUser). Doc("Retrieve user roles in clusters."). Param(ws.PathParameter("user", "username")). - Returns(http.StatusOK, api.StatusOK, iamvealpha2.RoleList{}). + Returns(http.StatusOK, api.StatusOK, iamv1alpha2.RoleList{}). Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) ws.Route(ws.GET("/users/{user}/namespaceroles"). To(handler.ListRolesOfUser). Doc("Retrieve user roles in namespaces."). Param(ws.PathParameter("user", "username")). - Returns(http.StatusOK, api.StatusOK, iamvealpha2.RoleList{}). + Returns(http.StatusOK, api.StatusOK, iamv1alpha2.RoleList{}). Metadata(restfulspec.KeyOpenAPITags, []string{constants.AccessManagementTag})) ws.Route(ws.GET("/namespaces/{namespace}/roles"). diff --git a/pkg/kapis/resources/v1alpha2/register.go b/pkg/kapis/resources/v1alpha2/register.go index a3e22a835..557e46cea 100644 --- a/pkg/kapis/resources/v1alpha2/register.go +++ b/pkg/kapis/resources/v1alpha2/register.go @@ -70,7 +70,7 @@ func AddToContainer(c *restful.Container, client kubernetes.Interface, factory i Deprecate(). Returns(http.StatusOK, api.StatusOK, models.PageableResponse{}). Metadata(restfulspec.KeyOpenAPITags, []string{constants.ClusterResourcesTag}). - Doc("Cluster level resource query"). + Doc("Cluster level resources"). Param(webservice.PathParameter("resources", "cluster level resource type, e.g. nodes,workspaces,storageclasses,clusterroles.")). Param(webservice.QueryParameter(params.ConditionsParam, "query conditions, connect multiple conditions with commas, equal symbol for exact query, wave symbol for fuzzy query e.g. name~a"). Required(false). diff --git a/pkg/kapis/resources/v1alpha3/register.go b/pkg/kapis/resources/v1alpha3/register.go index f78945064..7d462bdfa 100644 --- a/pkg/kapis/resources/v1alpha3/register.go +++ b/pkg/kapis/resources/v1alpha3/register.go @@ -48,8 +48,8 @@ func AddToContainer(c *restful.Container, informerFactory informers.InformerFact webservice.Route(webservice.GET("/{resources}"). To(handler.handleListResources). Metadata(restfulspec.KeyOpenAPITags, []string{tagNamespacedResource}). - Doc("Cluster level resource query"). - Param(webservice.PathParameter("resources", "namespace level resource type, e.g. pods,jobs,configmaps,services.")). + Doc("Cluster level resources"). + Param(webservice.PathParameter("resources", "cluster level resource type, e.g. pods,jobs,configmaps,services.")). Param(webservice.QueryParameter(query.ParameterName, "name used to do filtering").Required(false)). Param(webservice.QueryParameter(query.ParameterPage, "page").Required(false).DataFormat("page=%d").DefaultValue("page=1")). Param(webservice.QueryParameter(query.ParameterLimit, "limit").Required(false)). diff --git a/pkg/kapis/tenant/v1alpha2/register.go b/pkg/kapis/tenant/v1alpha2/register.go index 0124aca07..6b5e84518 100644 --- a/pkg/kapis/tenant/v1alpha2/register.go +++ b/pkg/kapis/tenant/v1alpha2/register.go @@ -52,13 +52,6 @@ func AddToContainer(c *restful.Container, k8sClient k8s.Client, factory informer Doc("List the namespaces of the specified workspace for the current user"). Returns(http.StatusOK, api.StatusOK, []v1.Namespace{}). Metadata(restfulspec.KeyOpenAPITags, []string{constants.TenantResourcesTag})) - ws.Route(ws.GET("/workspaces/{workspace}/clusters"). - To(handler.ListNamespaces). - Param(ws.PathParameter("workspace", "workspace name")). - Param(ws.PathParameter("member", "workspace member's username")). - Doc("List the namespaces for the workspace member"). - Returns(http.StatusOK, api.StatusOK, []v1.Namespace{}). - Metadata(restfulspec.KeyOpenAPITags, []string{constants.TenantResourcesTag})) c.Add(ws) return nil