func TestVerbRestrictionsWork(t *testing.T) { test1 := &authorizeTest{ context: kapi.WithUser(kapi.WithNamespace(kapi.NewContext(), "adze"), &user.DefaultInfo{Name: "Valerie"}), attributes: &DefaultAuthorizationAttributes{ Verb: "get", Resource: "buildConfigs", }, expectedAllowed: true, expectedReason: "allowed by rule in adze", } test1.clusterPolicies = newDefaultClusterPolicies() test1.policies = newAdzePolicies() test1.clusterBindings = newDefaultClusterPolicyBindings() test1.bindings = newAdzeBindings() test1.test(t) test2 := &authorizeTest{ context: kapi.WithUser(kapi.WithNamespace(kapi.NewContext(), "adze"), &user.DefaultInfo{Name: "Valerie"}), attributes: &DefaultAuthorizationAttributes{ Verb: "create", Resource: "buildConfigs", }, expectedAllowed: false, expectedReason: `User "Valerie" cannot create buildConfigs in project "adze"`, } test2.clusterPolicies = newDefaultClusterPolicies() test2.policies = newAdzePolicies() test2.clusterBindings = newDefaultClusterPolicyBindings() test2.bindings = newAdzeBindings() test2.test(t) }
func TestResourceRestrictionsWithWeirdWork(t *testing.T) { test1 := &authorizeTest{ context: kapi.WithUser(kapi.WithNamespace(kapi.NewContext(), "adze"), &user.DefaultInfo{Name: "Rachel"}), attributes: &DefaultAuthorizationAttributes{ Verb: "get", Resource: "BUILDCONFIGS", }, expectedAllowed: true, expectedReason: "allowed by rule in adze", } test1.clusterPolicies = newDefaultClusterPolicies() test1.policies = newAdzePolicies() test1.clusterBindings = newDefaultClusterPolicyBindings() test1.bindings = newAdzeBindings() test1.test(t) test2 := &authorizeTest{ context: kapi.WithUser(kapi.WithNamespace(kapi.NewContext(), "adze"), &user.DefaultInfo{Name: "Rachel"}), attributes: &DefaultAuthorizationAttributes{ Verb: "get", Resource: "buildconfigs", }, expectedAllowed: true, expectedReason: "allowed by rule in adze", } test2.clusterPolicies = newDefaultClusterPolicies() test2.policies = newAdzePolicies() test2.clusterBindings = newDefaultClusterPolicyBindings() test2.bindings = newAdzeBindings() test2.test(t) }
func TestStrategyPrepareMethods(t *testing.T) { _, helper := newHelper(t) storage, _ := NewREST(helper, testDefaultRegistry, &fakeSubjectAccessReviewRegistry{}) stream := validNewStream() strategy := fakeStrategy{imagestream.NewStrategy(testDefaultRegistry, &fakeSubjectAccessReviewRegistry{})} storage.store.CreateStrategy = strategy storage.store.UpdateStrategy = strategy ctx := kapi.WithUser(kapi.NewDefaultContext(), &fakeUser{}) obj, err := storage.Create(ctx, stream) if err != nil { t.Fatalf("Unexpected error: %v", err) } updatedStream := obj.(*api.ImageStream) if updatedStream.Annotations["test"] != "PrepareForCreate" { t.Errorf("Expected PrepareForCreate annotation") } obj, _, err = storage.Update(ctx, updatedStream) if err != nil { t.Errorf("Unexpected error: %v", err) } updatedStream = obj.(*api.ImageStream) if updatedStream.Annotations["test"] != "PrepareForUpdate" { t.Errorf("Expected PrepareForUpdate annotation") } }
func TestListProjects(t *testing.T) { namespaceList := kapi.NamespaceList{ Items: []kapi.Namespace{ { ObjectMeta: kapi.ObjectMeta{Name: "foo"}, }, }, } mockClient := testclient.NewSimpleFake(&namespaceList) storage := REST{ client: mockClient.Namespaces(), lister: &mockLister{&namespaceList}, } user := &user.DefaultInfo{ Name: "test-user", UID: "test-uid", Groups: []string{"test-groups"}, } ctx := kapi.WithUser(kapi.NewContext(), user) response, err := storage.List(ctx, labels.Everything(), fields.Everything()) if err != nil { t.Errorf("%#v should be nil.", err) } projects := response.(*api.ProjectList) if len(projects.Items) != 1 { t.Errorf("%#v projects.Items should have len 1.", projects.Items) } responseProject := projects.Items[0] if e, r := responseProject.Name, "foo"; e != r { t.Errorf("%#v != %#v.", e, r) } }
func TestUpdateError(t *testing.T) { ctx := kapi.WithUser(kapi.WithNamespace(kapi.NewContext(), "unittest"), &user.DefaultInfo{Name: "system:admin"}) storage := makeTestStorage() obj, err := storage.Create(ctx, &authorizationapi.RoleBinding{ ObjectMeta: kapi.ObjectMeta{Name: "my-different"}, RoleRef: kapi.ObjectReference{Name: "admin"}, }) if err != nil { t.Errorf("unexpected error: %v", err) return } original := obj.(*authorizationapi.RoleBinding) roleBinding := &authorizationapi.RoleBinding{ ObjectMeta: kapi.ObjectMeta{Name: "my-roleBinding", ResourceVersion: original.ResourceVersion}, RoleRef: kapi.ObjectReference{Name: "admin"}, } _, _, err = storage.Update(ctx, roleBinding) if err == nil { t.Errorf("Missing expected error") return } if !kapierrors.IsNotFound(err) { t.Errorf("Unexpected error %v", err) } }
func TestUpdateCannotChangeRoleRefError(t *testing.T) { ctx := kapi.WithUser(kapi.WithNamespace(kapi.NewContext(), "unittest"), &user.DefaultInfo{Name: "system:admin"}) storage := makeTestStorage() obj, err := storage.Create(ctx, &authorizationapi.RoleBinding{ ObjectMeta: kapi.ObjectMeta{Name: "my-different"}, RoleRef: kapi.ObjectReference{Name: "admin"}, }) if err != nil { t.Errorf("unexpected error: %v", err) return } original := obj.(*authorizationapi.RoleBinding) roleBinding := &authorizationapi.RoleBinding{ ObjectMeta: kapi.ObjectMeta{Name: "my-different", ResourceVersion: original.ResourceVersion}, RoleRef: kapi.ObjectReference{Name: "cluster-admin"}, } _, _, err = storage.Update(ctx, roleBinding) if err == nil { t.Errorf("Missing expected error") return } expectedErr := "cannot change roleRef" if !strings.Contains(err.Error(), expectedErr) { t.Errorf("Expected %v, got %v", expectedErr, err.Error()) } }
func TestCreateImageStreamOK(t *testing.T) { _, helper := newHelper(t) storage, _ := NewREST(helper, noDefaultRegistry, &fakeSubjectAccessReviewRegistry{}) stream := &api.ImageStream{ObjectMeta: kapi.ObjectMeta{Name: "foo"}} ctx := kapi.WithUser(kapi.NewDefaultContext(), &fakeUser{}) _, err := storage.Create(ctx, stream) if err != nil { t.Fatalf("Unexpected non-nil error: %#v", err) } actual := &api.ImageStream{} if err := helper.ExtractObj("/imagestreams/default/foo", actual, false); err != nil { t.Fatalf("unexpected extraction error: %v", err) } if actual.Name != stream.Name { t.Errorf("unexpected stream: %#v", actual) } if len(actual.UID) == 0 { t.Errorf("expected stream UID to be set: %#v", actual) } if stream.CreationTimestamp.IsZero() { t.Error("Unexpected zero CreationTimestamp") } if stream.Spec.DockerImageRepository != "" { t.Errorf("unexpected stream: %#v", stream) } }
func TestUpdateImageStreamConflictingNamespace(t *testing.T) { fakeEtcdClient, helper := newHelper(t) fakeEtcdClient.Data["/imagestreams/legal-name/bar"] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Value: runtime.EncodeOrDie(latest.Codec, &api.ImageStream{ ObjectMeta: kapi.ObjectMeta{Name: "bar", Namespace: "default"}, }), ModifiedIndex: 2, }, }, } storage, _ := NewREST(helper, noDefaultRegistry, &fakeSubjectAccessReviewRegistry{}) ctx := kapi.WithUser(kapi.WithNamespace(kapi.NewContext(), "legal-name"), &fakeUser{}) obj, created, err := storage.Update(ctx, &api.ImageStream{ ObjectMeta: kapi.ObjectMeta{Name: "bar", Namespace: "some-value", ResourceVersion: "2"}, }) if obj != nil || created { t.Error("Expected a nil obj, but we got a value") } checkExpectedNamespaceError(t, err) }
func TestDeniedWithError(t *testing.T) { test := &authorizeTest{ context: kapi.WithUser(kapi.WithNamespace(kapi.NewContext(), "adze"), &user.DefaultInfo{Name: "Anna"}), attributes: &DefaultAuthorizationAttributes{ Verb: "update", Resource: "roles", }, expectedAllowed: false, expectedError: "my special error", } test.clusterPolicies = newDefaultClusterPolicies() test.policies = append(test.policies, newAdzePolicies()...) test.clusterBindings = newDefaultClusterPolicyBindings() test.bindings = append(test.bindings, newAdzeBindings()...) test.bindings[0].RoleBindings["missing"] = &authorizationapi.RoleBinding{ ObjectMeta: kapi.ObjectMeta{ Name: "missing", }, RoleRef: kapi.ObjectReference{ Name: "not-a-real-binding", }, Users: util.NewStringSet("Anna"), } test.policyRetrievalError = errors.New("my special error") test.test(t) }
func TestAllowedWithMissingBinding(t *testing.T) { test := &authorizeTest{ context: kapi.WithUser(kapi.WithNamespace(kapi.NewContext(), "adze"), &user.DefaultInfo{Name: "Anna"}), attributes: &DefaultAuthorizationAttributes{ Verb: "update", Resource: "roles", }, expectedAllowed: true, expectedReason: "allowed by rule in adze", } test.clusterPolicies = newDefaultClusterPolicies() test.policies = append(test.policies, newAdzePolicies()...) test.clusterBindings = newDefaultClusterPolicyBindings() test.bindings = append(test.bindings, newAdzeBindings()...) test.bindings[0].RoleBindings["missing"] = &authorizationapi.RoleBinding{ ObjectMeta: kapi.ObjectMeta{ Name: "missing", }, RoleRef: kapi.ObjectReference{ Name: "not-a-real-binding", }, Users: util.NewStringSet("Anna"), } test.test(t) }
func TestUpdateImageStreamOK(t *testing.T) { fakeEtcdClient, helper := newHelper(t) fakeEtcdClient.Data["/imagestreams/default/bar"] = tools.EtcdResponseWithError{ R: &etcd.Response{ Node: &etcd.Node{ Value: runtime.EncodeOrDie(latest.Codec, &api.ImageStream{ ObjectMeta: kapi.ObjectMeta{Name: "bar", Namespace: "default"}, }), ModifiedIndex: 2, }, }, } storage, _ := NewREST(helper, noDefaultRegistry, &fakeSubjectAccessReviewRegistry{}) ctx := kapi.WithUser(kapi.NewDefaultContext(), &fakeUser{}) obj, created, err := storage.Update(ctx, &api.ImageStream{ObjectMeta: kapi.ObjectMeta{Name: "bar", ResourceVersion: "1"}}) if !errors.IsConflict(err) { t.Fatalf("unexpected non-error: %v", err) } obj, created, err = storage.Update(ctx, &api.ImageStream{ObjectMeta: kapi.ObjectMeta{Name: "bar", ResourceVersion: "2"}}) if err != nil || created { t.Fatalf("Unexpected non-nil error: %#v", err) } stream, ok := obj.(*api.ImageStream) if !ok { t.Errorf("Expected image stream, got %#v", obj) } if stream.Name != "bar" { t.Errorf("Unexpected stream returned: %#v", stream) } }
func TestCreateValidationError(t *testing.T) { storage := makeTestStorage() roleBinding := &authorizationapi.RoleBinding{} ctx := kapi.WithUser(kapi.WithNamespace(kapi.NewContext(), "unittest"), &user.DefaultInfo{Name: "system:admin"}) _, err := storage.Create(ctx, roleBinding) if err == nil { t.Errorf("Expected validation error") } }
func TestCreate(t *testing.T) { _, helper := newHelper(t) storage, _ := NewREST(helper, noDefaultRegistry, &fakeSubjectAccessReviewRegistry{}) stream := validNewStream() ctx := kapi.WithUser(kapi.NewDefaultContext(), &fakeUser{}) _, err := storage.Create(ctx, stream) if err != nil { t.Fatalf("unexpected error: %v", err) } }
func TestCreateRegistryErrorSaving(t *testing.T) { fakeEtcdClient, helper := newHelper(t) fakeEtcdClient.Err = fmt.Errorf("foo") storage, _ := NewREST(helper, noDefaultRegistry, &fakeSubjectAccessReviewRegistry{}) ctx := kapi.WithUser(kapi.NewDefaultContext(), &fakeUser{}) _, err := storage.Create(ctx, &api.ImageStream{ObjectMeta: kapi.ObjectMeta{Name: "foo"}}) if err != fakeEtcdClient.Err { t.Fatalf("Unexpected non-nil error: %#v", err) } }
func TestDeleteError(t *testing.T) { bindingRegistry := &test.PolicyBindingRegistry{} bindingRegistry.Err = errors.New("Sample Error") storage := NewVirtualStorage(&test.PolicyRegistry{}, bindingRegistry, &test.ClusterPolicyRegistry{}, &test.ClusterPolicyBindingRegistry{}) ctx := kapi.WithUser(kapi.WithNamespace(kapi.NewContext(), "unittest"), &user.DefaultInfo{Name: "system:admin"}) _, err := storage.Delete(ctx, "foo", nil) if err != bindingRegistry.Err { t.Errorf("unexpected error: %v", err) } }
func TestResourceNameAllow(t *testing.T) { test := &authorizeTest{ context: kapi.WithUser(kapi.WithNamespace(kapi.NewContext(), kapi.NamespaceNone), &user.DefaultInfo{Name: "just-a-user"}), attributes: &DefaultAuthorizationAttributes{ Verb: "get", Resource: "users", ResourceName: "~", }, expectedAllowed: true, expectedReason: "allowed by cluster rule", } test.clusterPolicies = newDefaultClusterPolicies() test.clusterBindings = newDefaultClusterPolicyBindings() test.test(t) }
func TestDisallowedViewingGlobalPods(t *testing.T) { test := &authorizeTest{ context: kapi.WithUser(kapi.WithNamespace(kapi.NewContext(), kapi.NamespaceNone), &user.DefaultInfo{Name: "SomeYahoo"}), attributes: &DefaultAuthorizationAttributes{ Verb: "get", Resource: "pods", }, expectedAllowed: false, expectedReason: `User "SomeYahoo" cannot get pods`, } test.clusterPolicies = newDefaultClusterPolicies() test.clusterBindings = newDefaultClusterPolicyBindings() test.test(t) }
func TestAdminEditingGlobalDeploymentConfig(t *testing.T) { test := &authorizeTest{ context: kapi.WithUser(kapi.WithNamespace(kapi.NewContext(), kapi.NamespaceNone), &user.DefaultInfo{Name: "ClusterAdmin"}), attributes: &DefaultAuthorizationAttributes{ Verb: "update", Resource: "deploymentConfigs", }, expectedAllowed: true, expectedReason: "allowed by cluster rule", } test.clusterPolicies = newDefaultClusterPolicies() test.clusterBindings = newDefaultClusterPolicyBindings() test.test(t) }
func TestNonResourceAllow(t *testing.T) { test := &authorizeTest{ context: kapi.WithUser(kapi.NewContext(), &user.DefaultInfo{Name: "ClusterAdmin"}), attributes: &DefaultAuthorizationAttributes{ Verb: "get", NonResourceURL: true, URL: "not-specified", }, expectedAllowed: true, expectedReason: "allowed by cluster rule", } test.clusterPolicies = newDefaultClusterPolicies() test.clusterBindings = newDefaultClusterPolicyBindings() test.test(t) }
func TestHealthAllow(t *testing.T) { test := &authorizeTest{ context: kapi.WithUser(kapi.NewContext(), &user.DefaultInfo{Name: "no-one", Groups: []string{"system:unauthenticated"}}), attributes: &DefaultAuthorizationAttributes{ Verb: "get", NonResourceURL: true, URL: "/healthz", }, expectedAllowed: true, expectedReason: "allowed by cluster rule", } test.clusterPolicies = newDefaultClusterPolicies() test.clusterBindings = newDefaultClusterPolicyBindings() test.test(t) }
func TestHealthDeny(t *testing.T) { test := &authorizeTest{ context: kapi.WithUser(kapi.NewContext(), &user.DefaultInfo{Name: "no-one"}), attributes: &DefaultAuthorizationAttributes{ Verb: "get", NonResourceURL: true, URL: "/healthz", }, expectedAllowed: false, expectedReason: `User "no-one" cannot "get" on "/healthz"`, } test.clusterPolicies = newDefaultClusterPolicies() test.clusterBindings = newDefaultClusterPolicyBindings() test.test(t) }
// Create registers a given new ResourceAccessReview instance to r.registry. func (r *REST) Create(ctx kapi.Context, obj runtime.Object) (runtime.Object, error) { subjectAccessReview, ok := obj.(*authorizationapi.SubjectAccessReview) if !ok { return nil, kerrors.NewBadRequest(fmt.Sprintf("not a subjectAccessReview: %#v", obj)) } if err := kutilerrors.NewAggregate(authorizationvalidation.ValidateSubjectAccessReview(subjectAccessReview)); err != nil { return nil, err } var userToCheck user.Info if (len(subjectAccessReview.User) == 0) && (len(subjectAccessReview.Groups) == 0) { // if no user or group was specified, use the info from the context ctxUser, exists := kapi.UserFrom(ctx) if !exists { return nil, kerrors.NewBadRequest("user missing from context") } userToCheck = ctxUser } else { userToCheck = &user.DefaultInfo{ Name: subjectAccessReview.User, Groups: subjectAccessReview.Groups.List(), } } namespace := kapi.NamespaceValue(ctx) requestContext := kapi.WithUser(ctx, userToCheck) attributes := &authorizer.DefaultAuthorizationAttributes{ Verb: subjectAccessReview.Verb, Resource: subjectAccessReview.Resource, } allowed, reason, err := r.authorizer.Authorize(requestContext, attributes) if err != nil { return nil, err } response := &authorizationapi.SubjectAccessReviewResponse{ Namespace: namespace, Allowed: allowed, Reason: reason, } return response, nil }
func TestInvalidRole(t *testing.T) { test := &authorizeTest{ context: kapi.WithUser(kapi.WithNamespace(kapi.NewContext(), "mallet"), &user.DefaultInfo{Name: "Brad"}), attributes: &DefaultAuthorizationAttributes{ Verb: "get", Resource: "buildConfigs", }, expectedAllowed: false, expectedError: "unable to interpret:", } test.clusterPolicies = newDefaultClusterPolicies() test.policies = newInvalidExtensionPolicies() test.clusterBindings = newDefaultClusterPolicyBindings() test.bindings = newInvalidExtensionBindings() test.test(t) }
func TestInvalidRoleButRuleNotUsed(t *testing.T) { test := &authorizeTest{ context: kapi.WithUser(kapi.WithNamespace(kapi.NewContext(), "mallet"), &user.DefaultInfo{Name: "Brad"}), attributes: &DefaultAuthorizationAttributes{ Verb: "update", Resource: "buildConfigs", }, expectedAllowed: true, expectedReason: "allowed by rule in mallet", } test.clusterPolicies = newDefaultClusterPolicies() test.policies = newInvalidExtensionPolicies() test.clusterBindings = newDefaultClusterPolicyBindings() test.bindings = newInvalidExtensionBindings() test.test(t) }
func TestGlobalPolicyOutranksLocalPolicy(t *testing.T) { test := &authorizeTest{ context: kapi.WithUser(kapi.WithNamespace(kapi.NewContext(), "adze"), &user.DefaultInfo{Name: "ClusterAdmin"}), attributes: &DefaultAuthorizationAttributes{ Verb: "update", Resource: "roles", }, expectedAllowed: true, expectedReason: "allowed by cluster rule", } test.clusterPolicies = newDefaultClusterPolicies() test.policies = append(test.policies, newAdzePolicies()...) test.clusterBindings = newDefaultClusterPolicyBindings() test.bindings = append(test.bindings, newAdzeBindings()...) test.test(t) }
func TestLocalRightsDoNotGrantGlobalRights(t *testing.T) { test := &authorizeTest{ context: kapi.WithUser(kapi.WithNamespace(kapi.NewContext(), "backsaw"), &user.DefaultInfo{Name: "Rachel"}), attributes: &DefaultAuthorizationAttributes{ Verb: "get", Resource: "buildConfigs", }, expectedAllowed: false, expectedReason: `User "Rachel" cannot get buildConfigs in project "backsaw"`, } test.clusterPolicies = newDefaultClusterPolicies() test.policies = append(test.policies, newAdzePolicies()...) test.clusterBindings = newDefaultClusterPolicyBindings() test.bindings = append(test.bindings, newAdzeBindings()...) test.test(t) }
func TestDeleteValid(t *testing.T) { storage := makeClusterTestStorage() ctx := kapi.WithUser(kapi.WithNamespace(kapi.NewContext(), ""), &user.DefaultInfo{Name: "system:admin"}) obj, err := storage.Delete(ctx, "cluster-admins", nil) if err != nil { t.Fatalf("unexpected error: %v", err) } switch r := obj.(type) { case *kapi.Status: if r.Status != "Success" { t.Fatalf("Got back non-success status: %#v", r) } default: t.Fatalf("Got back non-status result: %v", r) } }
func TestAdminUpdateDisallowedKindInAdze(t *testing.T) { test := &authorizeTest{ context: kapi.WithUser(kapi.WithNamespace(kapi.NewContext(), "adze"), &user.DefaultInfo{Name: "Matthew"}), attributes: &DefaultAuthorizationAttributes{ Verb: "update", Resource: "roles", }, expectedAllowed: false, expectedReason: `User "Matthew" cannot update roles in project "adze"`, } test.clusterPolicies = newDefaultClusterPolicies() test.policies = newAdzePolicies() test.policies = append(test.policies, newMalletPolicies()...) test.clusterBindings = newDefaultClusterPolicyBindings() test.bindings = newAdzeBindings() test.bindings = append(test.bindings, newMalletBindings()...) test.test(t) }
func TestAdminGetAllowedKindInMallet(t *testing.T) { test := &authorizeTest{ context: kapi.WithUser(kapi.WithNamespace(kapi.NewContext(), "mallet"), &user.DefaultInfo{Name: "Matthew"}), attributes: &DefaultAuthorizationAttributes{ Verb: "get", Resource: "policies", }, expectedAllowed: true, expectedReason: "allowed by rule in mallet", } test.clusterPolicies = newDefaultClusterPolicies() test.policies = newAdzePolicies() test.policies = append(test.policies, newMalletPolicies()...) test.clusterBindings = newDefaultClusterPolicyBindings() test.bindings = newAdzeBindings() test.bindings = append(test.bindings, newMalletBindings()...) test.test(t) }
func TestViewerGetDisallowedKindInMallet(t *testing.T) { test := &authorizeTest{ context: kapi.WithUser(kapi.WithNamespace(kapi.NewContext(), "mallet"), &user.DefaultInfo{Name: "Victor"}), attributes: &DefaultAuthorizationAttributes{ Verb: "get", Resource: "policies", }, expectedAllowed: false, expectedReason: `User "Victor" cannot get policies in project "mallet"`, } test.clusterPolicies = newDefaultClusterPolicies() test.policies = newAdzePolicies() test.policies = append(test.policies, newMalletPolicies()...) test.clusterBindings = newDefaultClusterPolicyBindings() test.bindings = newAdzeBindings() test.bindings = append(test.bindings, newMalletBindings()...) test.test(t) }