Merge pull request #14710 from liggitt/authz_attr

Auto commit by PR queue bot
This commit is contained in:
k8s-merge-robot 2015-10-02 09:18:13 -07:00
commit 333eaf5893
3 changed files with 38 additions and 29 deletions

View File

@ -362,11 +362,10 @@ func (r *requestAttributeGetter) GetAttribs(req *http.Request) authorizer.Attrib
} }
} }
attribs.ReadOnly = IsReadOnlyReq(*req)
apiRequestInfo, _ := r.apiRequestInfoResolver.GetAPIRequestInfo(req) apiRequestInfo, _ := r.apiRequestInfoResolver.GetAPIRequestInfo(req)
attribs.APIGroup = apiRequestInfo.APIGroup attribs.APIGroup = apiRequestInfo.APIGroup
attribs.Verb = apiRequestInfo.Verb
// If a path follows the conventions of the REST object store, then // If a path follows the conventions of the REST object store, then
// we can extract the resource. Otherwise, not. // we can extract the resource. Otherwise, not.
@ -441,7 +440,8 @@ type APIRequestInfoResolver struct {
// /api/{version}/watch/namespaces/{namespace}/{resource} // /api/{version}/watch/namespaces/{namespace}/{resource}
func (r *APIRequestInfoResolver) GetAPIRequestInfo(req *http.Request) (APIRequestInfo, error) { func (r *APIRequestInfoResolver) GetAPIRequestInfo(req *http.Request) (APIRequestInfo, error) {
requestInfo := APIRequestInfo{ requestInfo := APIRequestInfo{
Raw: splitPath(req.URL.Path), Raw: splitPath(req.URL.Path),
Verb: strings.ToLower(req.Method),
} }
currentParts := requestInfo.Raw currentParts := requestInfo.Raw
@ -489,8 +489,9 @@ func (r *APIRequestInfoResolver) GetAPIRequestInfo(req *http.Request) (APIReques
requestInfo.Verb = "patch" requestInfo.Verb = "patch"
case "DELETE": case "DELETE":
requestInfo.Verb = "delete" requestInfo.Verb = "delete"
default:
requestInfo.Verb = ""
} }
} }
// URL forms: /namespaces/{namespace}/{kind}/*, where parts are adjusted to be relative to kind // URL forms: /namespaces/{namespace}/{kind}/*, where parts are adjusted to be relative to kind

View File

