Skip to content
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

Add verb to authorizer attributes #14710

Merged
merged 1 commit into from Oct 2, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 5 additions & 4 deletions pkg/apiserver/handlers.go
Expand Up @@ -362,11 +362,10 @@ func (r *requestAttributeGetter) GetAttribs(req *http.Request) authorizer.Attrib
}
}

attribs.ReadOnly = IsReadOnlyReq(*req)

apiRequestInfo, _ := r.apiRequestInfoResolver.GetAPIRequestInfo(req)

attribs.APIGroup = apiRequestInfo.APIGroup
attribs.Verb = apiRequestInfo.Verb

// If a path follows the conventions of the REST object store, then
// we can extract the resource. Otherwise, not.
Expand Down Expand Up @@ -441,7 +440,8 @@ type APIRequestInfoResolver struct {
// /api/{version}/watch/namespaces/{namespace}/{resource}
func (r *APIRequestInfoResolver) GetAPIRequestInfo(req *http.Request) (APIRequestInfo, error) {
requestInfo := APIRequestInfo{
Raw: splitPath(req.URL.Path),
Raw: splitPath(req.URL.Path),
Verb: strings.ToLower(req.Method),
}

currentParts := requestInfo.Raw
Expand Down Expand Up @@ -489,8 +489,9 @@ func (r *APIRequestInfoResolver) GetAPIRequestInfo(req *http.Request) (APIReques
requestInfo.Verb = "patch"
case "DELETE":
requestInfo.Verb = "delete"
default:
requestInfo.Verb = ""
}

}

// URL forms: /namespaces/{namespace}/{kind}/*, where parts are adjusted to be relative to kind
Expand Down
46 changes: 23 additions & 23 deletions pkg/auth/authorizer/abac/abac_test.go
Expand Up @@ -75,49 +75,49 @@ func TestNotAuthorized(t *testing.T) {

testCases := []struct {
User user.DefaultInfo
RO bool
Verb string
Resource string
NS string
ExpectAllow bool
}{
// Scheduler can read pods
{User: uScheduler, RO: true, Resource: "pods", NS: "ns1", ExpectAllow: true},
{User: uScheduler, RO: true, Resource: "pods", NS: "", ExpectAllow: true},
{User: uScheduler, Verb: "list", Resource: "pods", NS: "ns1", ExpectAllow: true},
{User: uScheduler, Verb: "list", Resource: "pods", NS: "", ExpectAllow: true},
// Scheduler cannot write pods
{User: uScheduler, RO: false, Resource: "pods", NS: "ns1", ExpectAllow: false},
{User: uScheduler, RO: false, Resource: "pods", NS: "", ExpectAllow: false},
{User: uScheduler, Verb: "create", Resource: "pods", NS: "ns1", ExpectAllow: false},
{User: uScheduler, Verb: "create", Resource: "pods", NS: "", ExpectAllow: false},
// Scheduler can write bindings
{User: uScheduler, RO: true, Resource: "bindings", NS: "ns1", ExpectAllow: true},
{User: uScheduler, RO: true, Resource: "bindings", NS: "", ExpectAllow: true},
{User: uScheduler, Verb: "get", Resource: "bindings", NS: "ns1", ExpectAllow: true},
{User: uScheduler, Verb: "get", Resource: "bindings", NS: "", ExpectAllow: true},

// Alice can read and write anything in the right namespace.
{User: uAlice, RO: true, Resource: "pods", NS: "projectCaribou", ExpectAllow: true},
{User: uAlice, RO: true, Resource: "widgets", NS: "projectCaribou", ExpectAllow: true},
{User: uAlice, RO: true, Resource: "", NS: "projectCaribou", ExpectAllow: true},
{User: uAlice, RO: false, Resource: "pods", NS: "projectCaribou", ExpectAllow: true},
{User: uAlice, RO: false, Resource: "widgets", NS: "projectCaribou", ExpectAllow: true},
{User: uAlice, RO: false, Resource: "", NS: "projectCaribou", ExpectAllow: true},
{User: uAlice, Verb: "get", Resource: "pods", NS: "projectCaribou", ExpectAllow: true},
{User: uAlice, Verb: "get", Resource: "widgets", NS: "projectCaribou", ExpectAllow: true},
{User: uAlice, Verb: "get", Resource: "", NS: "projectCaribou", ExpectAllow: true},
{User: uAlice, Verb: "update", Resource: "pods", NS: "projectCaribou", ExpectAllow: true},
{User: uAlice, Verb: "update", Resource: "widgets", NS: "projectCaribou", ExpectAllow: true},
{User: uAlice, Verb: "update", Resource: "", NS: "projectCaribou", ExpectAllow: true},
// .. but not the wrong namespace.
{User: uAlice, RO: true, Resource: "pods", NS: "ns1", ExpectAllow: false},
{User: uAlice, RO: true, Resource: "widgets", NS: "ns1", ExpectAllow: false},
{User: uAlice, RO: true, Resource: "", NS: "ns1", ExpectAllow: false},
{User: uAlice, Verb: "get", Resource: "pods", NS: "ns1", ExpectAllow: false},
{User: uAlice, Verb: "get", Resource: "widgets", NS: "ns1", ExpectAllow: false},
{User: uAlice, Verb: "get", Resource: "", NS: "ns1", ExpectAllow: false},

// Chuck can read events, since anyone can.
{User: uChuck, RO: true, Resource: "events", NS: "ns1", ExpectAllow: true},
{User: uChuck, RO: true, Resource: "events", NS: "", ExpectAllow: true},
{User: uChuck, Verb: "get", Resource: "events", NS: "ns1", ExpectAllow: true},
{User: uChuck, Verb: "get", Resource: "events", NS: "", ExpectAllow: true},
// Chuck can't do other things.
{User: uChuck, RO: false, Resource: "events", NS: "ns1", ExpectAllow: false},
{User: uChuck, RO: true, Resource: "pods", NS: "ns1", ExpectAllow: false},
{User: uChuck, RO: true, Resource: "floop", NS: "ns1", ExpectAllow: false},
{User: uChuck, Verb: "update", Resource: "events", NS: "ns1", ExpectAllow: false},
{User: uChuck, Verb: "get", Resource: "pods", NS: "ns1", ExpectAllow: false},
{User: uChuck, Verb: "get", Resource: "floop", NS: "ns1", ExpectAllow: false},
// Chunk can't access things with no kind or namespace
// TODO: find a way to give someone access to miscellaneous endpoints, such as
// /healthz, /version, etc.
{User: uChuck, RO: true, Resource: "", NS: "", ExpectAllow: false},
{User: uChuck, Verb: "get", Resource: "", NS: "", ExpectAllow: false},
}
for i, tc := range testCases {
attr := authorizer.AttributesRecord{
User: &tc.User,
ReadOnly: tc.RO,
Verb: tc.Verb,
Resource: tc.Resource,
Namespace: tc.NS,
}
Expand Down
12 changes: 10 additions & 2 deletions pkg/auth/authorizer/interfaces.go
Expand Up @@ -32,6 +32,10 @@ type Attributes interface {
// authentication occurred.
GetGroups() []string

// GetVerb returns the kube verb associated with API requests (this includes get, list, watch, create, update, patch, delete, and proxy),
// or the lowercased HTTP verb associated with non-API requests (this includes get, put, post, patch, and delete)
GetVerb() string

// When IsReadOnly() == true, the request has no side effects, other than
// caching, logging, and other incidentals.
IsReadOnly() bool
Expand Down Expand Up @@ -62,7 +66,7 @@ func (f AuthorizerFunc) Authorize(a Attributes) error {
// AttributesRecord implements Attributes interface.
type AttributesRecord struct {
User user.Info
ReadOnly bool
Verb string
Namespace string
APIGroup string
Resource string
Expand All @@ -76,8 +80,12 @@ func (a AttributesRecord) GetGroups() []string {
return a.User.GetGroups()
}

func (a AttributesRecord) GetVerb() string {
return a.Verb
}

func (a AttributesRecord) IsReadOnly() bool {
return a.ReadOnly
return a.Verb == "get" || a.Verb == "list" || a.Verb == "watch"
}

func (a AttributesRecord) GetNamespace() string {
Expand Down