19 "github.com/coreos/go-oidc"
20 "github.com/mbland/hmacauth"
21 "github.com/pusher/oauth2_proxy/pkg/apis/sessions"
22 "github.com/pusher/oauth2_proxy/pkg/logger"
23 "github.com/pusher/oauth2_proxy/pkg/sessions/cookie"
24 "github.com/pusher/oauth2_proxy/providers"
25 "github.com/stretchr/testify/assert"
26 "github.com/stretchr/testify/require"
27 "golang.org/x/net/websocket"
31 logger.SetFlags(logger.Lshortfile)
35type WebSocketOrRestHandler struct {
36 restHandler http.Handler
37 wsHandler http.Handler
40func (h *WebSocketOrRestHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
41 if r.Header.Get("Upgrade") == "websocket" {
42 h.wsHandler.ServeHTTP(w, r)
44 h.restHandler.ServeHTTP(w, r)
48func TestWebSocketProxy(t *testing.T) {
49 handler := WebSocketOrRestHandler{
50 restHandler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
52 hostname, _, _ := net.SplitHostPort(r.Host)
53 w.Write([]byte(hostname))
55 wsHandler: websocket.Handler(func(ws *websocket.Conn) {
58 err := websocket.Message.Receive(ws, &data)
60 t.Fatalf("err %s", err)
63 err = websocket.Message.Send(ws, data)
65 t.Fatalf("err %s", err)
70 backend := httptest.NewServer(&handler)
73 backendURL, _ := url.Parse(backend.URL)
75 options := NewOptions()
76 var auth hmacauth.HmacAuth
77 options.PassHostHeader = true
78 proxyHandler := NewWebSocketOrRestReverseProxy(backendURL, options, auth)
79 frontend := httptest.NewServer(proxyHandler)
80 defer frontend.Close()
82 frontendURL, _ := url.Parse(frontend.URL)
83 frontendWSURL := "ws://" + frontendURL.Host + "/"
85 ws, err := websocket.Dial(frontendWSURL, "", "http://localhost/")
87 t.Fatalf("err %s", err)
89 request := []byte("hello, world!")
90 err = websocket.Message.Send(ws, request)
92 t.Fatalf("err %s", err)
94 var response = make([]byte, 1024)
95 websocket.Message.Receive(ws, &response)
97 t.Fatalf("err %s", err)
99 if g, e := string(request), string(response); g != e {
100 t.Errorf("got body %q; expected %q", g, e)
103 getReq, _ := http.NewRequest("GET", frontend.URL, nil)
104 res, _ := http.DefaultClient.Do(getReq)
105 bodyBytes, _ := ioutil.ReadAll(res.Body)
106 backendHostname, _, _ := net.SplitHostPort(backendURL.Host)
107 if g, e := string(bodyBytes), backendHostname; g != e {
108 t.Errorf("got body %q; expected %q", g, e)
112func TestNewReverseProxy(t *testing.T) {
113 backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
115 hostname, _, _ := net.SplitHostPort(r.Host)
116 w.Write([]byte(hostname))
118 defer backend.Close()
120 backendURL, _ := url.Parse(backend.URL)
121 backendHostname, backendPort, _ := net.SplitHostPort(backendURL.Host)
122 backendHost := net.JoinHostPort(backendHostname, backendPort)
123 proxyURL, _ := url.Parse(backendURL.Scheme + "://" + backendHost + "/")
125 proxyHandler := NewReverseProxy(proxyURL, &Options{FlushInterval: time.Second})
126 setProxyUpstreamHostHeader(proxyHandler, proxyURL)
127 frontend := httptest.NewServer(proxyHandler)
128 defer frontend.Close()
130 getReq, _ := http.NewRequest("GET", frontend.URL, nil)
131 res, _ := http.DefaultClient.Do(getReq)
132 bodyBytes, _ := ioutil.ReadAll(res.Body)
133 if g, e := string(bodyBytes), backendHostname; g != e {
134 t.Errorf("got body %q; expected %q", g, e)
138func TestEncodedSlashes(t *testing.T) {
140 backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
144 defer backend.Close()
146 b, _ := url.Parse(backend.URL)
147 proxyHandler := NewReverseProxy(b, &Options{FlushInterval: time.Second})
148 setProxyDirector(proxyHandler)
149 frontend := httptest.NewServer(proxyHandler)
150 defer frontend.Close()
152 f, _ := url.Parse(frontend.URL)
153 encodedPath := "/a%2Fb/?c=1"
154 getReq := &http.Request{URL: &url.URL{Scheme: "http", Host: f.Host, Opaque: encodedPath}}
155 _, err := http.DefaultClient.Do(getReq)
157 t.Fatalf("err %s", err)
159 if seen != encodedPath {
160 t.Errorf("got bad request %q expected %q", seen, encodedPath)
164func TestRobotsTxt(t *testing.T) {
166 opts.ClientID = "asdlkjx"
167 opts.ClientSecret = "alkgks"
168 opts.CookieSecret = "asdkugkj"
171 proxy := NewOAuthProxy(opts, func(string) bool { return true })
172 rw := httptest.NewRecorder()
173 req, _ := http.NewRequest("GET", "/robots.txt", nil)
174 proxy.ServeHTTP(rw, req)
175 assert.Equal(t, 200, rw.Code)
176 assert.Equal(t, "User-agent: *\nDisallow: /", rw.Body.String())
179func TestIsValidRedirect(t *testing.T) {
181 opts.ClientID = "skdlfj"
182 opts.ClientSecret = "fgkdsgj"
183 opts.CookieSecret = "ljgiogbj"
184 // Should match domains that are exactly foo.bar and any subdomain of bar.foo
185 opts.WhitelistDomains = []string{
189 ".sub.port.bar:8080",
191 ".sub.anyport.bar:*",
195 proxy := NewOAuthProxy(opts, func(string) bool { return true })
197 testCases := []struct {
198 Desc, Redirect string
204 ExpectedResult: false,
208 Redirect: "/redirect",
209 ExpectedResult: true,
213 Redirect: "//redirect",
214 ExpectedResult: false,
218 Redirect: "http://foo.bar/redirect",
219 ExpectedResult: true,
223 Redirect: "https://foo.bar/redirect",
224 ExpectedResult: true,
227 Desc: "invalidHTTPSubdomain",
228 Redirect: "http://baz.foo.bar/redirect",
229 ExpectedResult: false,
232 Desc: "invalidHTTPSSubdomain",
233 Redirect: "https://baz.foo.bar/redirect",
234 ExpectedResult: false,
237 Desc: "validHTTPSubdomain",
238 Redirect: "http://baz.bar.foo/redirect",
239 ExpectedResult: true,
242 Desc: "validHTTPSSubdomain",
243 Redirect: "https://baz.bar.foo/redirect",
244 ExpectedResult: true,
247 Desc: "validHTTPDomain",
248 Redirect: "http://bar.foo/redirect",
249 ExpectedResult: true,
252 Desc: "invalidHTTP1",
253 Redirect: "http://foo.bar.evil.corp/redirect",
254 ExpectedResult: false,
257 Desc: "invalidHTTPS1",
258 Redirect: "https://foo.bar.evil.corp/redirect",
259 ExpectedResult: false,
262 Desc: "invalidHTTP2",
263 Redirect: "http://evil.corp/redirect?rd=foo.bar",
264 ExpectedResult: false,
267 Desc: "invalidHTTPS2",
268 Redirect: "https://evil.corp/redirect?rd=foo.bar",
269 ExpectedResult: false,
273 Redirect: "https://evil.corp:3838/redirect",
274 ExpectedResult: false,
277 Desc: "invalidEmptyPort",
278 Redirect: "http://foo.bar:3838/redirect",
279 ExpectedResult: false,
282 Desc: "invalidEmptyPortSubdomain",
283 Redirect: "http://baz.bar.foo:3838/redirect",
284 ExpectedResult: false,
287 Desc: "validSpecificPort",
288 Redirect: "http://port.bar:8080/redirect",
289 ExpectedResult: true,
292 Desc: "invalidSpecificPort",
293 Redirect: "http://port.bar:3838/redirect",
294 ExpectedResult: false,
297 Desc: "validSpecificPortSubdomain",
298 Redirect: "http://foo.sub.port.bar:8080/redirect",
299 ExpectedResult: true,
302 Desc: "invalidSpecificPortSubdomain",
303 Redirect: "http://foo.sub.port.bar:3838/redirect",
304 ExpectedResult: false,
307 Desc: "validAnyPort1",
308 Redirect: "http://anyport.bar:8080/redirect",
309 ExpectedResult: true,
312 Desc: "validAnyPort2",
313 Redirect: "http://anyport.bar:8081/redirect",
314 ExpectedResult: true,
317 Desc: "validAnyPortSubdomain1",
318 Redirect: "http://a.sub.anyport.bar:8080/redirect",
319 ExpectedResult: true,
322 Desc: "validAnyPortSubdomain2",
323 Redirect: "http://a.sub.anyport.bar:8081/redirect",
324 ExpectedResult: true,
328 for _, tc := range testCases {
329 t.Run(tc.Desc, func(t *testing.T) {
330 result := proxy.IsValidRedirect(tc.Redirect)
332 if result != tc.ExpectedResult {
333 t.Errorf("expected %t got %t", tc.ExpectedResult, result)
339type TestProvider struct {
340 *providers.ProviderData
343 GroupValidator func(string) bool
346func NewTestProvider(providerURL *url.URL, emailAddress string) *TestProvider {
347 return &TestProvider{
348 ProviderData: &providers.ProviderData{
349 ProviderName: "Test Provider",
352 Host: providerURL.Host,
353 Path: "/oauth/authorize",
357 Host: providerURL.Host,
358 Path: "/oauth/token",
360 ProfileURL: &url.URL{
362 Host: providerURL.Host,
363 Path: "/api/v1/profile",
365 Scope: "profile.email",
367 EmailAddress: emailAddress,
368 GroupValidator: func(s string) bool {
374func (tp *TestProvider) GetEmailAddress(session *sessions.SessionState) (string, error) {
375 return tp.EmailAddress, nil
378func (tp *TestProvider) ValidateSessionState(session *sessions.SessionState) bool {
382func (tp *TestProvider) ValidateGroup(email string) bool {
383 if tp.GroupValidator != nil {
384 return tp.GroupValidator(email)
389func TestBasicAuthPassword(t *testing.T) {
390 providerServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
391 logger.Printf("%#v", r)
395 payload = `{"access_token": "my_auth_token"}`
397 payload = r.Header.Get("Authorization")
399 payload = "No Authorization header found."
403 w.Write([]byte(payload))
406 opts.Upstreams = append(opts.Upstreams, providerServer.URL)
407 // The CookieSecret must be 32 bytes in order to create the AES
409 opts.CookieSecret = "xyzzyplughxyzzyplughxyzzyplughxp"
410 opts.ClientID = "dlgkj"
411 opts.ClientSecret = "alkgret"
412 opts.CookieSecure = false
413 opts.PassBasicAuth = true
414 opts.PassUserHeaders = true
415 opts.BasicAuthPassword = "This is a secure password"
418 providerURL, _ := url.Parse(providerServer.URL)
419 const emailAddress = "john.doe@example.com"
421 opts.provider = NewTestProvider(providerURL, emailAddress)
422 proxy := NewOAuthProxy(opts, func(email string) bool {
423 return email == emailAddress
426 rw := httptest.NewRecorder()
427 req, _ := http.NewRequest("GET", "/oauth2/callback?code=callback_code&state=nonce:",
428 strings.NewReader(""))
429 req.AddCookie(proxy.MakeCSRFCookie(req, "nonce", proxy.CookieExpire, time.Now()))
430 proxy.ServeHTTP(rw, req)
432 t.Fatalf("expected 3xx got %d", rw.Code)
434 cookie := rw.HeaderMap["Set-Cookie"][1]
436 cookieName := proxy.CookieName
438 keyPrefix := cookieName + "="
440 for _, field := range strings.Split(cookie, "; ") {
441 value = strings.TrimPrefix(field, keyPrefix)
449 req, _ = http.NewRequest("GET", "/", strings.NewReader(""))
450 req.AddCookie(&http.Cookie{
454 Expires: time.Now().Add(time.Duration(24)),
457 req.AddCookie(proxy.MakeCSRFCookie(req, "nonce", proxy.CookieExpire, time.Now()))
459 rw = httptest.NewRecorder()
460 proxy.ServeHTTP(rw, req)
462 // The username in the basic auth credentials is expected to be equal to the email address from the
463 // auth response, so we use the same variable here.
464 expectedHeader := "Basic " + base64.StdEncoding.EncodeToString([]byte(emailAddress+":"+opts.BasicAuthPassword))
465 assert.Equal(t, expectedHeader, rw.Body.String())
466 providerServer.Close()
469type PassAccessTokenTest struct {
470 providerServer *httptest.Server
475type PassAccessTokenTestOptions struct {
480func NewPassAccessTokenTest(opts PassAccessTokenTestOptions) *PassAccessTokenTest {
481 t := &PassAccessTokenTest{}
483 t.providerServer = httptest.NewServer(
484 http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
488 payload = `{"access_token": "my_auth_token"}`
490 payload = r.Header.Get("X-Forwarded-Access-Token")
492 payload = "No access token found."
496 w.Write([]byte(payload))
499 t.opts = NewOptions()
500 t.opts.Upstreams = append(t.opts.Upstreams, t.providerServer.URL)
501 if opts.ProxyUpstream != "" {
502 t.opts.Upstreams = append(t.opts.Upstreams, opts.ProxyUpstream)
504 // The CookieSecret must be 32 bytes in order to create the AES
506 t.opts.CookieSecret = "xyzzyplughxyzzyplughxyzzyplughxp"
507 t.opts.ClientID = "slgkj"
508 t.opts.ClientSecret = "gfjgojl"
509 t.opts.CookieSecure = false
510 t.opts.PassAccessToken = opts.PassAccessToken
513 providerURL, _ := url.Parse(t.providerServer.URL)
514 const emailAddress = "michael.bland@gsa.gov"
516 t.opts.provider = NewTestProvider(providerURL, emailAddress)
517 t.proxy = NewOAuthProxy(t.opts, func(email string) bool {
518 return email == emailAddress
523func (patTest *PassAccessTokenTest) Close() {
524 patTest.providerServer.Close()
527func (patTest *PassAccessTokenTest) getCallbackEndpoint() (httpCode int,
529 rw := httptest.NewRecorder()
530 req, err := http.NewRequest("GET", "/oauth2/callback?code=callback_code&state=nonce:",
531 strings.NewReader(""))
535 req.AddCookie(patTest.proxy.MakeCSRFCookie(req, "nonce", time.Hour, time.Now()))
536 patTest.proxy.ServeHTTP(rw, req)
537 return rw.Code, rw.HeaderMap["Set-Cookie"][1]
540// getEndpointWithCookie makes a requests againt the oauthproxy with passed requestPath
541// and cookie and returns body and status code.
542func (patTest *PassAccessTokenTest) getEndpointWithCookie(cookie string, endpoint string) (httpCode int, accessToken string) {
543 cookieName := patTest.proxy.CookieName
545 keyPrefix := cookieName + "="
547 for _, field := range strings.Split(cookie, "; ") {
548 value = strings.TrimPrefix(field, keyPrefix)
559 req, err := http.NewRequest("GET", endpoint, strings.NewReader(""))
563 req.AddCookie(&http.Cookie{
567 Expires: time.Now().Add(time.Duration(24)),
571 rw := httptest.NewRecorder()
572 patTest.proxy.ServeHTTP(rw, req)
573 return rw.Code, rw.Body.String()
576func TestForwardAccessTokenUpstream(t *testing.T) {
577 patTest := NewPassAccessTokenTest(PassAccessTokenTestOptions{
578 PassAccessToken: true,
580 defer patTest.Close()
582 // A successful validation will redirect and set the auth cookie.
583 code, cookie := patTest.getCallbackEndpoint()
585 t.Fatalf("expected 302; got %d", code)
587 assert.NotEqual(t, nil, cookie)
589 // Now we make a regular request; the access_token from the cookie is
590 // forwarded as the "X-Forwarded-Access-Token" header. The token is
591 // read by the test provider server and written in the response body.
592 code, payload := patTest.getEndpointWithCookie(cookie, "/")
594 t.Fatalf("expected 200; got %d", code)
596 assert.Equal(t, "my_auth_token", payload)
599func TestStaticProxyUpstream(t *testing.T) {
600 patTest := NewPassAccessTokenTest(PassAccessTokenTestOptions{
601 PassAccessToken: true,
602 ProxyUpstream: "static://200/static-proxy",
605 defer patTest.Close()
607 // A successful validation will redirect and set the auth cookie.
608 code, cookie := patTest.getCallbackEndpoint()
610 t.Fatalf("expected 302; got %d", code)
612 assert.NotEqual(t, nil, cookie)
614 // Now we make a regular request againts the upstream proxy; And validate
615 // the returned status code through the static proxy.
616 code, payload := patTest.getEndpointWithCookie(cookie, "/static-proxy")
618 t.Fatalf("expected 200; got %d", code)
620 assert.Equal(t, "Authenticated", payload)
623func TestDoNotForwardAccessTokenUpstream(t *testing.T) {
624 patTest := NewPassAccessTokenTest(PassAccessTokenTestOptions{
625 PassAccessToken: false,
627 defer patTest.Close()
629 // A successful validation will redirect and set the auth cookie.
630 code, cookie := patTest.getCallbackEndpoint()
632 t.Fatalf("expected 302; got %d", code)
634 assert.NotEqual(t, nil, cookie)
636 // Now we make a regular request, but the access token header should
638 code, payload := patTest.getEndpointWithCookie(cookie, "/")
640 t.Fatalf("expected 200; got %d", code)
642 assert.Equal(t, "No access token found.", payload)
645type SignInPageTest struct {
648 signInRegexp *regexp.Regexp
649 signInProviderRegexp *regexp.Regexp
652const signInRedirectPattern = `<input type="hidden" name="rd" value="(.*)">`
653const signInSkipProvider = `>Found<`
655func NewSignInPageTest(skipProvider bool) *SignInPageTest {
656 var sipTest SignInPageTest
658 sipTest.opts = NewOptions()
659 sipTest.opts.CookieSecret = "adklsj2"
660 sipTest.opts.ClientID = "lkdgj"
661 sipTest.opts.ClientSecret = "sgiufgoi"
662 sipTest.opts.SkipProviderButton = skipProvider
663 sipTest.opts.Validate()
665 sipTest.proxy = NewOAuthProxy(sipTest.opts, func(email string) bool {
668 sipTest.signInRegexp = regexp.MustCompile(signInRedirectPattern)
669 sipTest.signInProviderRegexp = regexp.MustCompile(signInSkipProvider)
674func (sipTest *SignInPageTest) GetEndpoint(endpoint string) (int, string) {
675 rw := httptest.NewRecorder()
676 req, _ := http.NewRequest("GET", endpoint, strings.NewReader(""))
677 sipTest.proxy.ServeHTTP(rw, req)
678 return rw.Code, rw.Body.String()
681func TestSignInPageIncludesTargetRedirect(t *testing.T) {
682 sipTest := NewSignInPageTest(false)
683 const endpoint = "/some/random/endpoint"
685 code, body := sipTest.GetEndpoint(endpoint)
686 assert.Equal(t, 403, code)
688 match := sipTest.signInRegexp.FindStringSubmatch(body)
690 t.Fatal("Did not find pattern in body: " +
691 signInRedirectPattern + "\nBody:\n" + body)
693 if match[1] != endpoint {
694 t.Fatal(`expected redirect to "` + endpoint +
695 `", but was "` + match[1] + `"`)
699func TestSignInPageDirectAccessRedirectsToRoot(t *testing.T) {
700 sipTest := NewSignInPageTest(false)
701 code, body := sipTest.GetEndpoint("/oauth2/sign_in")
702 assert.Equal(t, 200, code)
704 match := sipTest.signInRegexp.FindStringSubmatch(body)
706 t.Fatal("Did not find pattern in body: " +
707 signInRedirectPattern + "\nBody:\n" + body)
710 t.Fatal(`expected redirect to "/", but was "` + match[1] + `"`)
714func TestSignInPageSkipProvider(t *testing.T) {
715 sipTest := NewSignInPageTest(true)
716 const endpoint = "/some/random/endpoint"
718 code, body := sipTest.GetEndpoint(endpoint)
719 assert.Equal(t, 302, code)
721 match := sipTest.signInProviderRegexp.FindStringSubmatch(body)
723 t.Fatal("Did not find pattern in body: " +
724 signInSkipProvider + "\nBody:\n" + body)
728func TestSignInPageSkipProviderDirect(t *testing.T) {
729 sipTest := NewSignInPageTest(true)
730 const endpoint = "/sign_in"
732 code, body := sipTest.GetEndpoint(endpoint)
733 assert.Equal(t, 302, code)
735 match := sipTest.signInProviderRegexp.FindStringSubmatch(body)
737 t.Fatal("Did not find pattern in body: " +
738 signInSkipProvider + "\nBody:\n" + body)
742type ProcessCookieTest struct {
745 rw *httptest.ResponseRecorder
747 provider TestProvider
752type ProcessCookieTestOpts struct {
753 providerValidateCookieResponse bool
756type OptionsModifier func(*Options)
758func NewProcessCookieTest(opts ProcessCookieTestOpts, modifiers ...OptionsModifier) *ProcessCookieTest {
759 var pcTest ProcessCookieTest
761 pcTest.opts = NewOptions()
762 for _, modifier := range modifiers {
763 modifier(pcTest.opts)
765 pcTest.opts.ClientID = "asdfljk"
766 pcTest.opts.ClientSecret = "lkjfdsig"
767 pcTest.opts.CookieSecret = "0123456789abcdefabcd"
768 // First, set the CookieRefresh option so proxy.AesCipher is created,
769 // needed to encrypt the access_token.
770 pcTest.opts.CookieRefresh = time.Hour
771 pcTest.opts.Validate()
773 pcTest.proxy = NewOAuthProxy(pcTest.opts, func(email string) bool {
774 return pcTest.validateUser
776 pcTest.proxy.provider = &TestProvider{
777 ValidToken: opts.providerValidateCookieResponse,
780 // Now, zero-out proxy.CookieRefresh for the cases that don't involve
781 // access_token validation.
782 pcTest.proxy.CookieRefresh = time.Duration(0)
783 pcTest.rw = httptest.NewRecorder()
784 pcTest.req, _ = http.NewRequest("GET", "/", strings.NewReader(""))
785 pcTest.validateUser = true
789func NewProcessCookieTestWithDefaults() *ProcessCookieTest {
790 return NewProcessCookieTest(ProcessCookieTestOpts{
791 providerValidateCookieResponse: true,
795func NewProcessCookieTestWithOptionsModifiers(modifiers ...OptionsModifier) *ProcessCookieTest {
796 return NewProcessCookieTest(ProcessCookieTestOpts{
797 providerValidateCookieResponse: true,
801func (p *ProcessCookieTest) SaveSession(s *sessions.SessionState) error {
802 err := p.proxy.SaveSession(p.rw, p.req, s)
806 for _, cookie := range p.rw.Result().Cookies() {
807 p.req.AddCookie(cookie)
812func (p *ProcessCookieTest) LoadCookiedSession() (*sessions.SessionState, error) {
813 return p.proxy.LoadCookiedSession(p.req)
816func TestLoadCookiedSession(t *testing.T) {
817 pcTest := NewProcessCookieTestWithDefaults()
819 startSession := &sessions.SessionState{Email: "john.doe@example.com", AccessToken: "my_access_token", CreatedAt: time.Now()}
820 pcTest.SaveSession(startSession)
822 session, err := pcTest.LoadCookiedSession()
823 assert.Equal(t, nil, err)
824 assert.Equal(t, startSession.Email, session.Email)
825 assert.Equal(t, "john.doe@example.com", session.User)
826 assert.Equal(t, startSession.AccessToken, session.AccessToken)
829func TestProcessCookieNoCookieError(t *testing.T) {
830 pcTest := NewProcessCookieTestWithDefaults()
832 session, err := pcTest.LoadCookiedSession()
833 assert.Equal(t, "Cookie \"_oauth2_proxy\" not present", err.Error())
835 t.Errorf("expected nil session. got %#v", session)
839func TestProcessCookieRefreshNotSet(t *testing.T) {
840 pcTest := NewProcessCookieTestWithOptionsModifiers(func(opts *Options) {
841 opts.CookieExpire = time.Duration(23) * time.Hour
843 reference := time.Now().Add(time.Duration(-2) * time.Hour)
845 startSession := &sessions.SessionState{Email: "michael.bland@gsa.gov", AccessToken: "my_access_token", CreatedAt: reference}
846 pcTest.SaveSession(startSession)
848 session, err := pcTest.LoadCookiedSession()
849 assert.Equal(t, nil, err)
850 if session.Age() < time.Duration(-2)*time.Hour {
851 t.Errorf("cookie too young %v", session.Age())
853 assert.Equal(t, startSession.Email, session.Email)
856func TestProcessCookieFailIfCookieExpired(t *testing.T) {
857 pcTest := NewProcessCookieTestWithOptionsModifiers(func(opts *Options) {
858 opts.CookieExpire = time.Duration(24) * time.Hour
860 reference := time.Now().Add(time.Duration(25) * time.Hour * -1)
861 startSession := &sessions.SessionState{Email: "michael.bland@gsa.gov", AccessToken: "my_access_token", CreatedAt: reference}
862 pcTest.SaveSession(startSession)
864 session, err := pcTest.LoadCookiedSession()
865 assert.NotEqual(t, nil, err)
867 t.Errorf("expected nil session %#v", session)
871func TestProcessCookieFailIfRefreshSetAndCookieExpired(t *testing.T) {
872 pcTest := NewProcessCookieTestWithOptionsModifiers(func(opts *Options) {
873 opts.CookieExpire = time.Duration(24) * time.Hour
875 reference := time.Now().Add(time.Duration(25) * time.Hour * -1)
876 startSession := &sessions.SessionState{Email: "michael.bland@gsa.gov", AccessToken: "my_access_token", CreatedAt: reference}
877 pcTest.SaveSession(startSession)
879 pcTest.proxy.CookieRefresh = time.Hour
880 session, err := pcTest.LoadCookiedSession()
881 assert.NotEqual(t, nil, err)
883 t.Errorf("expected nil session %#v", session)
887func NewUserInfoEndpointTest() *ProcessCookieTest {
888 pcTest := NewProcessCookieTestWithDefaults()
889 pcTest.req, _ = http.NewRequest("GET",
890 pcTest.opts.ProxyPrefix+"/userinfo", nil)
894func TestUserInfoEndpointAccepted(t *testing.T) {
895 test := NewUserInfoEndpointTest()
896 startSession := &sessions.SessionState{
897 Email: "john.doe@example.com", AccessToken: "my_access_token"}
898 test.SaveSession(startSession)
900 test.proxy.ServeHTTP(test.rw, test.req)
901 assert.Equal(t, http.StatusOK, test.rw.Code)
902 bodyBytes, _ := ioutil.ReadAll(test.rw.Body)
903 assert.Equal(t, "{\"email\":\"john.doe@example.com\"}\n", string(bodyBytes))
906func TestUserInfoEndpointUnauthorizedOnNoCookieSetError(t *testing.T) {
907 test := NewUserInfoEndpointTest()
909 test.proxy.ServeHTTP(test.rw, test.req)
910 assert.Equal(t, http.StatusUnauthorized, test.rw.Code)
913func NewAuthOnlyEndpointTest(modifiers ...OptionsModifier) *ProcessCookieTest {
914 pcTest := NewProcessCookieTestWithOptionsModifiers(modifiers...)
915 pcTest.req, _ = http.NewRequest("GET",
916 pcTest.opts.ProxyPrefix+"/auth", nil)
920func TestAuthOnlyEndpointAccepted(t *testing.T) {
921 test := NewAuthOnlyEndpointTest()
922 startSession := &sessions.SessionState{
923 Email: "michael.bland@gsa.gov", AccessToken: "my_access_token", CreatedAt: time.Now()}
924 test.SaveSession(startSession)
926 test.proxy.ServeHTTP(test.rw, test.req)
927 assert.Equal(t, http.StatusAccepted, test.rw.Code)
928 bodyBytes, _ := ioutil.ReadAll(test.rw.Body)
929 assert.Equal(t, "", string(bodyBytes))
932func TestAuthOnlyEndpointUnauthorizedOnNoCookieSetError(t *testing.T) {
933 test := NewAuthOnlyEndpointTest()
935 test.proxy.ServeHTTP(test.rw, test.req)
936 assert.Equal(t, http.StatusUnauthorized, test.rw.Code)
937 bodyBytes, _ := ioutil.ReadAll(test.rw.Body)
938 assert.Equal(t, "unauthorized request\n", string(bodyBytes))
941func TestAuthOnlyEndpointUnauthorizedOnExpiration(t *testing.T) {
942 test := NewAuthOnlyEndpointTest(func(opts *Options) {
943 opts.CookieExpire = time.Duration(24) * time.Hour
945 reference := time.Now().Add(time.Duration(25) * time.Hour * -1)
946 startSession := &sessions.SessionState{
947 Email: "michael.bland@gsa.gov", AccessToken: "my_access_token", CreatedAt: reference}
948 test.SaveSession(startSession)
950 test.proxy.ServeHTTP(test.rw, test.req)
951 assert.Equal(t, http.StatusUnauthorized, test.rw.Code)
952 bodyBytes, _ := ioutil.ReadAll(test.rw.Body)
953 assert.Equal(t, "unauthorized request\n", string(bodyBytes))
956func TestAuthOnlyEndpointUnauthorizedOnEmailValidationFailure(t *testing.T) {
957 test := NewAuthOnlyEndpointTest()
958 startSession := &sessions.SessionState{
959 Email: "michael.bland@gsa.gov", AccessToken: "my_access_token", CreatedAt: time.Now()}
960 test.SaveSession(startSession)
961 test.validateUser = false
963 test.proxy.ServeHTTP(test.rw, test.req)
964 assert.Equal(t, http.StatusUnauthorized, test.rw.Code)
965 bodyBytes, _ := ioutil.ReadAll(test.rw.Body)
966 assert.Equal(t, "unauthorized request\n", string(bodyBytes))
969func TestAuthOnlyEndpointUnauthorizedOnProviderGroupValidationFailure(t *testing.T) {
970 test := NewAuthOnlyEndpointTest()
971 startSession := &sessions.SessionState{
972 Email: "michael.bland@gsa.gov", AccessToken: "my_access_token", CreatedAt: time.Now()}
973 test.SaveSession(startSession)
974 provider := &TestProvider{
976 GroupValidator: func(s string) bool {
981 test.proxy.provider = provider
982 test.proxy.ServeHTTP(test.rw, test.req)
983 assert.Equal(t, http.StatusUnauthorized, test.rw.Code)
984 bodyBytes, _ := ioutil.ReadAll(test.rw.Body)
985 assert.Equal(t, "unauthorized request\n", string(bodyBytes))
988func TestAuthOnlyEndpointSetXAuthRequestHeaders(t *testing.T) {
989 var pcTest ProcessCookieTest
991 pcTest.opts = NewOptions()
992 pcTest.opts.SetXAuthRequest = true
993 pcTest.opts.Validate()
995 pcTest.proxy = NewOAuthProxy(pcTest.opts, func(email string) bool {
996 return pcTest.validateUser
998 pcTest.proxy.provider = &TestProvider{
1002 pcTest.validateUser = true
1004 pcTest.rw = httptest.NewRecorder()
1005 pcTest.req, _ = http.NewRequest("GET",
1006 pcTest.opts.ProxyPrefix+"/auth", nil)
1008 startSession := &sessions.SessionState{
1009 User: "oauth_user", Email: "oauth_user@example.com", AccessToken: "oauth_token", CreatedAt: time.Now()}
1010 pcTest.SaveSession(startSession)
1012 pcTest.proxy.ServeHTTP(pcTest.rw, pcTest.req)
1013 assert.Equal(t, http.StatusAccepted, pcTest.rw.Code)
1014 assert.Equal(t, "oauth_user", pcTest.rw.HeaderMap["X-Auth-Request-User"][0])
1015 assert.Equal(t, "oauth_user@example.com", pcTest.rw.HeaderMap["X-Auth-Request-Email"][0])
1018func TestAuthSkippedForPreflightRequests(t *testing.T) {
1019 upstream := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
1021 w.Write([]byte("response"))
1023 defer upstream.Close()
1025 opts := NewOptions()
1026 opts.Upstreams = append(opts.Upstreams, upstream.URL)
1027 opts.ClientID = "aljsal"
1028 opts.ClientSecret = "jglkfsdgj"
1029 opts.CookieSecret = "dkfjgdls"
1030 opts.SkipAuthPreflight = true
1033 upstreamURL, _ := url.Parse(upstream.URL)
1034 opts.provider = NewTestProvider(upstreamURL, "")
1036 proxy := NewOAuthProxy(opts, func(string) bool { return false })
1037 rw := httptest.NewRecorder()
1038 req, _ := http.NewRequest("OPTIONS", "/preflight-request", nil)
1039 proxy.ServeHTTP(rw, req)
1041 assert.Equal(t, 200, rw.Code)
1042 assert.Equal(t, "response", rw.Body.String())
1045type SignatureAuthenticator struct {
1046 auth hmacauth.HmacAuth
1049func (v *SignatureAuthenticator) Authenticate(w http.ResponseWriter, r *http.Request) {
1050 result, headerSig, computedSig := v.auth.AuthenticateRequest(r)
1051 if result == hmacauth.ResultNoSignature {
1052 w.Write([]byte("no signature received"))
1053 } else if result == hmacauth.ResultMatch {
1054 w.Write([]byte("signatures match"))
1055 } else if result == hmacauth.ResultMismatch {
1056 w.Write([]byte("signatures do not match:" +
1057 "\n received: " + headerSig +
1058 "\n computed: " + computedSig))
1060 panic("Unknown result value: " + result.String())
1064type SignatureTest struct {
1066 upstream *httptest.Server
1068 provider *httptest.Server
1070 rw *httptest.ResponseRecorder
1071 authenticator *SignatureAuthenticator
1074func NewSignatureTest() *SignatureTest {
1075 opts := NewOptions()
1076 opts.CookieSecret = "cookie secret"
1077 opts.ClientID = "client ID"
1078 opts.ClientSecret = "client secret"
1079 opts.EmailDomains = []string{"acm.org"}
1081 authenticator := &SignatureAuthenticator{}
1082 upstream := httptest.NewServer(
1083 http.HandlerFunc(authenticator.Authenticate))
1084 upstreamURL, _ := url.Parse(upstream.URL)
1085 opts.Upstreams = append(opts.Upstreams, upstream.URL)
1087 providerHandler := func(w http.ResponseWriter, r *http.Request) {
1088 w.Write([]byte(`{"access_token": "my_auth_token"}`))
1090 provider := httptest.NewServer(http.HandlerFunc(providerHandler))
1091 providerURL, _ := url.Parse(provider.URL)
1092 opts.provider = NewTestProvider(providerURL, "mbland@acm.org")
1094 return &SignatureTest{
1100 httptest.NewRecorder(),
1105func (st *SignatureTest) Close() {
1110// fakeNetConn simulates an http.Request.Body buffer that will be consumed
1111// when it is read by the hmacauth.HmacAuth if not handled properly. See:
1112// https://github.com/18F/hmacauth/pull/4
1113type fakeNetConn struct {
1117func (fnc *fakeNetConn) Read(p []byte) (n int, err error) {
1118 if bodyLen := len(fnc.reqBody); bodyLen != 0 {
1119 copy(p, fnc.reqBody)
1121 return bodyLen, io.EOF
1126func (st *SignatureTest) MakeRequestWithExpectedKey(method, body, key string) {
1127 err := st.opts.Validate()
1131 proxy := NewOAuthProxy(st.opts, func(email string) bool { return true })
1133 var bodyBuf io.ReadCloser
1135 bodyBuf = ioutil.NopCloser(&fakeNetConn{reqBody: body})
1137 req := httptest.NewRequest(method, "/foo/bar", bodyBuf)
1138 req.Header = st.header
1140 state := &sessions.SessionState{
1141 Email: "mbland@acm.org", AccessToken: "my_access_token"}
1142 err = proxy.SaveSession(st.rw, req, state)
1146 for _, c := range st.rw.Result().Cookies() {
1149 // This is used by the upstream to validate the signature.
1150 st.authenticator.auth = hmacauth.NewHmacAuth(
1151 crypto.SHA1, []byte(key), SignatureHeader, SignatureHeaders)
1152 proxy.ServeHTTP(st.rw, req)
1155func TestNoRequestSignature(t *testing.T) {
1156 st := NewSignatureTest()
1158 st.MakeRequestWithExpectedKey("GET", "", "")
1159 assert.Equal(t, 200, st.rw.Code)
1160 assert.Equal(t, st.rw.Body.String(), "no signature received")
1163func TestRequestSignatureGetRequest(t *testing.T) {
1164 st := NewSignatureTest()
1166 st.opts.SignatureKey = "sha1:7d9e1aa87a5954e6f9fc59266b3af9d7c35fda2d"
1167 st.MakeRequestWithExpectedKey("GET", "", "7d9e1aa87a5954e6f9fc59266b3af9d7c35fda2d")
1168 assert.Equal(t, 200, st.rw.Code)
1169 assert.Equal(t, st.rw.Body.String(), "signatures match")
1172func TestRequestSignaturePostRequest(t *testing.T) {
1173 st := NewSignatureTest()
1175 st.opts.SignatureKey = "sha1:d90df39e2d19282840252612dd7c81421a372f61"
1176 payload := `{ "hello": "world!" }`
1177 st.MakeRequestWithExpectedKey("POST", payload, "d90df39e2d19282840252612dd7c81421a372f61")
1178 assert.Equal(t, 200, st.rw.Code)
1179 assert.Equal(t, st.rw.Body.String(), "signatures match")
1182func TestGetRedirect(t *testing.T) {
1183 options := NewOptions()
1184 _ = options.Validate()
1185 require.NotEmpty(t, options.ProxyPrefix)
1186 proxy := NewOAuthProxy(options, func(s string) bool { return false })
1191 expectedRedirect string
1194 name: "request outside of ProxyPrefix redirects to original URL",
1196 expectedRedirect: "/foo/bar",
1199 name: "request under ProxyPrefix redirects to root",
1200 url: proxy.ProxyPrefix + "/foo/bar",
1201 expectedRedirect: "/",
1204 for _, tt := range tests {
1205 t.Run(tt.name, func(t *testing.T) {
1206 req, _ := http.NewRequest("GET", tt.url, nil)
1207 redirect, err := proxy.GetRedirect(req)
1209 assert.NoError(t, err)
1210 assert.Equal(t, tt.expectedRedirect, redirect)
1215type ajaxRequestTest struct {
1220func newAjaxRequestTest() *ajaxRequestTest {
1221 test := &ajaxRequestTest{}
1222 test.opts = NewOptions()
1223 test.opts.CookieSecret = "sdflsw"
1224 test.opts.ClientID = "gkljfdl"
1225 test.opts.ClientSecret = "sdflkjs"
1226 test.opts.Validate()
1227 test.proxy = NewOAuthProxy(test.opts, func(email string) bool {
1233func (test *ajaxRequestTest) getEndpoint(endpoint string, header http.Header) (int, http.Header, error) {
1234 rw := httptest.NewRecorder()
1235 req, err := http.NewRequest(http.MethodGet, endpoint, strings.NewReader(""))
1240 test.proxy.ServeHTTP(rw, req)
1241 return rw.Code, rw.Header(), nil
1244func testAjaxUnauthorizedRequest(t *testing.T, header http.Header) {
1245 test := newAjaxRequestTest()
1248 code, rh, err := test.getEndpoint(endpoint, header)
1249 assert.NoError(t, err)
1250 assert.Equal(t, http.StatusUnauthorized, code)
1251 mime := rh.Get("Content-Type")
1252 assert.Equal(t, applicationJSON, mime)
1254func TestAjaxUnauthorizedRequest1(t *testing.T) {
1255 header := make(http.Header)
1256 header.Add("accept", applicationJSON)
1258 testAjaxUnauthorizedRequest(t, header)
1261func TestAjaxUnauthorizedRequest2(t *testing.T) {
1262 header := make(http.Header)
1263 header.Add("Accept", applicationJSON)
1265 testAjaxUnauthorizedRequest(t, header)
1268func TestAjaxForbiddendRequest(t *testing.T) {
1269 test := newAjaxRequestTest()
1271 header := make(http.Header)
1272 code, rh, err := test.getEndpoint(endpoint, header)
1273 assert.NoError(t, err)
1274 assert.Equal(t, http.StatusForbidden, code)
1275 mime := rh.Get("Content-Type")
1276 assert.NotEqual(t, applicationJSON, mime)
1279func TestClearSplitCookie(t *testing.T) {
1280 opts := NewOptions()
1281 opts.CookieName = "oauth2"
1282 opts.CookieDomain = "abc"
1283 store, err := cookie.NewCookieSessionStore(&opts.SessionOptions, &opts.CookieOptions)
1284 assert.Equal(t, err, nil)
1285 p := OAuthProxy{CookieName: opts.CookieName, CookieDomain: opts.CookieDomain, sessionStore: store}
1286 var rw = httptest.NewRecorder()
1287 req := httptest.NewRequest("get", "/", nil)
1289 req.AddCookie(&http.Cookie{
1293 req.AddCookie(&http.Cookie{
1297 req.AddCookie(&http.Cookie{
1302 p.ClearSessionCookie(rw, req)
1303 header := rw.Header()
1305 assert.Equal(t, 2, len(header["Set-Cookie"]), "should have 3 set-cookie header entries")
1308func TestClearSingleCookie(t *testing.T) {
1309 opts := NewOptions()
1310 opts.CookieName = "oauth2"
1311 opts.CookieDomain = "abc"
1312 store, err := cookie.NewCookieSessionStore(&opts.SessionOptions, &opts.CookieOptions)
1313 assert.Equal(t, err, nil)
1314 p := OAuthProxy{CookieName: opts.CookieName, CookieDomain: opts.CookieDomain, sessionStore: store}
1315 var rw = httptest.NewRecorder()
1316 req := httptest.NewRequest("get", "/", nil)
1318 req.AddCookie(&http.Cookie{
1322 req.AddCookie(&http.Cookie{
1327 p.ClearSessionCookie(rw, req)
1328 header := rw.Header()
1330 assert.Equal(t, 1, len(header["Set-Cookie"]), "should have 1 set-cookie header entries")
1333type NoOpKeySet struct {
1336func (NoOpKeySet) VerifySignature(ctx context.Context, jwt string) (payload []byte, err error) {
1337 splitStrings := strings.Split(jwt, ".")
1338 payloadString := splitStrings[1]
1339 jsonString, err := base64.RawURLEncoding.DecodeString(payloadString)
1340 return []byte(jsonString), err
1343func TestGetJwtSession(t *testing.T) {
1346 "sub": "1234567890",
1347 "aud": "https://test.myapp.com",
1349 "email": "john@example.com",
1350 "iss": "https://issuer.example.com",
1355 goodJwt := "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9." +
1356 "eyJzdWIiOiIxMjM0NTY3ODkwIiwiYXVkIjoiaHR0cHM6Ly90ZXN0Lm15YXBwLmNvbSIsIm5hbWUiOiJKb2huIERvZSIsImVtY" +
1357 "WlsIjoiam9obkBleGFtcGxlLmNvbSIsImlzcyI6Imh0dHBzOi8vaXNzdWVyLmV4YW1wbGUuY29tIiwiaWF0IjoxNTUzNjkxMj" +
1358 "E1LCJleHAiOjE5MTIxNTE4MjF9." +
1359 "rLVyzOnEldUq_pNkfa-WiV8TVJYWyZCaM2Am_uo8FGg11zD7l-qmz3x1seTvqpH6Y0Ty00fmv6dJnGnC8WMnPXQiodRTfhBSe" +
1360 "OKZMu0HkMD2sg52zlKkbfLTO6ic5VnbVgwjjrB8am_Ta6w7kyFUaB5C1BsIrrLMldkWEhynbb8"
1362 keyset := NoOpKeySet{}
1363 verifier := oidc.NewVerifier("https://issuer.example.com", keyset,
1364 &oidc.Config{ClientID: "https://test.myapp.com", SkipExpiryCheck: true})
1366 test := NewAuthOnlyEndpointTest(func(opts *Options) {
1367 opts.PassAuthorization = true
1368 opts.SetAuthorization = true
1369 opts.SetXAuthRequest = true
1370 opts.SkipJwtBearerTokens = true
1371 opts.jwtBearerVerifiers = append(opts.jwtBearerVerifiers, verifier)
1373 tp, _ := test.proxy.provider.(*TestProvider)
1374 tp.GroupValidator = func(s string) bool {
1378 authHeader := fmt.Sprintf("Bearer %s", goodJwt)
1379 test.req.Header = map[string][]string{
1380 "Authorization": {authHeader},
1384 session, _ := test.proxy.GetJwtSession(test.req)
1385 assert.Equal(t, session.User, "john@example.com")
1386 assert.Equal(t, session.Email, "john@example.com")
1387 assert.Equal(t, session.ExpiresOn, time.Unix(1912151821, 0))
1388 assert.Equal(t, session.IDToken, goodJwt)
1390 test.proxy.ServeHTTP(test.rw, test.req)
1391 if test.rw.Code >= 400 {
1392 t.Fatalf("expected 3xx got %d", test.rw.Code)
1395 // Check PassAuthorization, should overwrite Basic header
1396 assert.Equal(t, test.req.Header.Get("Authorization"), authHeader)
1397 assert.Equal(t, test.req.Header.Get("X-Forwarded-User"), "john@example.com")
1398 assert.Equal(t, test.req.Header.Get("X-Forwarded-Email"), "john@example.com")
1400 // SetAuthorization and SetXAuthRequest
1401 assert.Equal(t, test.rw.Header().Get("Authorization"), authHeader)
1402 assert.Equal(t, test.rw.Header().Get("X-Auth-Request-User"), "john@example.com")
1403 assert.Equal(t, test.rw.Header().Get("X-Auth-Request-Email"), "john@example.com")
1406func TestJwtUnauthorizedOnGroupValidationFailure(t *testing.T) {
1407 goodJwt := "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9." +
1408 "eyJzdWIiOiIxMjM0NTY3ODkwIiwiYXVkIjoiaHR0cHM6Ly90ZXN0Lm15YXBwLmNvbSIsIm5hbWUiOiJKb2huIERvZSIsImVtY" +
1409 "WlsIjoiam9obkBleGFtcGxlLmNvbSIsImlzcyI6Imh0dHBzOi8vaXNzdWVyLmV4YW1wbGUuY29tIiwiaWF0IjoxNTUzNjkxMj" +
1410 "E1LCJleHAiOjE5MTIxNTE4MjF9." +
1411 "rLVyzOnEldUq_pNkfa-WiV8TVJYWyZCaM2Am_uo8FGg11zD7l-qmz3x1seTvqpH6Y0Ty00fmv6dJnGnC8WMnPXQiodRTfhBSe" +
1412 "OKZMu0HkMD2sg52zlKkbfLTO6ic5VnbVgwjjrB8am_Ta6w7kyFUaB5C1BsIrrLMldkWEhynbb8"
1414 keyset := NoOpKeySet{}
1415 verifier := oidc.NewVerifier("https://issuer.example.com", keyset,
1416 &oidc.Config{ClientID: "https://test.myapp.com", SkipExpiryCheck: true})
1418 test := NewAuthOnlyEndpointTest(func(opts *Options) {
1419 opts.PassAuthorization = true
1420 opts.SetAuthorization = true
1421 opts.SetXAuthRequest = true
1422 opts.SkipJwtBearerTokens = true
1423 opts.jwtBearerVerifiers = append(opts.jwtBearerVerifiers, verifier)
1425 tp, _ := test.proxy.provider.(*TestProvider)
1426 // Verify ValidateGroup fails JWT authorization
1427 tp.GroupValidator = func(s string) bool {
1431 authHeader := fmt.Sprintf("Bearer %s", goodJwt)
1432 test.req.Header = map[string][]string{
1433 "Authorization": {authHeader},
1435 test.proxy.ServeHTTP(test.rw, test.req)
1436 if test.rw.Code != http.StatusUnauthorized {
1437 t.Fatalf("expected 401 got %d", test.rw.Code)
1441func TestFindJwtBearerToken(t *testing.T) {
1442 p := OAuthProxy{CookieName: "oauth2", CookieDomain: "abc"}
1443 getReq := &http.Request{URL: &url.URL{Scheme: "http", Host: "example.com"}}
1445 validToken := "eyJfoobar.eyJfoobar.12345asdf"
1449 getReq.Header = map[string][]string{
1450 "Authorization": {fmt.Sprintf("Bearer %s", validToken)},
1453 token, _ = p.findBearerToken(getReq)
1454 assert.Equal(t, validToken, token)
1456 // Basic - no password
1457 getReq.SetBasicAuth(token, "")
1458 token, _ = p.findBearerToken(getReq)
1459 assert.Equal(t, validToken, token)
1461 // Basic - sentinel password
1462 getReq.SetBasicAuth(token, "x-oauth-basic")
1463 token, _ = p.findBearerToken(getReq)
1464 assert.Equal(t, validToken, token)
1466 // Basic - any username, password matching jwt pattern
1467 getReq.SetBasicAuth("any-username-you-could-wish-for", token)
1468 token, _ = p.findBearerToken(getReq)
1469 assert.Equal(t, validToken, token)
1471 failures := []string{
1473 "eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.dGVzdA.dGVzdA.dGVzdA.dGVzdA.dGVzdA",
1475 "eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.dGVzdA.dGVzdA.dGVzdA",
1476 // Invalid encrypted key
1477 "eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.//////.dGVzdA.dGVzdA.dGVzdA",
1479 "eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.dGVzdA.//////.dGVzdA.dGVzdA",
1480 // Invalid ciphertext
1481 "eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.dGVzdA.dGVzdA.//////.dGVzdA",
1483 "eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.dGVzdA.dGVzdA.dGVzdA.//////",
1485 "W10.dGVzdA.dGVzdA.dGVzdA.dGVzdA",
1487 "######.dGVzdA.dGVzdA.dGVzdA.dGVzdA",
1488 // Missing alc/enc params
1489 "e30.dGVzdA.dGVzdA.dGVzdA.dGVzdA",
1492 for _, failure := range failures {
1493 getReq.Header = map[string][]string{
1494 "Authorization": {fmt.Sprintf("Bearer %s", failure)},
1496 _, err := p.findBearerToken(getReq)
1497 assert.Error(t, err)
1500 fmt.Printf("%s", token)
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list