1package pagewriter 2 3import ( 4 "errors" 5 "html/template" 6 "io/ioutil" 7 "net/http/httptest" 8 9 middlewareapi "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/middleware" 10 . "github.com/onsi/ginkgo" 11 . "github.com/onsi/gomega" 12) 13 14var _ = Describe("Error Page Writer", func() { 15 var errorPage *errorPageWriter 16 17 BeforeEach(func() { 18 tmpl, err := template.New("").Parse("{{.Title}} {{.Message}} {{.ProxyPrefix}} {{.StatusCode}} {{.Redirect}} {{.RequestID}} {{.Footer}} {{.Version}}") 19 Expect(err).ToNot(HaveOccurred()) 20 21 errorPage = &errorPageWriter{ 22 template: tmpl, 23 proxyPrefix: "/prefix/", 24 footer: "Custom Footer Text", 25 version: "v0.0.0-test", 26 } 27 }) 28 29 Context("WriteErrorPage", func() { 30 It("Writes the template to the response writer", func() { 31 recorder := httptest.NewRecorder() 32 errorPage.WriteErrorPage(recorder, ErrorPageOpts{ 33 Status: 403, 34 RedirectURL: "/redirect", 35 RequestID: testRequestID, 36 AppError: "Access Denied", 37 }) 38 39 body, err := ioutil.ReadAll(recorder.Result().Body) 40 Expect(err).ToNot(HaveOccurred()) 41 Expect(string(body)).To(Equal("Forbidden You do not have permission to access this resource. /prefix/ 403 /redirect 11111111-2222-4333-8444-555555555555 Custom Footer Text v0.0.0-test")) 42 }) 43 44 It("With a different code, uses the stock message for the correct code", func() { 45 recorder := httptest.NewRecorder() 46 errorPage.WriteErrorPage(recorder, ErrorPageOpts{ 47 Status: 500, 48 RedirectURL: "/redirect", 49 RequestID: testRequestID, 50 AppError: "Access Denied", 51 }) 52 53 body, err := ioutil.ReadAll(recorder.Result().Body) 54 Expect(err).ToNot(HaveOccurred()) 55 Expect(string(body)).To(Equal("Internal Server Error Oops! Something went wrong. For more information contact your server administrator. /prefix/ 500 /redirect 11111111-2222-4333-8444-555555555555 Custom Footer Text v0.0.0-test")) 56 }) 57 58 It("With a message override, uses the message", func() { 59 recorder := httptest.NewRecorder() 60 errorPage.WriteErrorPage(recorder, ErrorPageOpts{ 61 Status: 403, 62 RedirectURL: "/redirect", 63 RequestID: testRequestID, 64 AppError: "Access Denied", 65 Messages: []interface{}{ 66 "An extra message: %s", 67 "with more context.", 68 }, 69 }) 70 71 body, err := ioutil.ReadAll(recorder.Result().Body) 72 Expect(err).ToNot(HaveOccurred()) 73 Expect(string(body)).To(Equal("Forbidden An extra message: with more context. /prefix/ 403 /redirect 11111111-2222-4333-8444-555555555555 Custom Footer Text v0.0.0-test")) 74 }) 75 76 It("Sanitizes malicious user input", func() { 77 recorder := httptest.NewRecorder() 78 errorPage.WriteErrorPage(recorder, ErrorPageOpts{ 79 Status: 403, 80 RedirectURL: "/redirect", 81 RequestID: "<script>alert(1)</script>", 82 AppError: "Access Denied", 83 }) 84 85 body, err := ioutil.ReadAll(recorder.Result().Body) 86 Expect(err).ToNot(HaveOccurred()) 87 Expect(string(body)).To(Equal("Forbidden You do not have permission to access this resource. /prefix/ 403 /redirect <script>alert(1)</script> Custom Footer Text v0.0.0-test")) 88 }) 89 }) 90 91 Context("ProxyErrorHandler", func() { 92 It("Writes a bad gateway error the response writer", func() { 93 req := httptest.NewRequest("", "/bad-gateway", nil) 94 req = middlewareapi.AddRequestScope(req, &middlewareapi.RequestScope{ 95 RequestID: testRequestID, 96 }) 97 recorder := httptest.NewRecorder() 98 errorPage.ProxyErrorHandler(recorder, req, errors.New("some upstream error")) 99 100 body, err := ioutil.ReadAll(recorder.Result().Body) 101 Expect(err).ToNot(HaveOccurred()) 102 Expect(string(body)).To(Equal("Bad Gateway There was a problem connecting to the upstream server. /prefix/ 502 11111111-2222-4333-8444-555555555555 Custom Footer Text v0.0.0-test")) 103 }) 104 }) 105 106 Context("With Debug enabled", func() { 107 BeforeEach(func() { 108 tmpl, err := template.New("").Parse("{{.Message}}") 109 Expect(err).ToNot(HaveOccurred()) 110 111 errorPage.template = tmpl 112 errorPage.debug = true 113 }) 114 115 Context("WriteErrorPage", func() { 116 It("Writes the detailed error in place of the message", func() { 117 recorder := httptest.NewRecorder() 118 errorPage.WriteErrorPage(recorder, ErrorPageOpts{ 119 Status: 403, 120 RedirectURL: "/redirect", 121 AppError: "Debug error", 122 }) 123 124 body, err := ioutil.ReadAll(recorder.Result().Body) 125 Expect(err).ToNot(HaveOccurred()) 126 Expect(string(body)).To(Equal("Debug error")) 127 }) 128 }) 129 130 Context("ProxyErrorHandler", func() { 131 It("Writes a bad gateway error the response writer", func() { 132 req := httptest.NewRequest("", "/bad-gateway", nil) 133 req = middlewareapi.AddRequestScope(req, &middlewareapi.RequestScope{ 134 RequestID: testRequestID, 135 }) 136 recorder := httptest.NewRecorder() 137 errorPage.ProxyErrorHandler(recorder, req, errors.New("some upstream error")) 138 139 body, err := ioutil.ReadAll(recorder.Result().Body) 140 Expect(err).ToNot(HaveOccurred()) 141 Expect(string(body)).To(Equal("some upstream error")) 142 }) 143 }) 144 }) 145}) 146