forked from openshift/origin
-
Notifications
You must be signed in to change notification settings - Fork 1
/
storage.go
92 lines (76 loc) · 2.94 KB
/
storage.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
package selfsubjectrulesreview
import (
"fmt"
kapi "k8s.io/kubernetes/pkg/api"
kapierrors "k8s.io/kubernetes/pkg/api/errors"
"k8s.io/kubernetes/pkg/auth/user"
"k8s.io/kubernetes/pkg/runtime"
kutilerrors "k8s.io/kubernetes/pkg/util/errors"
authorizationapi "github.com/openshift/origin/pkg/authorization/api"
"github.com/openshift/origin/pkg/authorization/authorizer/scope"
"github.com/openshift/origin/pkg/authorization/registry/subjectrulesreview"
"github.com/openshift/origin/pkg/authorization/rulevalidation"
"github.com/openshift/origin/pkg/client"
)
type REST struct {
ruleResolver rulevalidation.AuthorizationRuleResolver
clusterPolicyGetter client.ClusterPolicyLister
}
func NewREST(ruleResolver rulevalidation.AuthorizationRuleResolver, clusterPolicyGetter client.ClusterPolicyLister) *REST {
return &REST{ruleResolver: ruleResolver, clusterPolicyGetter: clusterPolicyGetter}
}
func (r *REST) New() runtime.Object {
return &authorizationapi.SelfSubjectRulesReview{}
}
// Create registers a given new ResourceAccessReview instance to r.registry.
func (r *REST) Create(ctx kapi.Context, obj runtime.Object) (runtime.Object, error) {
rulesReview, ok := obj.(*authorizationapi.SelfSubjectRulesReview)
if !ok {
return nil, kapierrors.NewBadRequest(fmt.Sprintf("not a SelfSubjectRulesReview: %#v", obj))
}
namespace := kapi.NamespaceValue(ctx)
if len(namespace) == 0 {
return nil, kapierrors.NewBadRequest(fmt.Sprintf("namespace is required on this type: %v", namespace))
}
callingUser, exists := kapi.UserFrom(ctx)
if !exists {
return nil, kapierrors.NewBadRequest(fmt.Sprintf("user missing from context"))
}
// copy the user to avoid mutating the original extra map
userToCheck := &user.DefaultInfo{
Name: callingUser.GetName(),
Groups: callingUser.GetGroups(),
Extra: map[string][]string{},
}
switch {
case rulesReview.Spec.Scopes == nil:
for k, v := range callingUser.GetExtra() {
userToCheck.Extra[k] = v
}
case len(rulesReview.Spec.Scopes) > 0:
userToCheck.Extra[authorizationapi.ScopesKey] = rulesReview.Spec.Scopes
}
rules, errors := subjectrulesreview.GetEffectivePolicyRules(kapi.WithUser(ctx, userToCheck), r.ruleResolver, r.clusterPolicyGetter)
ret := &authorizationapi.SelfSubjectRulesReview{
Status: authorizationapi.SubjectRulesReviewStatus{
Rules: rules,
},
}
if len(errors) != 0 {
ret.Status.EvaluationError = kutilerrors.NewAggregate(errors).Error()
}
return ret, nil
}
func (r *REST) filterRulesByScopes(rules []authorizationapi.PolicyRule, scopes []string, namespace string) ([]authorizationapi.PolicyRule, error) {
scopeRules, err := scope.ScopesToRules(scopes, namespace, r.clusterPolicyGetter)
if err != nil {
return nil, err
}
filteredRules := []authorizationapi.PolicyRule{}
for _, rule := range rules {
if allowed, _ := rulevalidation.Covers(scopeRules, []authorizationapi.PolicyRule{rule}); allowed {
filteredRules = append(filteredRules, rule)
}
}
return filteredRules, nil
}