...
1
2
3
4
5
6
7
8
9
10
11
12
13
14 package utils
15
16 import (
17 "net/http"
18
19 "github.com/gin-gonic/gin"
20 authorizationv1 "k8s.io/api/authorization/v1"
21
22 "github.com/chaos-mesh/chaos-mesh/pkg/clientpool"
23 "github.com/chaos-mesh/chaos-mesh/pkg/mock"
24 )
25
26 func AuthRequired(c *gin.Context) {
27 if mockResult := mock.On("MockAuthRequired"); mockResult != nil {
28 c.Next()
29 return
30 }
31
32 authCli, err := clientpool.ExtractTokenAndGetAuthClient(c.Request.Header)
33 if err != nil {
34 c.AbortWithError(http.StatusUnauthorized, ErrInvalidRequest.WrapWithNoMessage(err))
35 return
36 }
37
38 namespace := c.Query("namespace")
39 verb := "list"
40 if c.Request.Method != http.MethodGet {
41
42 verb = "patch"
43 }
44
45 sar := &authorizationv1.SelfSubjectAccessReview{
46 Spec: authorizationv1.SelfSubjectAccessReviewSpec{
47 ResourceAttributes: &authorizationv1.ResourceAttributes{
48 Namespace: namespace,
49 Verb: verb,
50 Group: "chaos-mesh.org",
51 Resource: "*",
52 },
53 },
54 }
55
56 response, err := authCli.SelfSubjectAccessReviews().Create(sar)
57 if err != nil {
58 c.AbortWithError(http.StatusUnauthorized, ErrInvalidRequest.WrapWithNoMessage(err))
59 return
60 }
61
62 if !response.Status.Allowed {
63 if len(namespace) == 0 {
64 c.AbortWithError(http.StatusUnauthorized, ErrNoClusterPrivilege.New("can't %s resource in the cluster", verb))
65 } else {
66 c.AbortWithError(http.StatusUnauthorized, ErrNoNamespacePrivilege.New("can't %s resource in namespace %s", verb, namespace))
67 }
68 return
69 }
70
71 c.Next()
72 }
73