move authorizers over to new interface
This commit is contained in:
@@ -221,13 +221,13 @@ func resourceMatches(p abac.Policy, a authorizer.Attributes) bool {
|
||||
}
|
||||
|
||||
// Authorizer implements authorizer.Authorize
|
||||
func (pl policyList) Authorize(a authorizer.Attributes) (bool, string, error) {
|
||||
func (pl policyList) Authorize(a authorizer.Attributes) (authorizer.Decision, string, error) {
|
||||
for _, p := range pl {
|
||||
if matches(*p, a) {
|
||||
return true, "", nil
|
||||
return authorizer.DecisionAllow, "", nil
|
||||
}
|
||||
}
|
||||
return false, "No policy matched.", nil
|
||||
return authorizer.DecisionNoOpinion, "No policy matched.", nil
|
||||
// TODO: Benchmark how much time policy matching takes with a medium size
|
||||
// policy file, compared to other steps such as encoding/decoding.
|
||||
// Then, add Caching only if needed.
|
||||
|
@@ -81,46 +81,46 @@ func TestAuthorizeV0(t *testing.T) {
|
||||
uChuck := user.DefaultInfo{Name: "chuck", UID: "uid5", Groups: authenticatedGroup}
|
||||
|
||||
testCases := []struct {
|
||||
User user.DefaultInfo
|
||||
Verb string
|
||||
Resource string
|
||||
NS string
|
||||
APIGroup string
|
||||
Path string
|
||||
ExpectAllow bool
|
||||
User user.DefaultInfo
|
||||
Verb string
|
||||
Resource string
|
||||
NS string
|
||||
APIGroup string
|
||||
Path string
|
||||
ExpectDecision authorizer.Decision
|
||||
}{
|
||||
// Scheduler can read pods
|
||||
{User: uScheduler, Verb: "list", Resource: "pods", NS: "ns1", ExpectAllow: true},
|
||||
{User: uScheduler, Verb: "list", Resource: "pods", NS: "", ExpectAllow: true},
|
||||
{User: uScheduler, Verb: "list", Resource: "pods", NS: "ns1", ExpectDecision: authorizer.DecisionAllow},
|
||||
{User: uScheduler, Verb: "list", Resource: "pods", NS: "", ExpectDecision: authorizer.DecisionAllow},
|
||||
// Scheduler cannot write pods
|
||||
{User: uScheduler, Verb: "create", Resource: "pods", NS: "ns1", ExpectAllow: false},
|
||||
{User: uScheduler, Verb: "create", Resource: "pods", NS: "", ExpectAllow: false},
|
||||
{User: uScheduler, Verb: "create", Resource: "pods", NS: "ns1", ExpectDecision: authorizer.DecisionNoOpinion},
|
||||
{User: uScheduler, Verb: "create", Resource: "pods", NS: "", ExpectDecision: authorizer.DecisionNoOpinion},
|
||||
// Scheduler can write bindings
|
||||
{User: uScheduler, Verb: "get", Resource: "bindings", NS: "ns1", ExpectAllow: true},
|
||||
{User: uScheduler, Verb: "get", Resource: "bindings", NS: "", ExpectAllow: true},
|
||||
{User: uScheduler, Verb: "get", Resource: "bindings", NS: "ns1", ExpectDecision: authorizer.DecisionAllow},
|
||||
{User: uScheduler, Verb: "get", Resource: "bindings", NS: "", ExpectDecision: authorizer.DecisionAllow},
|
||||
|
||||
// Alice can read and write anything in the right namespace.
|
||||
{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},
|
||||
{User: uAlice, Verb: "update", Resource: "foo", NS: "projectCaribou", APIGroup: "bar", ExpectAllow: true},
|
||||
{User: uAlice, Verb: "get", Resource: "pods", NS: "projectCaribou", ExpectDecision: authorizer.DecisionAllow},
|
||||
{User: uAlice, Verb: "get", Resource: "widgets", NS: "projectCaribou", ExpectDecision: authorizer.DecisionAllow},
|
||||
{User: uAlice, Verb: "get", Resource: "", NS: "projectCaribou", ExpectDecision: authorizer.DecisionAllow},
|
||||
{User: uAlice, Verb: "update", Resource: "pods", NS: "projectCaribou", ExpectDecision: authorizer.DecisionAllow},
|
||||
{User: uAlice, Verb: "update", Resource: "widgets", NS: "projectCaribou", ExpectDecision: authorizer.DecisionAllow},
|
||||
{User: uAlice, Verb: "update", Resource: "", NS: "projectCaribou", ExpectDecision: authorizer.DecisionAllow},
|
||||
{User: uAlice, Verb: "update", Resource: "foo", NS: "projectCaribou", APIGroup: "bar", ExpectDecision: authorizer.DecisionAllow},
|
||||
// .. but not the wrong namespace.
|
||||
{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},
|
||||
{User: uAlice, Verb: "get", Resource: "pods", NS: "ns1", ExpectDecision: authorizer.DecisionNoOpinion},
|
||||
{User: uAlice, Verb: "get", Resource: "widgets", NS: "ns1", ExpectDecision: authorizer.DecisionNoOpinion},
|
||||
{User: uAlice, Verb: "get", Resource: "", NS: "ns1", ExpectDecision: authorizer.DecisionNoOpinion},
|
||||
|
||||
// Chuck can read events, since anyone can.
|
||||
{User: uChuck, Verb: "get", Resource: "events", NS: "ns1", ExpectAllow: true},
|
||||
{User: uChuck, Verb: "get", Resource: "events", NS: "", ExpectAllow: true},
|
||||
{User: uChuck, Verb: "get", Resource: "events", NS: "ns1", ExpectDecision: authorizer.DecisionAllow},
|
||||
{User: uChuck, Verb: "get", Resource: "events", NS: "", ExpectDecision: authorizer.DecisionAllow},
|
||||
// Chuck can't do other things.
|
||||
{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},
|
||||
{User: uChuck, Verb: "update", Resource: "events", NS: "ns1", ExpectDecision: authorizer.DecisionNoOpinion},
|
||||
{User: uChuck, Verb: "get", Resource: "pods", NS: "ns1", ExpectDecision: authorizer.DecisionNoOpinion},
|
||||
{User: uChuck, Verb: "get", Resource: "floop", NS: "ns1", ExpectDecision: authorizer.DecisionNoOpinion},
|
||||
// Chunk can't access things with no kind or namespace
|
||||
{User: uChuck, Verb: "get", Path: "/", Resource: "", NS: "", ExpectAllow: false},
|
||||
{User: uChuck, Verb: "get", Path: "/", Resource: "", NS: "", ExpectDecision: authorizer.DecisionNoOpinion},
|
||||
}
|
||||
for i, tc := range testCases {
|
||||
attr := authorizer.AttributesRecord{
|
||||
@@ -133,11 +133,11 @@ func TestAuthorizeV0(t *testing.T) {
|
||||
|
||||
ResourceRequest: len(tc.NS) > 0 || len(tc.Resource) > 0,
|
||||
}
|
||||
authorized, _, _ := a.Authorize(attr)
|
||||
if tc.ExpectAllow != authorized {
|
||||
decision, _, _ := a.Authorize(attr)
|
||||
if tc.ExpectDecision != decision {
|
||||
t.Logf("tc: %v -> attr %v", tc, attr)
|
||||
t.Errorf("%d: Expected allowed=%v but actually allowed=%v\n\t%v",
|
||||
i, tc.ExpectAllow, authorized, tc)
|
||||
i, tc.ExpectDecision, decision, tc)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -373,72 +373,72 @@ func TestAuthorizeV1beta1(t *testing.T) {
|
||||
uAPIGroup := user.DefaultInfo{Name: "apigroupuser", UID: "uid8", Groups: authenticatedGroup}
|
||||
|
||||
testCases := []struct {
|
||||
User user.DefaultInfo
|
||||
Verb string
|
||||
Resource string
|
||||
APIGroup string
|
||||
NS string
|
||||
Path string
|
||||
ExpectAllow bool
|
||||
User user.DefaultInfo
|
||||
Verb string
|
||||
Resource string
|
||||
APIGroup string
|
||||
NS string
|
||||
Path string
|
||||
ExpectDecision authorizer.Decision
|
||||
}{
|
||||
// Scheduler can read pods
|
||||
{User: uScheduler, Verb: "list", Resource: "pods", NS: "ns1", ExpectAllow: true},
|
||||
{User: uScheduler, Verb: "list", Resource: "pods", NS: "", ExpectAllow: true},
|
||||
{User: uScheduler, Verb: "list", Resource: "pods", NS: "ns1", ExpectDecision: authorizer.DecisionAllow},
|
||||
{User: uScheduler, Verb: "list", Resource: "pods", NS: "", ExpectDecision: authorizer.DecisionAllow},
|
||||
// Scheduler cannot write pods
|
||||
{User: uScheduler, Verb: "create", Resource: "pods", NS: "ns1", ExpectAllow: false},
|
||||
{User: uScheduler, Verb: "create", Resource: "pods", NS: "", ExpectAllow: false},
|
||||
{User: uScheduler, Verb: "create", Resource: "pods", NS: "ns1", ExpectDecision: authorizer.DecisionNoOpinion},
|
||||
{User: uScheduler, Verb: "create", Resource: "pods", NS: "", ExpectDecision: authorizer.DecisionNoOpinion},
|
||||
// Scheduler can write bindings
|
||||
{User: uScheduler, Verb: "get", Resource: "bindings", NS: "ns1", ExpectAllow: true},
|
||||
{User: uScheduler, Verb: "get", Resource: "bindings", NS: "", ExpectAllow: true},
|
||||
{User: uScheduler, Verb: "get", Resource: "bindings", NS: "ns1", ExpectDecision: authorizer.DecisionAllow},
|
||||
{User: uScheduler, Verb: "get", Resource: "bindings", NS: "", ExpectDecision: authorizer.DecisionAllow},
|
||||
|
||||
// Alice can read and write anything in the right namespace.
|
||||
{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},
|
||||
{User: uAlice, Verb: "get", Resource: "pods", NS: "projectCaribou", ExpectDecision: authorizer.DecisionAllow},
|
||||
{User: uAlice, Verb: "get", Resource: "widgets", NS: "projectCaribou", ExpectDecision: authorizer.DecisionAllow},
|
||||
{User: uAlice, Verb: "get", Resource: "", NS: "projectCaribou", ExpectDecision: authorizer.DecisionAllow},
|
||||
{User: uAlice, Verb: "update", Resource: "pods", NS: "projectCaribou", ExpectDecision: authorizer.DecisionAllow},
|
||||
{User: uAlice, Verb: "update", Resource: "widgets", NS: "projectCaribou", ExpectDecision: authorizer.DecisionAllow},
|
||||
{User: uAlice, Verb: "update", Resource: "", NS: "projectCaribou", ExpectDecision: authorizer.DecisionAllow},
|
||||
// .. but not the wrong namespace.
|
||||
{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},
|
||||
{User: uAlice, Verb: "get", Resource: "pods", NS: "ns1", ExpectDecision: authorizer.DecisionNoOpinion},
|
||||
{User: uAlice, Verb: "get", Resource: "widgets", NS: "ns1", ExpectDecision: authorizer.DecisionNoOpinion},
|
||||
{User: uAlice, Verb: "get", Resource: "", NS: "ns1", ExpectDecision: authorizer.DecisionNoOpinion},
|
||||
|
||||
// Debbie can write to pods in the right namespace
|
||||
{User: uDebbie, Verb: "update", Resource: "pods", NS: "projectCaribou", ExpectAllow: true},
|
||||
{User: uDebbie, Verb: "update", Resource: "pods", NS: "projectCaribou", ExpectDecision: authorizer.DecisionAllow},
|
||||
|
||||
// Chuck can read events, since anyone can.
|
||||
{User: uChuck, Verb: "get", Resource: "events", NS: "ns1", ExpectAllow: true},
|
||||
{User: uChuck, Verb: "get", Resource: "events", NS: "", ExpectAllow: true},
|
||||
{User: uChuck, Verb: "get", Resource: "events", NS: "ns1", ExpectDecision: authorizer.DecisionAllow},
|
||||
{User: uChuck, Verb: "get", Resource: "events", NS: "", ExpectDecision: authorizer.DecisionAllow},
|
||||
// Chuck can't do other things.
|
||||
{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},
|
||||
{User: uChuck, Verb: "update", Resource: "events", NS: "ns1", ExpectDecision: authorizer.DecisionNoOpinion},
|
||||
{User: uChuck, Verb: "get", Resource: "pods", NS: "ns1", ExpectDecision: authorizer.DecisionNoOpinion},
|
||||
{User: uChuck, Verb: "get", Resource: "floop", NS: "ns1", ExpectDecision: authorizer.DecisionNoOpinion},
|
||||
// Chuck can't access things with no resource or namespace
|
||||
{User: uChuck, Verb: "get", Path: "/", Resource: "", NS: "", ExpectAllow: false},
|
||||
{User: uChuck, Verb: "get", Path: "/", Resource: "", NS: "", ExpectDecision: authorizer.DecisionNoOpinion},
|
||||
// but can access /api
|
||||
{User: uChuck, Verb: "get", Path: "/api", Resource: "", NS: "", ExpectAllow: true},
|
||||
{User: uChuck, Verb: "get", Path: "/api", Resource: "", NS: "", ExpectDecision: authorizer.DecisionAllow},
|
||||
// though he cannot write to it
|
||||
{User: uChuck, Verb: "create", Path: "/api", Resource: "", NS: "", ExpectAllow: false},
|
||||
{User: uChuck, Verb: "create", Path: "/api", Resource: "", NS: "", ExpectDecision: authorizer.DecisionNoOpinion},
|
||||
// while he can write to /custom
|
||||
{User: uChuck, Verb: "update", Path: "/custom", Resource: "", NS: "", ExpectAllow: true},
|
||||
{User: uChuck, Verb: "update", Path: "/custom", Resource: "", NS: "", ExpectDecision: authorizer.DecisionAllow},
|
||||
// he cannot get "/root"
|
||||
{User: uChuck, Verb: "get", Path: "/root", Resource: "", NS: "", ExpectAllow: false},
|
||||
{User: uChuck, Verb: "get", Path: "/root", Resource: "", NS: "", ExpectDecision: authorizer.DecisionNoOpinion},
|
||||
// but can get any subpath
|
||||
{User: uChuck, Verb: "get", Path: "/root/", Resource: "", NS: "", ExpectAllow: true},
|
||||
{User: uChuck, Verb: "get", Path: "/root/test/1/2/3", Resource: "", NS: "", ExpectAllow: true},
|
||||
{User: uChuck, Verb: "get", Path: "/root/", Resource: "", NS: "", ExpectDecision: authorizer.DecisionAllow},
|
||||
{User: uChuck, Verb: "get", Path: "/root/test/1/2/3", Resource: "", NS: "", ExpectDecision: authorizer.DecisionAllow},
|
||||
|
||||
// the user "noresource" can get any non-resource request
|
||||
{User: uNoResource, Verb: "get", Path: "", Resource: "", NS: "", ExpectAllow: true},
|
||||
{User: uNoResource, Verb: "get", Path: "/", Resource: "", NS: "", ExpectAllow: true},
|
||||
{User: uNoResource, Verb: "get", Path: "/foo/bar/baz", Resource: "", NS: "", ExpectAllow: true},
|
||||
{User: uNoResource, Verb: "get", Path: "", Resource: "", NS: "", ExpectDecision: authorizer.DecisionAllow},
|
||||
{User: uNoResource, Verb: "get", Path: "/", Resource: "", NS: "", ExpectDecision: authorizer.DecisionAllow},
|
||||
{User: uNoResource, Verb: "get", Path: "/foo/bar/baz", Resource: "", NS: "", ExpectDecision: authorizer.DecisionAllow},
|
||||
// but cannot get any request where IsResourceRequest() == true
|
||||
{User: uNoResource, Verb: "get", Path: "/", Resource: "", NS: "bar", ExpectAllow: false},
|
||||
{User: uNoResource, Verb: "get", Path: "/foo/bar/baz", Resource: "foo", NS: "bar", ExpectAllow: false},
|
||||
{User: uNoResource, Verb: "get", Path: "/", Resource: "", NS: "bar", ExpectDecision: authorizer.DecisionNoOpinion},
|
||||
{User: uNoResource, Verb: "get", Path: "/foo/bar/baz", Resource: "foo", NS: "bar", ExpectDecision: authorizer.DecisionNoOpinion},
|
||||
|
||||
// Test APIGroup matching
|
||||
{User: uAPIGroup, Verb: "get", APIGroup: "x", Resource: "foo", NS: "projectAnyGroup", ExpectAllow: true},
|
||||
{User: uAPIGroup, Verb: "get", APIGroup: "x", Resource: "foo", NS: "projectEmptyGroup", ExpectAllow: false},
|
||||
{User: uAPIGroup, Verb: "get", APIGroup: "x", Resource: "foo", NS: "projectXGroup", ExpectAllow: true},
|
||||
{User: uAPIGroup, Verb: "get", APIGroup: "x", Resource: "foo", NS: "projectAnyGroup", ExpectDecision: authorizer.DecisionAllow},
|
||||
{User: uAPIGroup, Verb: "get", APIGroup: "x", Resource: "foo", NS: "projectEmptyGroup", ExpectDecision: authorizer.DecisionNoOpinion},
|
||||
{User: uAPIGroup, Verb: "get", APIGroup: "x", Resource: "foo", NS: "projectXGroup", ExpectDecision: authorizer.DecisionAllow},
|
||||
}
|
||||
for i, tc := range testCases {
|
||||
attr := authorizer.AttributesRecord{
|
||||
@@ -451,10 +451,10 @@ func TestAuthorizeV1beta1(t *testing.T) {
|
||||
Path: tc.Path,
|
||||
}
|
||||
// t.Logf("tc %2v: %v -> attr %v", i, tc, attr)
|
||||
authorized, _, _ := a.Authorize(attr)
|
||||
if tc.ExpectAllow != authorized {
|
||||
decision, _, _ := a.Authorize(attr)
|
||||
if tc.ExpectDecision != decision {
|
||||
t.Errorf("%d: Expected allowed=%v but actually allowed=%v, for case %+v & %+v",
|
||||
i, tc.ExpectAllow, authorized, tc, attr)
|
||||
i, tc.ExpectDecision, decision, tc, attr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user