-
Notifications
You must be signed in to change notification settings - Fork 205
Consider supporting groups instead of single users only and create their tests #351
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: sig-auth-acceptance
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,6 +21,7 @@ import ( | |
"fmt" | ||
|
||
"k8s.io/apiserver/pkg/authorization/authorizer" | ||
"k8s.io/utils/set" | ||
) | ||
|
||
// StaticAuthorizationConfig describes what is needed to specify a static | ||
|
@@ -38,8 +39,9 @@ type StaticAuthorizationConfig struct { | |
} | ||
|
||
type UserConfig struct { | ||
Name string `json:"name,omitempty"` | ||
Groups []string `json:"groups,omitempty"` | ||
Name string `json:"name,omitempty"` | ||
Groups []string `json:"groups,omitempty"` | ||
GroupSet set.Set[string] | ||
} | ||
|
||
type staticAuthorizer struct { | ||
|
@@ -48,8 +50,12 @@ type staticAuthorizer struct { | |
|
||
// NewStaticAuthorizer creates an authorizer for static SubjectAccessReviews | ||
func NewStaticAuthorizer(config []StaticAuthorizationConfig) (*staticAuthorizer, error) { | ||
for _, c := range config { | ||
if c.ResourceRequest != (c.Path == "") { | ||
for c := range config { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since we need some internal representation of the config anyway, it might be easier to implement this part as a That way The constructor might then look something like this: func NewStaticAuthorizer(config []StaticAuthorizationConfig) (authorizer.Authorizer, error) {
var authorizers []staticAuthorizer
for _, c := range config {
authz, err := newStaticAuthorizers(&c)
// handle error
authorizers = append(authorizers, authz)
}
return unionauthorizer.New(authorizers...)
} WDYT? cc @ibihim There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. lol. Yes, I agree. This is what I tried to convey. We need an internal and an external representation. The internal one has a Set, the other has a slice of groups potentially. WRT the I have no strong opinions. We could leave it as is, but why invent our own logic, if we try to satisfy the authorizer interface, right? |
||
if config[c].User.Groups != nil { | ||
config[c].User.GroupSet = set.New(config[c].User.Groups...) | ||
} | ||
|
||
if config[c].ResourceRequest != (config[c].Path == "") { | ||
return nil, fmt.Errorf("invalid configuration: resource requests must not include a path: %v", config) | ||
} | ||
} | ||
|
@@ -60,17 +66,30 @@ func (saConfig StaticAuthorizationConfig) Matches(a authorizer.Attributes) bool | |
isAllowed := func(staticConf string, requestVal string) bool { | ||
if staticConf == "" { | ||
return true | ||
} else { | ||
return staticConf == requestVal | ||
} | ||
return staticConf == requestVal | ||
} | ||
isGroupAllowed := func(requestGroups []string) bool { | ||
if len(saConfig.User.GroupSet) == 0 { | ||
return true | ||
} | ||
for _, group := range requestGroups { | ||
if _, exists := saConfig.User.GroupSet[group]; exists { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. use the |
||
return true | ||
} | ||
} | ||
return false | ||
} | ||
|
||
userName := "" | ||
userGroups := []string{} | ||
if a.GetUser() != nil { | ||
userName = a.GetUser().GetName() | ||
userGroups = a.GetUser().GetGroups() | ||
} | ||
|
||
if isAllowed(saConfig.User.Name, userName) && | ||
if (saConfig.User.Name == "" || isAllowed(saConfig.User.Name, userName)) && | ||
ShazaAldawamneh marked this conversation as resolved.
Show resolved
Hide resolved
|
||
isGroupAllowed(userGroups) && | ||
isAllowed(saConfig.Verb, a.GetVerb()) && | ||
isAllowed(saConfig.Namespace, a.GetNamespace()) && | ||
isAllowed(saConfig.APIGroup, a.GetAPIGroup()) && | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we split the external, serialized config, and its internal representation?
Make it so that only one of username/group can be specified.