1package policychecker_test
2
3import (
4	"errors"
5	"io/ioutil"
6	"net/http"
7	"net/http/httptest"
8
9	"code.cloudfoundry.org/lager/lagertest"
10
11	"github.com/concourse/concourse/atc/api/policychecker"
12	"github.com/concourse/concourse/atc/api/policychecker/policycheckerfakes"
13	"github.com/concourse/concourse/atc/policy"
14
15	. "github.com/onsi/ginkgo"
16	. "github.com/onsi/gomega"
17)
18
19var _ = Describe("Handler", func() {
20	var (
21		innerHandlerCalled   bool
22		dummyHandler         http.HandlerFunc
23		policyCheckerHandler http.Handler
24		req                  *http.Request
25		fakePolicyChecker    *policycheckerfakes.FakePolicyChecker
26		responseWriter       *httptest.ResponseRecorder
27
28		logger = lagertest.NewTestLogger("test")
29	)
30
31	BeforeEach(func() {
32		fakePolicyChecker = new(policycheckerfakes.FakePolicyChecker)
33
34		innerHandlerCalled = false
35		dummyHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
36			innerHandlerCalled = true
37		})
38
39		responseWriter = httptest.NewRecorder()
40
41		var err error
42		req, err = http.NewRequest("GET", "localhost:8080", nil)
43		Expect(err).NotTo(HaveOccurred())
44	})
45
46	JustBeforeEach(func() {
47		policyCheckerHandler.ServeHTTP(responseWriter, req)
48	})
49
50	Describe("when policy checker is not configured", func() {
51		BeforeEach(func() {
52			policyCheckerHandler = policychecker.NewHandler(logger, dummyHandler, "some-action", nil)
53		})
54
55		It("calls the inner handler", func() {
56			Expect(innerHandlerCalled).To(BeTrue())
57		})
58	})
59
60	Describe("when policy checker is configured", func() {
61		BeforeEach(func() {
62			policyCheckerHandler = policychecker.NewHandler(logger, dummyHandler, "some-action", fakePolicyChecker)
63		})
64
65		Context("policy check passes", func() {
66			BeforeEach(func() {
67				fakePolicyChecker.CheckReturns(policy.PassedPolicyCheck(), nil)
68			})
69
70			It("calls the inner handler", func() {
71				Expect(innerHandlerCalled).To(BeTrue())
72			})
73		})
74
75		Context("policy check doesn't pass", func() {
76			BeforeEach(func() {
77				fakePolicyChecker.CheckReturns(policy.PolicyCheckOutput{
78					Allowed: false,
79					Reasons: []string{"a policy says you can't do that", "another policy also says you can't do that"},
80				}, nil)
81			})
82
83			It("return http forbidden", func() {
84				Expect(responseWriter.Code).To(Equal(http.StatusForbidden))
85
86				msg, err := ioutil.ReadAll(responseWriter.Body)
87				Expect(err).ToNot(HaveOccurred())
88				Expect(string(msg)).To(Equal("policy check failed: a policy says you can't do that, another policy also says you can't do that"))
89			})
90
91			It("not call the inner handler", func() {
92				Expect(innerHandlerCalled).To(BeFalse())
93			})
94		})
95
96		Context("policy check errors", func() {
97			BeforeEach(func() {
98				fakePolicyChecker.CheckReturns(policy.FailedPolicyCheck(), errors.New("some-error"))
99			})
100
101			It("return http bad request", func() {
102				Expect(responseWriter.Code).To(Equal(http.StatusBadRequest))
103
104				msg, err := ioutil.ReadAll(responseWriter.Body)
105				Expect(err).ToNot(HaveOccurred())
106				Expect(string(msg)).To(Equal("policy check error: some-error"))
107			})
108
109			It("not call the inner handler", func() {
110				Expect(innerHandlerCalled).To(BeFalse())
111			})
112		})
113	})
114})
115