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  })