forked from openshift/origin
-
Notifications
You must be signed in to change notification settings - Fork 0
/
personal_subjectaccessreview.go
74 lines (58 loc) · 2.21 KB
/
personal_subjectaccessreview.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
package authorizer
import (
"bytes"
"fmt"
"io/ioutil"
"net/http"
kapi "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/runtime"
authorizationapi "github.com/openshift/origin/pkg/authorization/api"
)
func IsPersonalAccessReview(a AuthorizationAttributes) (bool, error) {
switch extendedAttributes := a.GetRequestAttributes().(type) {
case *http.Request:
return isPersonalAccessReviewFromRequest(a, extendedAttributes)
case *authorizationapi.SubjectAccessReview:
return isPersonalAccessReviewFromSAR(extendedAttributes), nil
case *authorizationapi.LocalSubjectAccessReview:
return isPersonalAccessReviewFromLocalSAR(extendedAttributes), nil
default:
return false, fmt.Errorf("unexpected request attributes for checking personal access review: %v", extendedAttributes)
}
}
// isPersonalAccessReviewFromRequest this variant handles the case where we have an httpRequest
func isPersonalAccessReviewFromRequest(a AuthorizationAttributes, req *http.Request) (bool, error) {
// TODO once we're integrated with the api installer, we should have direct access to the deserialized content
// for now, this only happens on subjectaccessreviews with a personal check, pay the double retrieve and decode cost
body, err := ioutil.ReadAll(req.Body)
if err != nil {
return false, err
}
req.Body = ioutil.NopCloser(bytes.NewBuffer(body))
obj, err := runtime.Decode(kapi.Codecs.UniversalDecoder(), body)
if err != nil {
return false, err
}
switch castObj := obj.(type) {
case *authorizationapi.SubjectAccessReview:
return isPersonalAccessReviewFromSAR(castObj), nil
case *authorizationapi.LocalSubjectAccessReview:
return isPersonalAccessReviewFromLocalSAR(castObj), nil
default:
return false, nil
}
}
// isPersonalAccessReviewFromSAR this variant handles the case where we have an SAR
func isPersonalAccessReviewFromSAR(sar *authorizationapi.SubjectAccessReview) bool {
if len(sar.User) == 0 && len(sar.Groups) == 0 {
return true
}
return false
}
// isPersonalAccessReviewFromLocalSAR this variant handles the case where we have a local SAR
func isPersonalAccessReviewFromLocalSAR(sar *authorizationapi.LocalSubjectAccessReview) bool {
if len(sar.User) == 0 && len(sar.Groups) == 0 {
return true
}
return false
}