forked from openshift/origin
-
Notifications
You must be signed in to change notification settings - Fork 0
/
storage.go
99 lines (81 loc) · 2.9 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
93
94
95
96
97
98
99
package selfsubjectrulesreview
import (
"fmt"
"sort"
kapi "k8s.io/kubernetes/pkg/api"
kapierrors "k8s.io/kubernetes/pkg/api/errors"
"k8s.io/kubernetes/pkg/runtime"
authorizationapi "github.com/openshift/origin/pkg/authorization/api"
"github.com/openshift/origin/pkg/authorization/authorizer/scope"
"github.com/openshift/origin/pkg/authorization/rulevalidation"
)
type REST struct {
ruleResolver rulevalidation.AuthorizationRuleResolver
clusterPolicyGetter rulevalidation.ClusterPolicyGetter
}
func NewREST(ruleResolver rulevalidation.AuthorizationRuleResolver, clusterPolicyGetter rulevalidation.ClusterPolicyGetter) *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))
}
user, exists := kapi.UserFrom(ctx)
if !exists {
return nil, fmt.Errorf("user missing from context")
}
policyRules, err := r.ruleResolver.GetEffectivePolicyRules(ctx)
rules := []authorizationapi.PolicyRule{}
for _, rule := range policyRules {
rules = append(rules, rulevalidation.BreakdownRule(rule)...)
}
switch {
case rulesReview.Spec.Scopes == nil:
if scopes, _ := user.GetExtra()[authorizationapi.ScopesKey]; len(scopes) > 0 {
rules, err = r.filterRulesByScopes(rules, scopes, namespace)
if err != nil {
return nil, err
}
}
case len(rulesReview.Spec.Scopes) > 0:
rules, err = r.filterRulesByScopes(rules, rulesReview.Spec.Scopes, namespace)
if err != nil {
return nil, err
}
}
if compactedRules, err := rulevalidation.CompactRules(rules); err == nil {
rules = compactedRules
}
sort.Sort(authorizationapi.SortableRuleSlice(rules))
ret := &authorizationapi.SelfSubjectRulesReview{
Status: authorizationapi.SubjectRulesReviewStatus{
Rules: rules,
},
}
if err != nil {
ret.Status.EvaluationError = err.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
}