mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-03 19:58:17 +00:00 
			
		
		
		
	Use namespace from context
This commit is contained in:
		@@ -16,6 +16,7 @@ go_library(
 | 
				
			|||||||
        "//pkg/registry/rbac:go_default_library",
 | 
					        "//pkg/registry/rbac:go_default_library",
 | 
				
			||||||
        "//pkg/registry/rbac/validation:go_default_library",
 | 
					        "//pkg/registry/rbac/validation:go_default_library",
 | 
				
			||||||
        "//vendor:k8s.io/apimachinery/pkg/api/errors",
 | 
					        "//vendor:k8s.io/apimachinery/pkg/api/errors",
 | 
				
			||||||
 | 
					        "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
 | 
				
			||||||
        "//vendor:k8s.io/apimachinery/pkg/runtime",
 | 
					        "//vendor:k8s.io/apimachinery/pkg/runtime",
 | 
				
			||||||
        "//vendor:k8s.io/apiserver/pkg/authorization/authorizer",
 | 
					        "//vendor:k8s.io/apiserver/pkg/authorization/authorizer",
 | 
				
			||||||
        "//vendor:k8s.io/apiserver/pkg/endpoints/request",
 | 
					        "//vendor:k8s.io/apiserver/pkg/endpoints/request",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,6 +19,7 @@ package policybased
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/api/errors"
 | 
						"k8s.io/apimachinery/pkg/api/errors"
 | 
				
			||||||
 | 
						metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/runtime"
 | 
						"k8s.io/apimachinery/pkg/runtime"
 | 
				
			||||||
	"k8s.io/apiserver/pkg/authorization/authorizer"
 | 
						"k8s.io/apiserver/pkg/authorization/authorizer"
 | 
				
			||||||
	genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
 | 
						genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
 | 
				
			||||||
@@ -48,11 +49,11 @@ func (s *Storage) Create(ctx genericapirequest.Context, obj runtime.Object) (run
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	clusterRoleBinding := obj.(*rbac.ClusterRoleBinding)
 | 
						clusterRoleBinding := obj.(*rbac.ClusterRoleBinding)
 | 
				
			||||||
	if rbacregistry.BindingAuthorized(ctx, clusterRoleBinding.RoleRef, clusterRoleBinding.Namespace, s.authorizer) {
 | 
						if rbacregistry.BindingAuthorized(ctx, clusterRoleBinding.RoleRef, metav1.NamespaceNone, s.authorizer) {
 | 
				
			||||||
		return s.StandardStorage.Create(ctx, obj)
 | 
							return s.StandardStorage.Create(ctx, obj)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rules, err := s.ruleResolver.GetRoleReferenceRules(clusterRoleBinding.RoleRef, clusterRoleBinding.Namespace)
 | 
						rules, err := s.ruleResolver.GetRoleReferenceRules(clusterRoleBinding.RoleRef, metav1.NamespaceNone)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -71,12 +72,12 @@ func (s *Storage) Update(ctx genericapirequest.Context, name string, obj rest.Up
 | 
				
			|||||||
		clusterRoleBinding := obj.(*rbac.ClusterRoleBinding)
 | 
							clusterRoleBinding := obj.(*rbac.ClusterRoleBinding)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// if we're explicitly authorized to bind this clusterrole, return
 | 
							// if we're explicitly authorized to bind this clusterrole, return
 | 
				
			||||||
		if rbacregistry.BindingAuthorized(ctx, clusterRoleBinding.RoleRef, clusterRoleBinding.Namespace, s.authorizer) {
 | 
							if rbacregistry.BindingAuthorized(ctx, clusterRoleBinding.RoleRef, metav1.NamespaceNone, s.authorizer) {
 | 
				
			||||||
			return obj, nil
 | 
								return obj, nil
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Otherwise, see if we already have all the permissions contained in the referenced clusterrole
 | 
							// Otherwise, see if we already have all the permissions contained in the referenced clusterrole
 | 
				
			||||||
		rules, err := s.ruleResolver.GetRoleReferenceRules(clusterRoleBinding.RoleRef, clusterRoleBinding.Namespace)
 | 
							rules, err := s.ruleResolver.GetRoleReferenceRules(clusterRoleBinding.RoleRef, metav1.NamespaceNone)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return nil, err
 | 
								return nil, err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -85,7 +85,7 @@ func BindingAuthorized(ctx genericapirequest.Context, roleRef rbac.RoleRef, bind
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		utilruntime.HandleError(fmt.Errorf(
 | 
							utilruntime.HandleError(fmt.Errorf(
 | 
				
			||||||
			"error authorizing user %#v to bind %#v in namespace %s: %v",
 | 
								"error authorizing user %#v to bind %#v in namespace %s: %v",
 | 
				
			||||||
			roleRef, bindingNamespace, user, err,
 | 
								user, roleRef, bindingNamespace, err,
 | 
				
			||||||
		))
 | 
							))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return ok
 | 
						return ok
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -47,12 +47,19 @@ func (s *Storage) Create(ctx genericapirequest.Context, obj runtime.Object) (run
 | 
				
			|||||||
		return s.StandardStorage.Create(ctx, obj)
 | 
							return s.StandardStorage.Create(ctx, obj)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Get the namespace from the context (populated from the URL).
 | 
				
			||||||
 | 
						// The namespace in the object can be empty until StandardStorage.Create()->BeforeCreate() populates it from the context.
 | 
				
			||||||
 | 
						namespace, ok := genericapirequest.NamespaceFrom(ctx)
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							return nil, errors.NewBadRequest("namespace is required")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	roleBinding := obj.(*rbac.RoleBinding)
 | 
						roleBinding := obj.(*rbac.RoleBinding)
 | 
				
			||||||
	if rbacregistry.BindingAuthorized(ctx, roleBinding.RoleRef, roleBinding.Namespace, s.authorizer) {
 | 
						if rbacregistry.BindingAuthorized(ctx, roleBinding.RoleRef, namespace, s.authorizer) {
 | 
				
			||||||
		return s.StandardStorage.Create(ctx, obj)
 | 
							return s.StandardStorage.Create(ctx, obj)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rules, err := s.ruleResolver.GetRoleReferenceRules(roleBinding.RoleRef, roleBinding.Namespace)
 | 
						rules, err := s.ruleResolver.GetRoleReferenceRules(roleBinding.RoleRef, namespace)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -68,15 +75,22 @@ func (s *Storage) Update(ctx genericapirequest.Context, name string, obj rest.Up
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	nonEscalatingInfo := rest.WrapUpdatedObjectInfo(obj, func(ctx genericapirequest.Context, obj runtime.Object, oldObj runtime.Object) (runtime.Object, error) {
 | 
						nonEscalatingInfo := rest.WrapUpdatedObjectInfo(obj, func(ctx genericapirequest.Context, obj runtime.Object, oldObj runtime.Object) (runtime.Object, error) {
 | 
				
			||||||
 | 
							// Get the namespace from the context (populated from the URL).
 | 
				
			||||||
 | 
							// The namespace in the object can be empty until StandardStorage.Update()->BeforeUpdate() populates it from the context.
 | 
				
			||||||
 | 
							namespace, ok := genericapirequest.NamespaceFrom(ctx)
 | 
				
			||||||
 | 
							if !ok {
 | 
				
			||||||
 | 
								return nil, errors.NewBadRequest("namespace is required")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		roleBinding := obj.(*rbac.RoleBinding)
 | 
							roleBinding := obj.(*rbac.RoleBinding)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// if we're explicitly authorized to bind this role, return
 | 
							// if we're explicitly authorized to bind this role, return
 | 
				
			||||||
		if rbacregistry.BindingAuthorized(ctx, roleBinding.RoleRef, roleBinding.Namespace, s.authorizer) {
 | 
							if rbacregistry.BindingAuthorized(ctx, roleBinding.RoleRef, namespace, s.authorizer) {
 | 
				
			||||||
			return obj, nil
 | 
								return obj, nil
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Otherwise, see if we already have all the permissions contained in the referenced role
 | 
							// Otherwise, see if we already have all the permissions contained in the referenced role
 | 
				
			||||||
		rules, err := s.ruleResolver.GetRoleReferenceRules(roleBinding.RoleRef, roleBinding.Namespace)
 | 
							rules, err := s.ruleResolver.GetRoleReferenceRules(roleBinding.RoleRef, namespace)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return nil, err
 | 
								return nil, err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -352,9 +352,17 @@ func TestRBAC(t *testing.T) {
 | 
				
			|||||||
					},
 | 
										},
 | 
				
			||||||
					{
 | 
										{
 | 
				
			||||||
						ObjectMeta: metav1.ObjectMeta{Name: "create-rolebindings", Namespace: "job-namespace"},
 | 
											ObjectMeta: metav1.ObjectMeta{Name: "create-rolebindings", Namespace: "job-namespace"},
 | 
				
			||||||
						Subjects:   []rbacapi.Subject{{Kind: "User", Name: "job-writer-namespace"}},
 | 
											Subjects: []rbacapi.Subject{
 | 
				
			||||||
 | 
												{Kind: "User", Name: "job-writer-namespace"},
 | 
				
			||||||
 | 
												{Kind: "User", Name: "any-rolebinding-writer-namespace"},
 | 
				
			||||||
 | 
											},
 | 
				
			||||||
						RoleRef: rbacapi.RoleRef{Kind: "ClusterRole", Name: "create-rolebindings"},
 | 
											RoleRef: rbacapi.RoleRef{Kind: "ClusterRole", Name: "create-rolebindings"},
 | 
				
			||||||
					},
 | 
										},
 | 
				
			||||||
 | 
										{
 | 
				
			||||||
 | 
											ObjectMeta: metav1.ObjectMeta{Name: "bind-any-clusterrole", Namespace: "job-namespace"},
 | 
				
			||||||
 | 
											Subjects:   []rbacapi.Subject{{Kind: "User", Name: "any-rolebinding-writer-namespace"}},
 | 
				
			||||||
 | 
											RoleRef:    rbacapi.RoleRef{Kind: "ClusterRole", Name: "bind-any-clusterrole"},
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			requests: []request{
 | 
								requests: []request{
 | 
				
			||||||
@@ -384,6 +392,8 @@ func TestRBAC(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
				// cannot bind role anywhere
 | 
									// cannot bind role anywhere
 | 
				
			||||||
				{"user-with-no-permissions", "POST", "rbac.authorization.k8s.io", "rolebindings", "job-namespace", "", writeJobsRoleBinding, http.StatusForbidden},
 | 
									{"user-with-no-permissions", "POST", "rbac.authorization.k8s.io", "rolebindings", "job-namespace", "", writeJobsRoleBinding, http.StatusForbidden},
 | 
				
			||||||
 | 
									// can only bind role in namespace where they have explicit bind permission
 | 
				
			||||||
 | 
									{"any-rolebinding-writer-namespace", "POST", "rbac.authorization.k8s.io", "rolebindings", "forbidden-namespace", "", writeJobsRoleBinding, http.StatusForbidden},
 | 
				
			||||||
				// can only bind role in namespace where they have covering permissions
 | 
									// can only bind role in namespace where they have covering permissions
 | 
				
			||||||
				{"job-writer-namespace", "POST", "rbac.authorization.k8s.io", "rolebindings", "forbidden-namespace", "", writeJobsRoleBinding, http.StatusForbidden},
 | 
									{"job-writer-namespace", "POST", "rbac.authorization.k8s.io", "rolebindings", "forbidden-namespace", "", writeJobsRoleBinding, http.StatusForbidden},
 | 
				
			||||||
				{"job-writer-namespace", "POST", "rbac.authorization.k8s.io", "rolebindings", "job-namespace", "", writeJobsRoleBinding, http.StatusCreated},
 | 
									{"job-writer-namespace", "POST", "rbac.authorization.k8s.io", "rolebindings", "job-namespace", "", writeJobsRoleBinding, http.StatusCreated},
 | 
				
			||||||
@@ -396,6 +406,8 @@ func TestRBAC(t *testing.T) {
 | 
				
			|||||||
				// can bind role because they have explicit bind permission
 | 
									// can bind role because they have explicit bind permission
 | 
				
			||||||
				{"any-rolebinding-writer", "POST", "rbac.authorization.k8s.io", "rolebindings", "job-namespace", "", writeJobsRoleBinding, http.StatusCreated},
 | 
									{"any-rolebinding-writer", "POST", "rbac.authorization.k8s.io", "rolebindings", "job-namespace", "", writeJobsRoleBinding, http.StatusCreated},
 | 
				
			||||||
				{superUser, "DELETE", "rbac.authorization.k8s.io", "rolebindings", "job-namespace", "pi", "", http.StatusOK},
 | 
									{superUser, "DELETE", "rbac.authorization.k8s.io", "rolebindings", "job-namespace", "pi", "", http.StatusOK},
 | 
				
			||||||
 | 
									{"any-rolebinding-writer-namespace", "POST", "rbac.authorization.k8s.io", "rolebindings", "job-namespace", "", writeJobsRoleBinding, http.StatusCreated},
 | 
				
			||||||
 | 
									{superUser, "DELETE", "rbac.authorization.k8s.io", "rolebindings", "job-namespace", "pi", "", http.StatusOK},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -434,12 +446,6 @@ func TestRBAC(t *testing.T) {
 | 
				
			|||||||
						sub += fmt.Sprintf(",\"resourceVersion\": \"%v\"", resVersion)
 | 
											sub += fmt.Sprintf(",\"resourceVersion\": \"%v\"", resVersion)
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				// For any creation requests, add the namespace to the object meta.
 | 
					 | 
				
			||||||
				if r.verb == "POST" || r.verb == "PUT" {
 | 
					 | 
				
			||||||
					if r.namespace != "" {
 | 
					 | 
				
			||||||
						sub += fmt.Sprintf(",\"namespace\": %q", r.namespace)
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				body = strings.NewReader(fmt.Sprintf(r.body, sub))
 | 
									body = strings.NewReader(fmt.Sprintf(r.body, sub))
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user