@ -75,49 +75,49 @@ func TestNotAuthorized(t *testing.T) {
testCases := []struct { testCases := []struct {
User user.DefaultInfo User user.DefaultInfo
RO bool Verb string
Resource string Resource string
NS string NS string
ExpectAllow bool ExpectAllow bool
}{ }{
// Scheduler can read pods // Scheduler can read pods
{User: uScheduler, RO: true, Resource: "pods", NS: "ns1", ExpectAllow: true}, {User: uScheduler, Verb: "list", Resource: "pods", NS: "ns1", ExpectAllow: true},
{User: uScheduler, RO: true, Resource: "pods", NS: "", ExpectAllow: true}, {User: uScheduler, Verb: "list", Resource: "pods", NS: "", ExpectAllow: true},
// Scheduler cannot write pods // Scheduler cannot write pods
{User: uScheduler, RO: false, Resource: "pods", NS: "ns1", ExpectAllow: false}, {User: uScheduler, Verb: "create", Resource: "pods", NS: "ns1", ExpectAllow: false},
{User: uScheduler, RO: false, Resource: "pods", NS: "", ExpectAllow: false}, {User: uScheduler, Verb: "create", Resource: "pods", NS: "", ExpectAllow: false},
// Scheduler can write bindings // Scheduler can write bindings
{User: uScheduler, RO: true, Resource: "bindings", NS: "ns1", ExpectAllow: true}, {User: uScheduler, Verb: "get", Resource: "bindings", NS: "ns1", ExpectAllow: true},
{User: uScheduler, RO: true, Resource: "bindings", NS: "", ExpectAllow: true}, {User: uScheduler, Verb: "get", Resource: "bindings", NS: "", ExpectAllow: true},
// Alice can read and write anything in the right namespace. // Alice can read and write anything in the right namespace.
{User: uAlice, RO: true, Resource: "pods", NS: "projectCaribou", ExpectAllow: true}, {User: uAlice, Verb: "get", Resource: "pods", NS: "projectCaribou", ExpectAllow: true},
{User: uAlice, RO: true, Resource: "widgets", NS: "projectCaribou", ExpectAllow: true}, {User: uAlice, Verb: "get", Resource: "widgets", NS: "projectCaribou", ExpectAllow: true},
{User: uAlice, RO: true, Resource: "", NS: "projectCaribou", ExpectAllow: true}, {User: uAlice, Verb: "get", Resource: "", NS: "projectCaribou", ExpectAllow: true},
{User: uAlice, RO: false, Resource: "pods", NS: "projectCaribou", ExpectAllow: true}, {User: uAlice, Verb: "update", Resource: "pods", NS: "projectCaribou", ExpectAllow: true},
{User: uAlice, RO: false, Resource: "widgets", NS: "projectCaribou", ExpectAllow: true}, {User: uAlice, Verb: "update", Resource: "widgets", NS: "projectCaribou", ExpectAllow: true},
{User: uAlice, RO: false, Resource: "", NS: "projectCaribou", ExpectAllow: true}, {User: uAlice, Verb: "update", Resource: "", NS: "projectCaribou", ExpectAllow: true},
// .. but not the wrong namespace. // .. but not the wrong namespace.
{User: uAlice, RO: true, Resource: "pods", NS: "ns1", ExpectAllow: false}, {User: uAlice, Verb: "get", Resource: "pods", NS: "ns1", ExpectAllow: false},
{User: uAlice, RO: true, Resource: "widgets", NS: "ns1", ExpectAllow: false}, {User: uAlice, Verb: "get", Resource: "widgets", NS: "ns1", ExpectAllow: false},
{User: uAlice, RO: true, Resource: "", NS: "ns1", ExpectAllow: false}, {User: uAlice, Verb: "get", Resource: "", NS: "ns1", ExpectAllow: false},
// Chuck can read events, since anyone can. // Chuck can read events, since anyone can.
{User: uChuck, RO: true, Resource: "events", NS: "ns1", ExpectAllow: true}, {User: uChuck, Verb: "get", Resource: "events", NS: "ns1", ExpectAllow: true},
{User: uChuck, RO: true, Resource: "events", NS: "", ExpectAllow: true}, {User: uChuck, Verb: "get", Resource: "events", NS: "", ExpectAllow: true},
// Chuck can't do other things. // Chuck can't do other things.
{User: uChuck, RO: false, Resource: "events", NS: "ns1", ExpectAllow: false}, {User: uChuck, Verb: "update", Resource: "events", NS: "ns1", ExpectAllow: false},
{User: uChuck, RO: true, Resource: "pods", NS: "ns1", ExpectAllow: false}, {User: uChuck, Verb: "get", Resource: "pods", NS: "ns1", ExpectAllow: false},
{User: uChuck, RO: true, Resource: "floop", NS: "ns1", ExpectAllow: false}, {User: uChuck, Verb: "get", Resource: "floop", NS: "ns1", ExpectAllow: false},
// Chunk can't access things with no kind or namespace // Chunk can't access things with no kind or namespace
// TODO: find a way to give someone access to miscellaneous endpoints, such as // TODO: find a way to give someone access to miscellaneous endpoints, such as
// /healthz, /version, etc. // /healthz, /version, etc.
{User: uChuck, RO: true, Resource: "", NS: "", ExpectAllow: false}, {User: uChuck, Verb: "get", Resource: "", NS: "", ExpectAllow: false},
} }
for i, tc := range testCases { for i, tc := range testCases {
attr := authorizer.AttributesRecord{ attr := authorizer.AttributesRecord{
User: &tc.User, User: &tc.User,
ReadOnly: tc.RO, Verb: tc.Verb,
Resource: tc.Resource, Resource: tc.Resource,
Namespace: tc.NS, Namespace: tc.NS,
} }

View File

@ -32,6 +32,10 @@ type Attributes interface {
// authentication occurred. // authentication occurred.
GetGroups() []string 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 // When IsReadOnly() == true, the request has no side effects, other than
// caching, logging, and other incidentals. // caching, logging, and other incidentals.
IsReadOnly() bool IsReadOnly() bool
@ -62,7 +66,7 @@ func (f AuthorizerFunc) Authorize(a Attributes) error {
// AttributesRecord implements Attributes interface. // AttributesRecord implements Attributes interface.
type AttributesRecord struct { type AttributesRecord struct {
User user.Info User user.Info
ReadOnly bool Verb string
Namespace string Namespace string
APIGroup string APIGroup string
Resource string Resource string
@ -76,8 +80,12 @@ func (a AttributesRecord) GetGroups() []string {
return a.User.GetGroups() return a.User.GetGroups()
} }
func (a AttributesRecord) GetVerb() string {
return a.Verb
}
func (a AttributesRecord) IsReadOnly() bool { func (a AttributesRecord) IsReadOnly() bool {
return a.ReadOnly return a.Verb == "get" || a.Verb == "list" || a.Verb == "watch"
} }
func (a AttributesRecord) GetNamespace() string { func (a AttributesRecord) GetNamespace() string {