From a1ef4004f849dd65916551e916313b286eaebb2c Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Tue, 18 May 2021 22:34:46 -0700 Subject: [PATCH] Implement generic CanDo against k8s roles --- pkg/accesscontrol/access_control.go | 21 +++++++++++++++++++++ pkg/schema/factory.go | 13 ++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/pkg/accesscontrol/access_control.go b/pkg/accesscontrol/access_control.go index cc1b34e..fb91a32 100644 --- a/pkg/accesscontrol/access_control.go +++ b/pkg/accesscontrol/access_control.go @@ -4,6 +4,8 @@ import ( "github.com/rancher/apiserver/pkg/server" "github.com/rancher/apiserver/pkg/types" "github.com/rancher/steve/pkg/attributes" + "github.com/rancher/wrangler/pkg/kv" + "k8s.io/apimachinery/pkg/runtime/schema" ) type AccessControl struct { @@ -14,6 +16,25 @@ func NewAccessControl() *AccessControl { return &AccessControl{} } +func (a *AccessControl) CanDo(apiOp *types.APIRequest, resource, verb, namespace, name string) error { + apiSchema := apiOp.Schemas.LookupSchema(resource) + if apiSchema != nil && attributes.GVK(apiSchema).Kind != "" { + access := GetAccessListMap(apiSchema) + if access[verb].Grants(namespace, name) { + return nil + } + } + group, resource := kv.Split(resource, "/") + accessSet := apiOp.Schemas.Attributes["accessSet"].(*AccessSet) + if accessSet.Grants(verb, schema.GroupResource{ + Group: group, + Resource: resource, + }, namespace, name) { + return nil + } + return a.SchemaBasedAccess.CanDo(apiOp, resource, verb, namespace, name) +} + func (a *AccessControl) CanWatch(apiOp *types.APIRequest, schema *types.APISchema) error { if attributes.GVK(schema).Kind != "" { access := GetAccessListMap(schema) diff --git a/pkg/schema/factory.go b/pkg/schema/factory.go index a7d51f4..3b9f150 100644 --- a/pkg/schema/factory.go +++ b/pkg/schema/factory.go @@ -125,9 +125,20 @@ func (c *Collection) schemasForSubject(access *accesscontrol.AccessSet) (*types. } } + result.Attributes = map[string]interface{}{ + "accessSet": access, + } return result, nil } +func (c *Collection) defaultStore() types.Store { + templates := c.templates[""] + if len(templates) > 0 { + return templates[0].Store + } + return nil +} + func (c *Collection) applyTemplates(schema *types.APISchema) { c.lock.RLock() defer c.lock.RUnlock() @@ -152,7 +163,7 @@ func (c *Collection) applyTemplates(schema *types.APISchema) { if t.StoreFactory == nil { schema.Store = t.Store } else { - schema.Store = t.StoreFactory(templates[2].Store) + schema.Store = t.StoreFactory(c.defaultStore()) } } if t.Customize != nil {