mirror of https://github.com/k3s-io/k3s
Merge pull request #38968 from liggitt/anonymous-abac
Automatic merge from submit-queue (batch tested with PRs 36751, 38968) Convert * users/groups to system:authenticated group in ABAC Part of enabling anonymous auth by default in 1.6 means protecting earlier policies that did not intend to grant access to anonymous users. This modifies ABAC policies that match `user` or `group` `*` to only match authenticated users. Docs PR to update examples to use `system:authenticated` or `system:unauthenticated` groups explicitly: https://github.com/kubernetes/kubernetes.github.io/pull/1992 ```release-note ABAC policies using "user":"*" or "group":"*" to match all users or groups will only match authenticated requests. To match unauthenticated requests, ABAC policies must explicitly specify "group":"system:unauthenticated" ```pull/6/head
commit
c3aac2b938
|
@ -75,6 +75,7 @@ pkg/api/v1
|
|||
pkg/api/v1/service
|
||||
pkg/apimachinery
|
||||
pkg/apis/abac/v0
|
||||
pkg/apis/abac/v1beta1
|
||||
pkg/apis/apps/install
|
||||
pkg/apis/authentication.k8s.io/install
|
||||
pkg/apis/authentication/install
|
||||
|
|
|
@ -19,6 +19,7 @@ go_library(
|
|||
deps = [
|
||||
"//pkg/apis/abac:go_default_library",
|
||||
"//pkg/apis/meta/v1:go_default_library",
|
||||
"//pkg/auth/user:go_default_library",
|
||||
"//pkg/conversion:go_default_library",
|
||||
"//pkg/runtime:go_default_library",
|
||||
"//pkg/runtime/schema:go_default_library",
|
||||
|
@ -32,5 +33,6 @@ go_test(
|
|||
deps = [
|
||||
"//pkg/apis/abac:go_default_library",
|
||||
"//pkg/apis/abac/v0:go_default_library",
|
||||
"//pkg/auth/user:go_default_library",
|
||||
],
|
||||
)
|
||||
|
|
|
@ -18,6 +18,7 @@ package v0
|
|||
|
||||
import (
|
||||
api "k8s.io/kubernetes/pkg/apis/abac"
|
||||
"k8s.io/kubernetes/pkg/auth/user"
|
||||
"k8s.io/kubernetes/pkg/conversion"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
)
|
||||
|
@ -32,9 +33,14 @@ func addConversionFuncs(scheme *runtime.Scheme) error {
|
|||
out.Spec.Resource = in.Resource
|
||||
out.Spec.Readonly = in.Readonly
|
||||
|
||||
// In v0, unspecified user and group matches all subjects
|
||||
// In v0, unspecified user and group matches all authenticated subjects
|
||||
if len(in.User) == 0 && len(in.Group) == 0 {
|
||||
out.Spec.User = "*"
|
||||
out.Spec.Group = user.AllAuthenticated
|
||||
}
|
||||
// In v0, user or group of * matches all authenticated subjects
|
||||
if in.User == "*" || in.Group == "*" {
|
||||
out.Spec.Group = user.AllAuthenticated
|
||||
out.Spec.User = ""
|
||||
}
|
||||
|
||||
// In v0, leaving namespace empty matches all namespaces
|
||||
|
|
|
@ -22,9 +22,10 @@ import (
|
|||
|
||||
api "k8s.io/kubernetes/pkg/apis/abac"
|
||||
"k8s.io/kubernetes/pkg/apis/abac/v0"
|
||||
"k8s.io/kubernetes/pkg/auth/user"
|
||||
)
|
||||
|
||||
func TestConversion(t *testing.T) {
|
||||
func TestV0Conversion(t *testing.T) {
|
||||
testcases := map[string]struct {
|
||||
old *v0.Policy
|
||||
expected *api.Policy
|
||||
|
@ -32,7 +33,7 @@ func TestConversion(t *testing.T) {
|
|||
// a completely empty policy rule allows everything to all users
|
||||
"empty": {
|
||||
old: &v0.Policy{},
|
||||
expected: &api.Policy{Spec: api.PolicySpec{User: "*", Readonly: false, NonResourcePath: "*", Namespace: "*", Resource: "*", APIGroup: "*"}},
|
||||
expected: &api.Policy{Spec: api.PolicySpec{Group: user.AllAuthenticated, Readonly: false, NonResourcePath: "*", Namespace: "*", Resource: "*", APIGroup: "*"}},
|
||||
},
|
||||
|
||||
// specifying a user is preserved
|
||||
|
@ -47,22 +48,32 @@ func TestConversion(t *testing.T) {
|
|||
expected: &api.Policy{Spec: api.PolicySpec{Group: "mygroup", Readonly: false, NonResourcePath: "*", Namespace: "*", Resource: "*", APIGroup: "*"}},
|
||||
},
|
||||
|
||||
// specifying * for user or group maps to all authenticated subjects
|
||||
"* user": {
|
||||
old: &v0.Policy{User: "*"},
|
||||
expected: &api.Policy{Spec: api.PolicySpec{Group: user.AllAuthenticated, Readonly: false, NonResourcePath: "*", Namespace: "*", Resource: "*", APIGroup: "*"}},
|
||||
},
|
||||
"* group": {
|
||||
old: &v0.Policy{Group: "*"},
|
||||
expected: &api.Policy{Spec: api.PolicySpec{Group: user.AllAuthenticated, Readonly: false, NonResourcePath: "*", Namespace: "*", Resource: "*", APIGroup: "*"}},
|
||||
},
|
||||
|
||||
// specifying a namespace removes the * match on non-resource path
|
||||
"namespace": {
|
||||
old: &v0.Policy{Namespace: "myns"},
|
||||
expected: &api.Policy{Spec: api.PolicySpec{User: "*", Readonly: false, NonResourcePath: "", Namespace: "myns", Resource: "*", APIGroup: "*"}},
|
||||
expected: &api.Policy{Spec: api.PolicySpec{Group: user.AllAuthenticated, Readonly: false, NonResourcePath: "", Namespace: "myns", Resource: "*", APIGroup: "*"}},
|
||||
},
|
||||
|
||||
// specifying a resource removes the * match on non-resource path
|
||||
"resource": {
|
||||
old: &v0.Policy{Resource: "myresource"},
|
||||
expected: &api.Policy{Spec: api.PolicySpec{User: "*", Readonly: false, NonResourcePath: "", Namespace: "*", Resource: "myresource", APIGroup: "*"}},
|
||||
expected: &api.Policy{Spec: api.PolicySpec{Group: user.AllAuthenticated, Readonly: false, NonResourcePath: "", Namespace: "*", Resource: "myresource", APIGroup: "*"}},
|
||||
},
|
||||
|
||||
// specifying a namespace+resource removes the * match on non-resource path
|
||||
"namespace+resource": {
|
||||
old: &v0.Policy{Namespace: "myns", Resource: "myresource"},
|
||||
expected: &api.Policy{Spec: api.PolicySpec{User: "*", Readonly: false, NonResourcePath: "", Namespace: "myns", Resource: "myresource", APIGroup: "*"}},
|
||||
expected: &api.Policy{Spec: api.PolicySpec{Group: user.AllAuthenticated, Readonly: false, NonResourcePath: "", Namespace: "myns", Resource: "myresource", APIGroup: "*"}},
|
||||
},
|
||||
}
|
||||
for k, tc := range testcases {
|
||||
|
|
|
@ -5,19 +5,37 @@ licenses(["notice"])
|
|||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"conversion.go",
|
||||
"doc.go",
|
||||
"register.go",
|
||||
"types.go",
|
||||
"zz_generated.conversion.go",
|
||||
"zz_generated.deepcopy.go",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//pkg/apis/abac:go_default_library",
|
||||
"//pkg/apis/meta/v1:go_default_library",
|
||||
"//pkg/auth/user:go_default_library",
|
||||
"//pkg/conversion:go_default_library",
|
||||
"//pkg/runtime:go_default_library",
|
||||
"//pkg/runtime/schema:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_xtest",
|
||||
srcs = ["conversion_test.go"],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//pkg/apis/abac:go_default_library",
|
||||
"//pkg/apis/abac/v1beta1:go_default_library",
|
||||
"//pkg/auth/user:go_default_library",
|
||||
],
|
||||
)
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
api "k8s.io/kubernetes/pkg/apis/abac"
|
||||
"k8s.io/kubernetes/pkg/auth/user"
|
||||
"k8s.io/kubernetes/pkg/conversion"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
)
|
||||
|
||||
func addConversionFuncs(scheme *runtime.Scheme) error {
|
||||
return scheme.AddConversionFuncs(
|
||||
func(in *Policy, out *api.Policy, s conversion.Scope) error {
|
||||
// Begin by copying all fields
|
||||
if err := autoConvert_v1beta1_Policy_To_abac_Policy(in, out, s); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// In v1beta1, * user or group maps to all authenticated subjects
|
||||
if in.Spec.User == "*" || in.Spec.Group == "*" {
|
||||
out.Spec.Group = user.AllAuthenticated
|
||||
out.Spec.User = ""
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
)
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1beta1_test
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
api "k8s.io/kubernetes/pkg/apis/abac"
|
||||
"k8s.io/kubernetes/pkg/apis/abac/v1beta1"
|
||||
"k8s.io/kubernetes/pkg/auth/user"
|
||||
)
|
||||
|
||||
func TestV1Beta1Conversion(t *testing.T) {
|
||||
testcases := map[string]struct {
|
||||
old *v1beta1.Policy
|
||||
expected *api.Policy
|
||||
}{
|
||||
// specifying a user is preserved
|
||||
"user": {
|
||||
old: &v1beta1.Policy{Spec: v1beta1.PolicySpec{User: "bob"}},
|
||||
expected: &api.Policy{Spec: api.PolicySpec{User: "bob"}},
|
||||
},
|
||||
|
||||
// specifying a group is preserved
|
||||
"group": {
|
||||
old: &v1beta1.Policy{Spec: v1beta1.PolicySpec{Group: "mygroup"}},
|
||||
expected: &api.Policy{Spec: api.PolicySpec{Group: "mygroup"}},
|
||||
},
|
||||
|
||||
// specifying * for user or group maps to all authenticated subjects
|
||||
"* user": {
|
||||
old: &v1beta1.Policy{Spec: v1beta1.PolicySpec{User: "*"}},
|
||||
expected: &api.Policy{Spec: api.PolicySpec{Group: user.AllAuthenticated}},
|
||||
},
|
||||
"* group": {
|
||||
old: &v1beta1.Policy{Spec: v1beta1.PolicySpec{Group: "*"}},
|
||||
expected: &api.Policy{Spec: api.PolicySpec{Group: user.AllAuthenticated}},
|
||||
},
|
||||
}
|
||||
for k, tc := range testcases {
|
||||
internal := &api.Policy{}
|
||||
if err := api.Scheme.Convert(tc.old, internal, nil); err != nil {
|
||||
t.Errorf("%s: unexpected error: %v", k, err)
|
||||
}
|
||||
if !reflect.DeepEqual(internal, tc.expected) {
|
||||
t.Errorf("%s: expected\n\t%#v, got \n\t%#v", k, tc.expected, internal)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// +k8s:deepcopy-gen=package,register
|
||||
// +k8s:conversion-gen=k8s.io/kubernetes/pkg/apis/abac
|
||||
// +k8s:openapi-gen=true
|
||||
// +k8s:defaulter-gen=TypeMeta
|
||||
|
||||
// +groupName=abac.authorization.kubernetes.io
|
||||
package v1beta1 // import "k8s.io/kubernetes/pkg/apis/abac/v1beta1"
|
|
@ -33,10 +33,14 @@ func init() {
|
|||
// Programmer error.
|
||||
panic(err)
|
||||
}
|
||||
if err := addConversionFuncs(api.Scheme); err != nil {
|
||||
// Programmer error.
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
|
||||
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes, addConversionFuncs)
|
||||
AddToScheme = SchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// This file was autogenerated by conversion-gen. Do not edit it manually!
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
abac "k8s.io/kubernetes/pkg/apis/abac"
|
||||
conversion "k8s.io/kubernetes/pkg/conversion"
|
||||
runtime "k8s.io/kubernetes/pkg/runtime"
|
||||
)
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(RegisterConversions)
|
||||
}
|
||||
|
||||
// RegisterConversions adds conversion functions to the given scheme.
|
||||
// Public to allow building arbitrary schemes.
|
||||
func RegisterConversions(scheme *runtime.Scheme) error {
|
||||
return scheme.AddGeneratedConversionFuncs(
|
||||
Convert_v1beta1_Policy_To_abac_Policy,
|
||||
Convert_abac_Policy_To_v1beta1_Policy,
|
||||
Convert_v1beta1_PolicySpec_To_abac_PolicySpec,
|
||||
Convert_abac_PolicySpec_To_v1beta1_PolicySpec,
|
||||
)
|
||||
}
|
||||
|
||||
func autoConvert_v1beta1_Policy_To_abac_Policy(in *Policy, out *abac.Policy, s conversion.Scope) error {
|
||||
if err := Convert_v1beta1_PolicySpec_To_abac_PolicySpec(&in.Spec, &out.Spec, s); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v1beta1_Policy_To_abac_Policy(in *Policy, out *abac.Policy, s conversion.Scope) error {
|
||||
return autoConvert_v1beta1_Policy_To_abac_Policy(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_abac_Policy_To_v1beta1_Policy(in *abac.Policy, out *Policy, s conversion.Scope) error {
|
||||
if err := Convert_abac_PolicySpec_To_v1beta1_PolicySpec(&in.Spec, &out.Spec, s); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_abac_Policy_To_v1beta1_Policy(in *abac.Policy, out *Policy, s conversion.Scope) error {
|
||||
return autoConvert_abac_Policy_To_v1beta1_Policy(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1beta1_PolicySpec_To_abac_PolicySpec(in *PolicySpec, out *abac.PolicySpec, s conversion.Scope) error {
|
||||
out.User = in.User
|
||||
out.Group = in.Group
|
||||
out.Readonly = in.Readonly
|
||||
out.APIGroup = in.APIGroup
|
||||
out.Resource = in.Resource
|
||||
out.Namespace = in.Namespace
|
||||
out.NonResourcePath = in.NonResourcePath
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v1beta1_PolicySpec_To_abac_PolicySpec(in *PolicySpec, out *abac.PolicySpec, s conversion.Scope) error {
|
||||
return autoConvert_v1beta1_PolicySpec_To_abac_PolicySpec(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_abac_PolicySpec_To_v1beta1_PolicySpec(in *abac.PolicySpec, out *PolicySpec, s conversion.Scope) error {
|
||||
out.User = in.User
|
||||
out.Group = in.Group
|
||||
out.Readonly = in.Readonly
|
||||
out.APIGroup = in.APIGroup
|
||||
out.Resource = in.Resource
|
||||
out.Namespace = in.Namespace
|
||||
out.NonResourcePath = in.NonResourcePath
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_abac_PolicySpec_To_v1beta1_PolicySpec(in *abac.PolicySpec, out *PolicySpec, s conversion.Scope) error {
|
||||
return autoConvert_abac_PolicySpec_To_v1beta1_PolicySpec(in, out, s)
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// This file was autogenerated by deepcopy-gen. Do not edit it manually!
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
conversion "k8s.io/kubernetes/pkg/conversion"
|
||||
runtime "k8s.io/kubernetes/pkg/runtime"
|
||||
reflect "reflect"
|
||||
)
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(RegisterDeepCopies)
|
||||
}
|
||||
|
||||
// RegisterDeepCopies adds deep-copy functions to the given scheme. Public
|
||||
// to allow building arbitrary schemes.
|
||||
func RegisterDeepCopies(scheme *runtime.Scheme) error {
|
||||
return scheme.AddGeneratedDeepCopyFuncs(
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1beta1_Policy, InType: reflect.TypeOf(&Policy{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1beta1_PolicySpec, InType: reflect.TypeOf(&PolicySpec{})},
|
||||
)
|
||||
}
|
||||
|
||||
func DeepCopy_v1beta1_Policy(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*Policy)
|
||||
out := out.(*Policy)
|
||||
out.TypeMeta = in.TypeMeta
|
||||
out.Spec = in.Spec
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_v1beta1_PolicySpec(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*PolicySpec)
|
||||
out := out.(*PolicySpec)
|
||||
out.User = in.User
|
||||
out.Group = in.Group
|
||||
out.Readonly = in.Readonly
|
||||
out.APIGroup = in.APIGroup
|
||||
out.Resource = in.Resource
|
||||
out.Namespace = in.Namespace
|
||||
out.NonResourcePath = in.NonResourcePath
|
||||
return nil
|
||||
}
|
||||
}
|
|
@ -73,9 +73,11 @@ func TestAuthorizeV0(t *testing.T) {
|
|||
t.Fatalf("unable to read policy file: %v", err)
|
||||
}
|
||||
|
||||
uScheduler := user.DefaultInfo{Name: "scheduler", UID: "uid1"}
|
||||
uAlice := user.DefaultInfo{Name: "alice", UID: "uid3"}
|
||||
uChuck := user.DefaultInfo{Name: "chuck", UID: "uid5"}
|
||||
authenticatedGroup := []string{user.AllAuthenticated}
|
||||
|
||||
uScheduler := user.DefaultInfo{Name: "scheduler", UID: "uid1", Groups: authenticatedGroup}
|
||||
uAlice := user.DefaultInfo{Name: "alice", UID: "uid3", Groups: authenticatedGroup}
|
||||
uChuck := user.DefaultInfo{Name: "chuck", UID: "uid5", Groups: authenticatedGroup}
|
||||
|
||||
testCases := []struct {
|
||||
User user.DefaultInfo
|
||||
|
@ -163,12 +165,14 @@ func TestAuthorizeV1beta1(t *testing.T) {
|
|||
t.Fatalf("unable to read policy file: %v", err)
|
||||
}
|
||||
|
||||
uScheduler := user.DefaultInfo{Name: "scheduler", UID: "uid1"}
|
||||
uAlice := user.DefaultInfo{Name: "alice", UID: "uid3"}
|
||||
uChuck := user.DefaultInfo{Name: "chuck", UID: "uid5"}
|
||||
uDebbie := user.DefaultInfo{Name: "debbie", UID: "uid6"}
|
||||
uNoResource := user.DefaultInfo{Name: "noresource", UID: "uid7"}
|
||||
uAPIGroup := user.DefaultInfo{Name: "apigroupuser", UID: "uid8"}
|
||||
authenticatedGroup := []string{user.AllAuthenticated}
|
||||
|
||||
uScheduler := user.DefaultInfo{Name: "scheduler", UID: "uid1", Groups: authenticatedGroup}
|
||||
uAlice := user.DefaultInfo{Name: "alice", UID: "uid3", Groups: authenticatedGroup}
|
||||
uChuck := user.DefaultInfo{Name: "chuck", UID: "uid5", Groups: authenticatedGroup}
|
||||
uDebbie := user.DefaultInfo{Name: "debbie", UID: "uid6", Groups: authenticatedGroup}
|
||||
uNoResource := user.DefaultInfo{Name: "noresource", UID: "uid7", Groups: authenticatedGroup}
|
||||
uAPIGroup := user.DefaultInfo{Name: "apigroupuser", UID: "uid8", Groups: authenticatedGroup}
|
||||
|
||||
testCases := []struct {
|
||||
User user.DefaultInfo
|
||||
|
@ -263,16 +267,32 @@ func TestSubjectMatches(t *testing.T) {
|
|||
Policy runtime.Object
|
||||
ExpectMatch bool
|
||||
}{
|
||||
"v0 empty policy matches unauthed user": {
|
||||
User: user.DefaultInfo{},
|
||||
"v0 empty policy does not match unauthed user": {
|
||||
User: user.DefaultInfo{Name: "system:anonymous", Groups: []string{"system:unauthenticated"}},
|
||||
Policy: &v0.Policy{
|
||||
User: "",
|
||||
Group: "",
|
||||
},
|
||||
ExpectMatch: true,
|
||||
ExpectMatch: false,
|
||||
},
|
||||
"v0 * user policy does not match unauthed user": {
|
||||
User: user.DefaultInfo{Name: "system:anonymous", Groups: []string{"system:unauthenticated"}},
|
||||
Policy: &v0.Policy{
|
||||
User: "*",
|
||||
Group: "",
|
||||
},
|
||||
ExpectMatch: false,
|
||||
},
|
||||
"v0 * group policy does not match unauthed user": {
|
||||
User: user.DefaultInfo{Name: "system:anonymous", Groups: []string{"system:unauthenticated"}},
|
||||
Policy: &v0.Policy{
|
||||
User: "",
|
||||
Group: "*",
|
||||
},
|
||||
ExpectMatch: false,
|
||||
},
|
||||
"v0 empty policy matches authed user": {
|
||||
User: user.DefaultInfo{Name: "Foo"},
|
||||
User: user.DefaultInfo{Name: "Foo", Groups: []string{user.AllAuthenticated}},
|
||||
Policy: &v0.Policy{
|
||||
User: "",
|
||||
Group: "",
|
||||
|
@ -280,7 +300,7 @@ func TestSubjectMatches(t *testing.T) {
|
|||
ExpectMatch: true,
|
||||
},
|
||||
"v0 empty policy matches authed user with groups": {
|
||||
User: user.DefaultInfo{Name: "Foo", Groups: []string{"a", "b"}},
|
||||
User: user.DefaultInfo{Name: "Foo", Groups: []string{"a", "b", user.AllAuthenticated}},
|
||||
Policy: &v0.Policy{
|
||||
User: "",
|
||||
Group: "",
|
||||
|
@ -289,7 +309,7 @@ func TestSubjectMatches(t *testing.T) {
|
|||
},
|
||||
|
||||
"v0 user policy does not match unauthed user": {
|
||||
User: user.DefaultInfo{},
|
||||
User: user.DefaultInfo{Name: "system:anonymous", Groups: []string{"system:unauthenticated"}},
|
||||
Policy: &v0.Policy{
|
||||
User: "Foo",
|
||||
Group: "",
|
||||
|
@ -297,7 +317,7 @@ func TestSubjectMatches(t *testing.T) {
|
|||
ExpectMatch: false,
|
||||
},
|
||||
"v0 user policy does not match different user": {
|
||||
User: user.DefaultInfo{Name: "Bar"},
|
||||
User: user.DefaultInfo{Name: "Bar", Groups: []string{user.AllAuthenticated}},
|
||||
Policy: &v0.Policy{
|
||||
User: "Foo",
|
||||
Group: "",
|
||||
|
@ -305,7 +325,7 @@ func TestSubjectMatches(t *testing.T) {
|
|||
ExpectMatch: false,
|
||||
},
|
||||
"v0 user policy is case-sensitive": {
|
||||
User: user.DefaultInfo{Name: "foo"},
|
||||
User: user.DefaultInfo{Name: "foo", Groups: []string{user.AllAuthenticated}},
|
||||
Policy: &v0.Policy{
|
||||
User: "Foo",
|
||||
Group: "",
|
||||
|
@ -313,7 +333,7 @@ func TestSubjectMatches(t *testing.T) {
|
|||
ExpectMatch: false,
|
||||
},
|
||||
"v0 user policy does not match substring": {
|
||||
User: user.DefaultInfo{Name: "FooBar"},
|
||||
User: user.DefaultInfo{Name: "FooBar", Groups: []string{user.AllAuthenticated}},
|
||||
Policy: &v0.Policy{
|
||||
User: "Foo",
|
||||
Group: "",
|
||||
|
@ -321,7 +341,7 @@ func TestSubjectMatches(t *testing.T) {
|
|||
ExpectMatch: false,
|
||||
},
|
||||
"v0 user policy matches username": {
|
||||
User: user.DefaultInfo{Name: "Foo"},
|
||||
User: user.DefaultInfo{Name: "Foo", Groups: []string{user.AllAuthenticated}},
|
||||
Policy: &v0.Policy{
|
||||
User: "Foo",
|
||||
Group: "",
|
||||
|
@ -330,7 +350,7 @@ func TestSubjectMatches(t *testing.T) {
|
|||
},
|
||||
|
||||
"v0 group policy does not match unauthed user": {
|
||||
User: user.DefaultInfo{},
|
||||
User: user.DefaultInfo{Name: "system:anonymous", Groups: []string{"system:unauthenticated"}},
|
||||
Policy: &v0.Policy{
|
||||
User: "",
|
||||
Group: "Foo",
|
||||
|
@ -338,7 +358,7 @@ func TestSubjectMatches(t *testing.T) {
|
|||
ExpectMatch: false,
|
||||
},
|
||||
"v0 group policy does not match user in different group": {
|
||||
User: user.DefaultInfo{Name: "FooBar", Groups: []string{"B"}},
|
||||
User: user.DefaultInfo{Name: "FooBar", Groups: []string{"B", user.AllAuthenticated}},
|
||||
Policy: &v0.Policy{
|
||||
User: "",
|
||||
Group: "A",
|
||||
|
@ -346,7 +366,7 @@ func TestSubjectMatches(t *testing.T) {
|
|||
ExpectMatch: false,
|
||||
},
|
||||
"v0 group policy is case-sensitive": {
|
||||
User: user.DefaultInfo{Name: "Foo", Groups: []string{"A", "B", "C"}},
|
||||
User: user.DefaultInfo{Name: "Foo", Groups: []string{"A", "B", "C", user.AllAuthenticated}},
|
||||
Policy: &v0.Policy{
|
||||
User: "",
|
||||
Group: "b",
|
||||
|
@ -354,7 +374,7 @@ func TestSubjectMatches(t *testing.T) {
|
|||
ExpectMatch: false,
|
||||
},
|
||||
"v0 group policy does not match substring": {
|
||||
User: user.DefaultInfo{Name: "Foo", Groups: []string{"A", "BBB", "C"}},
|
||||
User: user.DefaultInfo{Name: "Foo", Groups: []string{"A", "BBB", "C", user.AllAuthenticated}},
|
||||
Policy: &v0.Policy{
|
||||
User: "",
|
||||
Group: "B",
|
||||
|
@ -362,7 +382,7 @@ func TestSubjectMatches(t *testing.T) {
|
|||
ExpectMatch: false,
|
||||
},
|
||||
"v0 group policy matches user in group": {
|
||||
User: user.DefaultInfo{Name: "Foo", Groups: []string{"A", "B", "C"}},
|
||||
User: user.DefaultInfo{Name: "Foo", Groups: []string{"A", "B", "C", user.AllAuthenticated}},
|
||||
Policy: &v0.Policy{
|
||||
User: "",
|
||||
Group: "B",
|
||||
|
@ -371,7 +391,7 @@ func TestSubjectMatches(t *testing.T) {
|
|||
},
|
||||
|
||||
"v0 user and group policy requires user match": {
|
||||
User: user.DefaultInfo{Name: "Bar", Groups: []string{"A", "B", "C"}},
|
||||
User: user.DefaultInfo{Name: "Bar", Groups: []string{"A", "B", "C", user.AllAuthenticated}},
|
||||
Policy: &v0.Policy{
|
||||
User: "Foo",
|
||||
Group: "B",
|
||||
|
@ -379,7 +399,7 @@ func TestSubjectMatches(t *testing.T) {
|
|||
ExpectMatch: false,
|
||||
},
|
||||
"v0 user and group policy requires group match": {
|
||||
User: user.DefaultInfo{Name: "Foo", Groups: []string{"A", "B", "C"}},
|
||||
User: user.DefaultInfo{Name: "Foo", Groups: []string{"A", "B", "C", user.AllAuthenticated}},
|
||||
Policy: &v0.Policy{
|
||||
User: "Foo",
|
||||
Group: "D",
|
||||
|
@ -387,7 +407,7 @@ func TestSubjectMatches(t *testing.T) {
|
|||
ExpectMatch: false,
|
||||
},
|
||||
"v0 user and group policy matches": {
|
||||
User: user.DefaultInfo{Name: "Foo", Groups: []string{"A", "B", "C"}},
|
||||
User: user.DefaultInfo{Name: "Foo", Groups: []string{"A", "B", "C", user.AllAuthenticated}},
|
||||
Policy: &v0.Policy{
|
||||
User: "Foo",
|
||||
Group: "B",
|
||||
|
@ -396,7 +416,7 @@ func TestSubjectMatches(t *testing.T) {
|
|||
},
|
||||
|
||||
"v1 empty policy does not match unauthed user": {
|
||||
User: user.DefaultInfo{},
|
||||
User: user.DefaultInfo{Name: "system:anonymous", Groups: []string{"system:unauthenticated"}},
|
||||
Policy: &v1beta1.Policy{
|
||||
Spec: v1beta1.PolicySpec{
|
||||
User: "",
|
||||
|
@ -405,8 +425,28 @@ func TestSubjectMatches(t *testing.T) {
|
|||
},
|
||||
ExpectMatch: false,
|
||||
},
|
||||
"v1 * user policy does not match unauthed user": {
|
||||
User: user.DefaultInfo{Name: "system:anonymous", Groups: []string{"system:unauthenticated"}},
|
||||
Policy: &v1beta1.Policy{
|
||||
Spec: v1beta1.PolicySpec{
|
||||
User: "*",
|
||||
Group: "",
|
||||
},
|
||||
},
|
||||
ExpectMatch: false,
|
||||
},
|
||||
"v1 * group policy does not match unauthed user": {
|
||||
User: user.DefaultInfo{Name: "system:anonymous", Groups: []string{"system:unauthenticated"}},
|
||||
Policy: &v1beta1.Policy{
|
||||
Spec: v1beta1.PolicySpec{
|
||||
User: "",
|
||||
Group: "*",
|
||||
},
|
||||
},
|
||||
ExpectMatch: false,
|
||||
},
|
||||
"v1 empty policy does not match authed user": {
|
||||
User: user.DefaultInfo{Name: "Foo"},
|
||||
User: user.DefaultInfo{Name: "Foo", Groups: []string{user.AllAuthenticated}},
|
||||
Policy: &v1beta1.Policy{
|
||||
Spec: v1beta1.PolicySpec{
|
||||
User: "",
|
||||
|
@ -416,7 +456,7 @@ func TestSubjectMatches(t *testing.T) {
|
|||
ExpectMatch: false,
|
||||
},
|
||||
"v1 empty policy does not match authed user with groups": {
|
||||
User: user.DefaultInfo{Name: "Foo", Groups: []string{"a", "b"}},
|
||||
User: user.DefaultInfo{Name: "Foo", Groups: []string{"a", "b", user.AllAuthenticated}},
|
||||
Policy: &v1beta1.Policy{
|
||||
Spec: v1beta1.PolicySpec{
|
||||
User: "",
|
||||
|
@ -427,7 +467,7 @@ func TestSubjectMatches(t *testing.T) {
|
|||
},
|
||||
|
||||
"v1 user policy does not match unauthed user": {
|
||||
User: user.DefaultInfo{},
|
||||
User: user.DefaultInfo{Name: "system:anonymous", Groups: []string{"system:unauthenticated"}},
|
||||
Policy: &v1beta1.Policy{
|
||||
Spec: v1beta1.PolicySpec{
|
||||
User: "Foo",
|
||||
|
@ -437,7 +477,7 @@ func TestSubjectMatches(t *testing.T) {
|
|||
ExpectMatch: false,
|
||||
},
|
||||
"v1 user policy does not match different user": {
|
||||
User: user.DefaultInfo{Name: "Bar"},
|
||||
User: user.DefaultInfo{Name: "Bar", Groups: []string{user.AllAuthenticated}},
|
||||
Policy: &v1beta1.Policy{
|
||||
Spec: v1beta1.PolicySpec{
|
||||
User: "Foo",
|
||||
|
@ -447,7 +487,7 @@ func TestSubjectMatches(t *testing.T) {
|
|||
ExpectMatch: false,
|
||||
},
|
||||
"v1 user policy is case-sensitive": {
|
||||
User: user.DefaultInfo{Name: "foo"},
|
||||
User: user.DefaultInfo{Name: "foo", Groups: []string{user.AllAuthenticated}},
|
||||
Policy: &v1beta1.Policy{
|
||||
Spec: v1beta1.PolicySpec{
|
||||
User: "Foo",
|
||||
|
@ -457,7 +497,7 @@ func TestSubjectMatches(t *testing.T) {
|
|||
ExpectMatch: false,
|
||||
},
|
||||
"v1 user policy does not match substring": {
|
||||
User: user.DefaultInfo{Name: "FooBar"},
|
||||
User: user.DefaultInfo{Name: "FooBar", Groups: []string{user.AllAuthenticated}},
|
||||
Policy: &v1beta1.Policy{
|
||||
Spec: v1beta1.PolicySpec{
|
||||
User: "Foo",
|
||||
|
@ -467,7 +507,7 @@ func TestSubjectMatches(t *testing.T) {
|
|||
ExpectMatch: false,
|
||||
},
|
||||
"v1 user policy matches username": {
|
||||
User: user.DefaultInfo{Name: "Foo"},
|
||||
User: user.DefaultInfo{Name: "Foo", Groups: []string{user.AllAuthenticated}},
|
||||
Policy: &v1beta1.Policy{
|
||||
Spec: v1beta1.PolicySpec{
|
||||
User: "Foo",
|
||||
|
@ -478,7 +518,7 @@ func TestSubjectMatches(t *testing.T) {
|
|||
},
|
||||
|
||||
"v1 group policy does not match unauthed user": {
|
||||
User: user.DefaultInfo{},
|
||||
User: user.DefaultInfo{Name: "system:anonymous", Groups: []string{"system:unauthenticated"}},
|
||||
Policy: &v1beta1.Policy{
|
||||
Spec: v1beta1.PolicySpec{
|
||||
User: "",
|
||||
|
@ -488,7 +528,7 @@ func TestSubjectMatches(t *testing.T) {
|
|||
ExpectMatch: false,
|
||||
},
|
||||
"v1 group policy does not match user in different group": {
|
||||
User: user.DefaultInfo{Name: "FooBar", Groups: []string{"B"}},
|
||||
User: user.DefaultInfo{Name: "FooBar", Groups: []string{"B", user.AllAuthenticated}},
|
||||
Policy: &v1beta1.Policy{
|
||||
Spec: v1beta1.PolicySpec{
|
||||
User: "",
|
||||
|
@ -498,7 +538,7 @@ func TestSubjectMatches(t *testing.T) {
|
|||
ExpectMatch: false,
|
||||
},
|
||||
"v1 group policy is case-sensitive": {
|
||||
User: user.DefaultInfo{Name: "Foo", Groups: []string{"A", "B", "C"}},
|
||||
User: user.DefaultInfo{Name: "Foo", Groups: []string{"A", "B", "C", user.AllAuthenticated}},
|
||||
Policy: &v1beta1.Policy{
|
||||
Spec: v1beta1.PolicySpec{
|
||||
User: "",
|
||||
|
@ -508,7 +548,7 @@ func TestSubjectMatches(t *testing.T) {
|
|||
ExpectMatch: false,
|
||||
},
|
||||
"v1 group policy does not match substring": {
|
||||
User: user.DefaultInfo{Name: "Foo", Groups: []string{"A", "BBB", "C"}},
|
||||
User: user.DefaultInfo{Name: "Foo", Groups: []string{"A", "BBB", "C", user.AllAuthenticated}},
|
||||
Policy: &v1beta1.Policy{
|
||||
Spec: v1beta1.PolicySpec{
|
||||
User: "",
|
||||
|
@ -518,7 +558,7 @@ func TestSubjectMatches(t *testing.T) {
|
|||
ExpectMatch: false,
|
||||
},
|
||||
"v1 group policy matches user in group": {
|
||||
User: user.DefaultInfo{Name: "Foo", Groups: []string{"A", "B", "C"}},
|
||||
User: user.DefaultInfo{Name: "Foo", Groups: []string{"A", "B", "C", user.AllAuthenticated}},
|
||||
Policy: &v1beta1.Policy{
|
||||
Spec: v1beta1.PolicySpec{
|
||||
User: "",
|
||||
|
@ -529,7 +569,7 @@ func TestSubjectMatches(t *testing.T) {
|
|||
},
|
||||
|
||||
"v1 user and group policy requires user match": {
|
||||
User: user.DefaultInfo{Name: "Bar", Groups: []string{"A", "B", "C"}},
|
||||
User: user.DefaultInfo{Name: "Bar", Groups: []string{"A", "B", "C", user.AllAuthenticated}},
|
||||
Policy: &v1beta1.Policy{
|
||||
Spec: v1beta1.PolicySpec{
|
||||
User: "Foo",
|
||||
|
@ -539,7 +579,7 @@ func TestSubjectMatches(t *testing.T) {
|
|||
ExpectMatch: false,
|
||||
},
|
||||
"v1 user and group policy requires group match": {
|
||||
User: user.DefaultInfo{Name: "Foo", Groups: []string{"A", "B", "C"}},
|
||||
User: user.DefaultInfo{Name: "Foo", Groups: []string{"A", "B", "C", user.AllAuthenticated}},
|
||||
Policy: &v1beta1.Policy{
|
||||
Spec: v1beta1.PolicySpec{
|
||||
User: "Foo",
|
||||
|
@ -549,7 +589,7 @@ func TestSubjectMatches(t *testing.T) {
|
|||
ExpectMatch: false,
|
||||
},
|
||||
"v1 user and group policy matches": {
|
||||
User: user.DefaultInfo{Name: "Foo", Groups: []string{"A", "B", "C"}},
|
||||
User: user.DefaultInfo{Name: "Foo", Groups: []string{"A", "B", "C", user.AllAuthenticated}},
|
||||
Policy: &v1beta1.Policy{
|
||||
Spec: v1beta1.PolicySpec{
|
||||
User: "Foo",
|
||||
|
@ -600,20 +640,18 @@ func TestPolicy(t *testing.T) {
|
|||
matches bool
|
||||
name string
|
||||
}{
|
||||
// v0
|
||||
{
|
||||
policy: &v0.Policy{},
|
||||
attr: authorizer.AttributesRecord{},
|
||||
matches: true,
|
||||
name: "v0 null",
|
||||
},
|
||||
|
||||
// v0 mismatches
|
||||
{
|
||||
policy: &v0.Policy{
|
||||
Readonly: true,
|
||||
},
|
||||
attr: authorizer.AttributesRecord{},
|
||||
attr: authorizer.AttributesRecord{
|
||||
User: &user.DefaultInfo{
|
||||
Name: "foo",
|
||||
Groups: []string{user.AllAuthenticated},
|
||||
},
|
||||
Verb: "create",
|
||||
},
|
||||
matches: false,
|
||||
name: "v0 read-only mismatch",
|
||||
},
|
||||
|
@ -623,7 +661,8 @@ func TestPolicy(t *testing.T) {
|
|||
},
|
||||
attr: authorizer.AttributesRecord{
|
||||
User: &user.DefaultInfo{
|
||||
Name: "bar",
|
||||
Name: "bar",
|
||||
Groups: []string{user.AllAuthenticated},
|
||||
},
|
||||
},
|
||||
matches: false,
|
||||
|
@ -634,6 +673,10 @@ func TestPolicy(t *testing.T) {
|
|||
Resource: "foo",
|
||||
},
|
||||
attr: authorizer.AttributesRecord{
|
||||
User: &user.DefaultInfo{
|
||||
Name: "foo",
|
||||
Groups: []string{user.AllAuthenticated},
|
||||
},
|
||||
Resource: "bar",
|
||||
ResourceRequest: true,
|
||||
},
|
||||
|
@ -648,7 +691,8 @@ func TestPolicy(t *testing.T) {
|
|||
},
|
||||
attr: authorizer.AttributesRecord{
|
||||
User: &user.DefaultInfo{
|
||||
Name: "foo",
|
||||
Name: "foo",
|
||||
Groups: []string{user.AllAuthenticated},
|
||||
},
|
||||
Resource: "foo",
|
||||
Namespace: "foo",
|
||||
|
@ -660,8 +704,14 @@ func TestPolicy(t *testing.T) {
|
|||
|
||||
// v0 matches
|
||||
{
|
||||
policy: &v0.Policy{},
|
||||
attr: authorizer.AttributesRecord{ResourceRequest: true},
|
||||
policy: &v0.Policy{},
|
||||
attr: authorizer.AttributesRecord{
|
||||
User: &user.DefaultInfo{
|
||||
Name: "foo",
|
||||
Groups: []string{user.AllAuthenticated},
|
||||
},
|
||||
ResourceRequest: true,
|
||||
},
|
||||
matches: true,
|
||||
name: "v0 null resource",
|
||||
},
|
||||
|
@ -670,6 +720,10 @@ func TestPolicy(t *testing.T) {
|
|||
Readonly: true,
|
||||
},
|
||||
attr: authorizer.AttributesRecord{
|
||||
User: &user.DefaultInfo{
|
||||
Name: "foo",
|
||||
Groups: []string{user.AllAuthenticated},
|
||||
},
|
||||
Verb: "get",
|
||||
},
|
||||
matches: true,
|
||||
|
@ -681,7 +735,8 @@ func TestPolicy(t *testing.T) {
|
|||
},
|
||||
attr: authorizer.AttributesRecord{
|
||||
User: &user.DefaultInfo{
|
||||
Name: "foo",
|
||||
Name: "foo",
|
||||
Groups: []string{user.AllAuthenticated},
|
||||
},
|
||||
},
|
||||
matches: true,
|
||||
|
@ -692,6 +747,10 @@ func TestPolicy(t *testing.T) {
|
|||
Resource: "foo",
|
||||
},
|
||||
attr: authorizer.AttributesRecord{
|
||||
User: &user.DefaultInfo{
|
||||
Name: "foo",
|
||||
Groups: []string{user.AllAuthenticated},
|
||||
},
|
||||
Resource: "foo",
|
||||
ResourceRequest: true,
|
||||
},
|
||||
|
@ -703,6 +762,10 @@ func TestPolicy(t *testing.T) {
|
|||
{
|
||||
policy: &v1beta1.Policy{},
|
||||
attr: authorizer.AttributesRecord{
|
||||
User: &user.DefaultInfo{
|
||||
Name: "foo",
|
||||
Groups: []string{user.AllAuthenticated},
|
||||
},
|
||||
ResourceRequest: true,
|
||||
},
|
||||
matches: false,
|
||||
|
@ -716,7 +779,8 @@ func TestPolicy(t *testing.T) {
|
|||
},
|
||||
attr: authorizer.AttributesRecord{
|
||||
User: &user.DefaultInfo{
|
||||
Name: "bar",
|
||||
Name: "bar",
|
||||
Groups: []string{user.AllAuthenticated},
|
||||
},
|
||||
ResourceRequest: true,
|
||||
},
|
||||
|
@ -731,6 +795,10 @@ func TestPolicy(t *testing.T) {
|
|||
},
|
||||
},
|
||||
attr: authorizer.AttributesRecord{
|
||||
User: &user.DefaultInfo{
|
||||
Name: "foo",
|
||||
Groups: []string{user.AllAuthenticated},
|
||||
},
|
||||
ResourceRequest: true,
|
||||
},
|
||||
matches: false,
|
||||
|
@ -744,6 +812,10 @@ func TestPolicy(t *testing.T) {
|
|||
},
|
||||
},
|
||||
attr: authorizer.AttributesRecord{
|
||||
User: &user.DefaultInfo{
|
||||
Name: "foo",
|
||||
Groups: []string{user.AllAuthenticated},
|
||||
},
|
||||
Resource: "bar",
|
||||
ResourceRequest: true,
|
||||
},
|
||||
|
@ -760,7 +832,8 @@ func TestPolicy(t *testing.T) {
|
|||
},
|
||||
attr: authorizer.AttributesRecord{
|
||||
User: &user.DefaultInfo{
|
||||
Name: "foo",
|
||||
Name: "foo",
|
||||
Groups: []string{user.AllAuthenticated},
|
||||
},
|
||||
Namespace: "bar",
|
||||
Resource: "baz",
|
||||
|
@ -777,6 +850,10 @@ func TestPolicy(t *testing.T) {
|
|||
},
|
||||
},
|
||||
attr: authorizer.AttributesRecord{
|
||||
User: &user.DefaultInfo{
|
||||
Name: "foo",
|
||||
Groups: []string{user.AllAuthenticated},
|
||||
},
|
||||
Path: "/api2",
|
||||
ResourceRequest: false,
|
||||
},
|
||||
|
@ -791,6 +868,10 @@ func TestPolicy(t *testing.T) {
|
|||
},
|
||||
},
|
||||
attr: authorizer.AttributesRecord{
|
||||
User: &user.DefaultInfo{
|
||||
Name: "foo",
|
||||
Groups: []string{user.AllAuthenticated},
|
||||
},
|
||||
Path: "/api2/foo",
|
||||
ResourceRequest: false,
|
||||
},
|
||||
|
@ -807,7 +888,8 @@ func TestPolicy(t *testing.T) {
|
|||
},
|
||||
attr: authorizer.AttributesRecord{
|
||||
User: &user.DefaultInfo{
|
||||
Name: "foo",
|
||||
Name: "foo",
|
||||
Groups: []string{user.AllAuthenticated},
|
||||
},
|
||||
ResourceRequest: true,
|
||||
},
|
||||
|
@ -821,6 +903,10 @@ func TestPolicy(t *testing.T) {
|
|||
},
|
||||
},
|
||||
attr: authorizer.AttributesRecord{
|
||||
User: &user.DefaultInfo{
|
||||
Name: "foo",
|
||||
Groups: []string{user.AllAuthenticated},
|
||||
},
|
||||
ResourceRequest: true,
|
||||
},
|
||||
matches: true,
|
||||
|
@ -835,7 +921,7 @@ func TestPolicy(t *testing.T) {
|
|||
attr: authorizer.AttributesRecord{
|
||||
User: &user.DefaultInfo{
|
||||
Name: "foo",
|
||||
Groups: []string{"bar"},
|
||||
Groups: []string{"bar", user.AllAuthenticated},
|
||||
},
|
||||
ResourceRequest: true,
|
||||
},
|
||||
|
@ -851,7 +937,7 @@ func TestPolicy(t *testing.T) {
|
|||
attr: authorizer.AttributesRecord{
|
||||
User: &user.DefaultInfo{
|
||||
Name: "foo",
|
||||
Groups: []string{"bar"},
|
||||
Groups: []string{"bar", user.AllAuthenticated},
|
||||
},
|
||||
ResourceRequest: true,
|
||||
},
|
||||
|
@ -866,6 +952,10 @@ func TestPolicy(t *testing.T) {
|
|||
},
|
||||
},
|
||||
attr: authorizer.AttributesRecord{
|
||||
User: &user.DefaultInfo{
|
||||
Name: "foo",
|
||||
Groups: []string{user.AllAuthenticated},
|
||||
},
|
||||
Verb: "get",
|
||||
ResourceRequest: true,
|
||||
},
|
||||
|
@ -880,6 +970,10 @@ func TestPolicy(t *testing.T) {
|
|||
},
|
||||
},
|
||||
attr: authorizer.AttributesRecord{
|
||||
User: &user.DefaultInfo{
|
||||
Name: "foo",
|
||||
Groups: []string{user.AllAuthenticated},
|
||||
},
|
||||
Resource: "foo",
|
||||
ResourceRequest: true,
|
||||
},
|
||||
|
@ -896,7 +990,8 @@ func TestPolicy(t *testing.T) {
|
|||
},
|
||||
attr: authorizer.AttributesRecord{
|
||||
User: &user.DefaultInfo{
|
||||
Name: "foo",
|
||||
Name: "foo",
|
||||
Groups: []string{user.AllAuthenticated},
|
||||
},
|
||||
Namespace: "bar",
|
||||
Resource: "baz",
|
||||
|
@ -913,6 +1008,10 @@ func TestPolicy(t *testing.T) {
|
|||
},
|
||||
},
|
||||
attr: authorizer.AttributesRecord{
|
||||
User: &user.DefaultInfo{
|
||||
Name: "foo",
|
||||
Groups: []string{user.AllAuthenticated},
|
||||
},
|
||||
Path: "/api",
|
||||
ResourceRequest: false,
|
||||
},
|
||||
|
@ -927,6 +1026,10 @@ func TestPolicy(t *testing.T) {
|
|||
},
|
||||
},
|
||||
attr: authorizer.AttributesRecord{
|
||||
User: &user.DefaultInfo{
|
||||
Name: "foo",
|
||||
Groups: []string{user.AllAuthenticated},
|
||||
},
|
||||
Path: "/api",
|
||||
ResourceRequest: false,
|
||||
},
|
||||
|
@ -941,6 +1044,10 @@ func TestPolicy(t *testing.T) {
|
|||
},
|
||||
},
|
||||
attr: authorizer.AttributesRecord{
|
||||
User: &user.DefaultInfo{
|
||||
Name: "foo",
|
||||
Groups: []string{user.AllAuthenticated},
|
||||
},
|
||||
Path: "/api/foo",
|
||||
ResourceRequest: false,
|
||||
},
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user":"*", "nonResourcePath": "*", "readonly": true}}
|
||||
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"group":"system:authenticated", "nonResourcePath": "*", "readonly": true}}
|
||||
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user":"system:unauthenticated", "nonResourcePath": "*", "readonly": true}}
|
||||
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user":"admin", "namespace": "*", "resource": "*", "apiGroup": "*" }}
|
||||
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user":"scheduler", "namespace": "*", "resource": "pods", "readonly": true }}
|
||||
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user":"scheduler", "namespace": "*", "resource": "bindings" }}
|
||||
|
|
|
@ -11406,6 +11406,83 @@ var OpenAPIDefinitions *common.OpenAPIDefinitions = &common.OpenAPIDefinitions{
|
|||
Dependencies: []string{
|
||||
"v1beta1.FSGroupStrategyOptions", "v1beta1.HostPortRange", "v1beta1.RunAsUserStrategyOptions", "v1beta1.SELinuxStrategyOptions", "v1beta1.SupplementalGroupsStrategyOptions"},
|
||||
},
|
||||
"v1beta1.Policy": {
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Policy contains a single ABAC policy rule",
|
||||
Properties: map[string]spec.Schema{
|
||||
"spec": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Spec describes the policy rule",
|
||||
Ref: spec.MustCreateRef("#/definitions/v1beta1.PolicySpec"),
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"spec"},
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"v1beta1.PolicySpec"},
|
||||
},
|
||||
"v1beta1.PolicySpec": {
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "PolicySpec contains the attributes for a policy rule",
|
||||
Properties: map[string]spec.Schema{
|
||||
"user": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "User is the username this rule applies to. Either user or group is required to match the request. \"*\" matches all users.",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"group": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Group is the group this rule applies to. Either user or group is required to match the request. \"*\" matches all groups.",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"readonly": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Readonly matches readonly requests when true, and all requests when false",
|
||||
Type: []string{"boolean"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"apiGroup": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "APIGroup is the name of an API group. APIGroup, Resource, and Namespace are required to match resource requests. \"*\" matches all API groups",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"resource": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Resource is the name of a resource. APIGroup, Resource, and Namespace are required to match resource requests. \"*\" matches all resources",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"namespace": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Namespace is the name of a namespace. APIGroup, Resource, and Namespace are required to match resource requests. \"*\" matches all namespaces (including unnamespaced requests)",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"nonResourcePath": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "NonResourcePath matches non-resource request paths. \"*\" matches all paths \"/foo/*\" matches all subpaths of foo",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Dependencies: []string{},
|
||||
},
|
||||
"v1beta1.ReplicaSet": {
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
|
|
|
@ -46,6 +46,7 @@ import (
|
|||
"k8s.io/kubernetes/pkg/auth/authenticator/bearertoken"
|
||||
"k8s.io/kubernetes/pkg/auth/authorizer"
|
||||
"k8s.io/kubernetes/pkg/auth/authorizer/abac"
|
||||
"k8s.io/kubernetes/pkg/auth/group"
|
||||
"k8s.io/kubernetes/pkg/auth/user"
|
||||
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api/v1"
|
||||
apiserverauthorizer "k8s.io/kubernetes/pkg/genericapiserver/authorizer"
|
||||
|
@ -67,7 +68,7 @@ func getTestTokenAuth() authenticator.Request {
|
|||
tokenAuthenticator := tokentest.New()
|
||||
tokenAuthenticator.Tokens[AliceToken] = &user.DefaultInfo{Name: "alice", UID: "1"}
|
||||
tokenAuthenticator.Tokens[BobToken] = &user.DefaultInfo{Name: "bob", UID: "2"}
|
||||
return bearertoken.New(tokenAuthenticator)
|
||||
return group.NewGroupAdder(bearertoken.New(tokenAuthenticator), []string{user.AllAuthenticated})
|
||||
}
|
||||
|
||||
func getTestWebhookTokenAuth(serverURL string) (authenticator.Request, error) {
|
||||
|
|
|
@ -576,6 +576,7 @@ k8s.io/kubernetes/pkg/apimachinery,gmarek,1
|
|||
k8s.io/kubernetes/pkg/apimachinery/announced,kargakis,1
|
||||
k8s.io/kubernetes/pkg/apimachinery/registered,jlowdermilk,1
|
||||
k8s.io/kubernetes/pkg/apis/abac/v0,liggitt,0
|
||||
k8s.io/kubernetes/pkg/apis/abac/v1beta1,liggitt,0
|
||||
k8s.io/kubernetes/pkg/apis/apps/validation,derekwaynecarr,1
|
||||
k8s.io/kubernetes/pkg/apis/authorization/validation,erictune,0
|
||||
k8s.io/kubernetes/pkg/apis/autoscaling/v1,yarntime,0
|
||||
|
|
|
Loading…
Reference in New Issue