github.com/pf-qiu/concourse/v6@v6.7.3-0.20201207032516-1f455d73275f/atc/policy/opa/opa_test.go (about) 1 package opa_test 2 3 import ( 4 "fmt" 5 "net/http" 6 "net/http/httptest" 7 "time" 8 9 "code.cloudfoundry.org/lager/lagertest" 10 "github.com/pf-qiu/concourse/v6/atc/policy" 11 "github.com/pf-qiu/concourse/v6/atc/policy/opa" 12 13 . "github.com/onsi/ginkgo" 14 . "github.com/onsi/gomega" 15 ) 16 17 var _ = Describe("Policy checker", func() { 18 19 var ( 20 logger = lagertest.NewTestLogger("opa-test") 21 fakeOpa *httptest.Server 22 agent policy.Agent 23 err error 24 ) 25 26 AfterEach(func() { 27 if fakeOpa != nil { 28 fakeOpa.Close() 29 } 30 }) 31 32 JustBeforeEach(func() { 33 fakeOpa.Start() 34 agent, err = (&opa.OpaConfig{fakeOpa.URL, time.Second * 2}).NewAgent(logger) 35 Expect(err).ToNot(HaveOccurred()) 36 Expect(agent).ToNot(BeNil()) 37 }) 38 39 Context("when OPA returns no result", func() { 40 BeforeEach(func() { 41 fakeOpa = httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 42 fmt.Fprint(w, "{}") 43 })) 44 }) 45 46 It("should return an error", func() { 47 result, err := agent.Check(policy.PolicyCheckInput{}) 48 Expect(err).To(MatchError(ContainSubstring("opa returned invalid response"))) 49 Expect(result.Allowed).To(BeFalse()) 50 }) 51 }) 52 53 Context("when OPA returns an empty result", func() { 54 BeforeEach(func() { 55 fakeOpa = httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 56 fmt.Fprint(w, `{ "result": {} }`) 57 })) 58 }) 59 60 It("should return an error", func() { 61 result, err := agent.Check(policy.PolicyCheckInput{}) 62 Expect(err).To(MatchError(ContainSubstring("opa returned invalid response"))) 63 Expect(result.Allowed).To(BeFalse()) 64 }) 65 }) 66 67 Context("when OPA returns no allowed field", func() { 68 BeforeEach(func() { 69 fakeOpa = httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 70 fmt.Fprint(w, `{ "result": { "reasons": [ "a policy says you can't do that" ] }}`) 71 })) 72 }) 73 74 It("should return an error", func() { 75 result, err := agent.Check(policy.PolicyCheckInput{}) 76 Expect(err).To(MatchError(ContainSubstring("opa returned invalid response"))) 77 Expect(result.Allowed).To(BeFalse()) 78 }) 79 }) 80 81 Context("when OPA returns allowed", func() { 82 BeforeEach(func() { 83 fakeOpa = httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 84 fmt.Fprint(w, `{"result": {"allowed": true }}`) 85 })) 86 }) 87 88 It("should be allowed", func() { 89 result, err := agent.Check(policy.PolicyCheckInput{}) 90 Expect(err).ToNot(HaveOccurred()) 91 Expect(result.Allowed).To(BeTrue()) 92 }) 93 }) 94 95 Context("when OPA returns not-allowed", func() { 96 BeforeEach(func() { 97 fakeOpa = httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 98 fmt.Fprint(w, `{"result": {"allowed": false }}`) 99 })) 100 }) 101 102 It("should not be allowed and return reasons", func() { 103 result, err := agent.Check(policy.PolicyCheckInput{}) 104 Expect(err).ToNot(HaveOccurred()) 105 Expect(result.Allowed).To(BeFalse()) 106 Expect(result.Reasons).To(BeEmpty()) 107 }) 108 }) 109 110 Context("when OPA returns not-allowed with reasons", func() { 111 BeforeEach(func() { 112 fakeOpa = httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 113 fmt.Fprint(w, `{"result": {"allowed": false, "reasons": ["a policy says you can't do that"]}}`) 114 })) 115 }) 116 117 It("should not be allowed and return reasons", func() { 118 result, err := agent.Check(policy.PolicyCheckInput{}) 119 Expect(err).ToNot(HaveOccurred()) 120 Expect(result.Allowed).To(BeFalse()) 121 Expect(result.Reasons).To(ConsistOf("a policy says you can't do that")) 122 }) 123 }) 124 125 Context("when OPA is unreachable", func() { 126 BeforeEach(func() { 127 fakeOpa = httptest.NewUnstartedServer(http.NotFoundHandler()) 128 }) 129 130 JustBeforeEach(func() { 131 fakeOpa.Close() 132 fakeOpa = nil 133 }) 134 135 It("should return error", func() { 136 result, err := agent.Check(policy.PolicyCheckInput{}) 137 Expect(err).To(HaveOccurred()) 138 Expect(err.Error()).To(MatchRegexp("connection refused")) 139 Expect(result.Allowed).To(BeFalse()) 140 }) 141 }) 142 143 Context("when OPA returns http error", func() { 144 BeforeEach(func() { 145 fakeOpa = httptest.NewUnstartedServer(http.NotFoundHandler()) 146 }) 147 148 It("should return error", func() { 149 result, err := agent.Check(policy.PolicyCheckInput{}) 150 Expect(err).To(HaveOccurred()) 151 Expect(err.Error()).To(Equal("opa returned status: 404")) 152 Expect(result.Allowed).To(BeFalse()) 153 }) 154 }) 155 156 Context("when OPA returns bad response", func() { 157 BeforeEach(func() { 158 fakeOpa = httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 159 fmt.Fprint(w, `hello`) 160 })) 161 }) 162 163 It("should return error", func() { 164 result, err := agent.Check(policy.PolicyCheckInput{}) 165 Expect(err).To(HaveOccurred()) 166 Expect(err.Error()).To(Equal("opa returned bad response: invalid character 'h' looking for beginning of value")) 167 Expect(result.Allowed).To(BeFalse()) 168 }) 169 }) 170 })