github.com/pf-qiu/concourse/v6@v6.7.3-0.20201207032516-1f455d73275f/atc/api/policychecker/checker.go (about) 1 package policychecker 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "io/ioutil" 7 "net/http" 8 9 "sigs.k8s.io/yaml" 10 11 "github.com/pf-qiu/concourse/v6/atc/api/accessor" 12 "github.com/pf-qiu/concourse/v6/atc/policy" 13 ) 14 15 //go:generate counterfeiter . PolicyChecker 16 17 type PolicyChecker interface { 18 Check(string, accessor.Access, *http.Request) (policy.PolicyCheckOutput, error) 19 } 20 21 type checker struct { 22 policyChecker policy.Checker 23 } 24 25 func NewApiPolicyChecker(policyChecker policy.Checker) PolicyChecker { 26 return &checker{policyChecker: policyChecker} 27 } 28 29 func (c *checker) Check(action string, acc accessor.Access, req *http.Request) (policy.PolicyCheckOutput, error) { 30 // Ignore self invoked API calls. 31 if acc.IsSystem() { 32 return policy.PassedPolicyCheck(), nil 33 } 34 35 // Actions in black will not go through policy check. 36 if c.policyChecker.ShouldSkipAction(action) { 37 return policy.PassedPolicyCheck(), nil 38 } 39 40 // Only actions with specified http method will go through policy check. 41 // But actions in white list will always go through policy check. 42 if !c.policyChecker.ShouldCheckHttpMethod(req.Method) && 43 !c.policyChecker.ShouldCheckAction(action) { 44 return policy.PassedPolicyCheck(), nil 45 } 46 47 team := req.FormValue(":team_name") 48 input := policy.PolicyCheckInput{ 49 HttpMethod: req.Method, 50 Action: action, 51 User: acc.Claims().UserName, 52 Roles: acc.TeamRoles()[team], 53 Team: team, 54 Pipeline: req.FormValue(":pipeline_name"), 55 } 56 57 switch ct := req.Header.Get("Content-type"); ct { 58 case "application/json", "text/vnd.yaml", "text/yaml", "text/x-yaml", "application/x-yaml": 59 body, err := ioutil.ReadAll(req.Body) 60 if err != nil { 61 return policy.FailedPolicyCheck(), err 62 } else if body != nil && len(body) > 0 { 63 if ct == "application/json" { 64 err = json.Unmarshal(body, &input.Data) 65 } else { 66 err = yaml.Unmarshal(body, &input.Data) 67 } 68 if err != nil { 69 return policy.FailedPolicyCheck(), err 70 } 71 72 req.Body = ioutil.NopCloser(bytes.NewBuffer(body)) 73 } 74 } 75 76 return c.policyChecker.Check(input) 77 }