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 TestBasicAuthPassword(t *testing.T) {
383 providerServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
384 logger.Printf("%#v", r)
388 payload = `{"access_token": "my_auth_token"}`
390 payload = r.Header.Get("Authorization")
392 payload = "No Authorization header found."
396 w.Write([]byte(payload))
399 opts.Upstreams = append(opts.Upstreams, providerServer.URL)
400 // The CookieSecret must be 32 bytes in order to create the AES
402 opts.CookieSecret = "xyzzyplughxyzzyplughxyzzyplughxp"
403 opts.ClientID = "dlgkj"
404 opts.ClientSecret = "alkgret"
405 opts.CookieSecure = false
406 opts.PassBasicAuth = true
407 opts.PassUserHeaders = true
408 opts.PreferEmailToUser = true
409 opts.BasicAuthPassword = "This is a secure password"
412 providerURL, _ := url.Parse(providerServer.URL)
413 const emailAddress = "john.doe@example.com"
415 opts.provider = NewTestProvider(providerURL, emailAddress)
416 proxy := NewOAuthProxy(opts, func(email string) bool {
417 return email == emailAddress
420 rw := httptest.NewRecorder()
421 req, _ := http.NewRequest("GET", "/oauth2/callback?code=callback_code&state=nonce:",
422 strings.NewReader(""))
423 req.AddCookie(proxy.MakeCSRFCookie(req, "nonce", proxy.CookieExpire, time.Now()))
424 proxy.ServeHTTP(rw, req)
426 t.Fatalf("expected 3xx got %d", rw.Code)
428 cookie := rw.HeaderMap["Set-Cookie"][1]
430 cookieName := proxy.CookieName
432 keyPrefix := cookieName + "="
434 for _, field := range strings.Split(cookie, "; ") {
435 value = strings.TrimPrefix(field, keyPrefix)
443 req, _ = http.NewRequest("GET", "/", strings.NewReader(""))
444 req.AddCookie(&http.Cookie{
448 Expires: time.Now().Add(time.Duration(24)),
451 req.AddCookie(proxy.MakeCSRFCookie(req, "nonce", proxy.CookieExpire, time.Now()))
453 rw = httptest.NewRecorder()
454 proxy.ServeHTTP(rw, req)
456 // The username in the basic auth credentials is expected to be equal to the email address from the
457 // auth response, so we use the same variable here.
458 expectedHeader := "Basic " + base64.StdEncoding.EncodeToString([]byte(emailAddress+":"+opts.BasicAuthPassword))
459 assert.Equal(t, expectedHeader, rw.Body.String())
460 providerServer.Close()
463func TestBasicAuthWithEmail(t *testing.T) {
465 opts.PassBasicAuth = true
466 opts.PassUserHeaders = false
467 opts.PreferEmailToUser = false
468 opts.BasicAuthPassword = "This is a secure password"
471 const emailAddress = "john.doe@example.com"
472 const userName = "9fcab5c9b889a557"
474 // The username in the basic auth credentials is expected to be equal to the email address from the
475 expectedEmailHeader := "Basic " + base64.StdEncoding.EncodeToString([]byte(emailAddress+":"+opts.BasicAuthPassword))
476 expectedUserHeader := "Basic " + base64.StdEncoding.EncodeToString([]byte(userName+":"+opts.BasicAuthPassword))
478 session := &sessions.SessionState{
481 AccessToken: "oauth_token",
482 CreatedAt: time.Now(),
485 rw := httptest.NewRecorder()
486 req, _ := http.NewRequest("GET", opts.ProxyPrefix+"/testCase0", nil)
487 proxy := NewOAuthProxy(opts, func(email string) bool {
488 return email == emailAddress
490 proxy.addHeadersForProxying(rw, req, session)
491 assert.Equal(t, expectedUserHeader, req.Header["Authorization"][0])
492 assert.Equal(t, userName, req.Header["X-Forwarded-User"][0])
495 opts.PreferEmailToUser = true
497 rw := httptest.NewRecorder()
498 req, _ := http.NewRequest("GET", opts.ProxyPrefix+"/testCase1", nil)
500 proxy := NewOAuthProxy(opts, func(email string) bool {
501 return email == emailAddress
503 proxy.addHeadersForProxying(rw, req, session)
504 assert.Equal(t, expectedEmailHeader, req.Header["Authorization"][0])
505 assert.Equal(t, emailAddress, req.Header["X-Forwarded-User"][0])
509func TestPassUserHeadersWithEmail(t *testing.T) {
511 opts.PassBasicAuth = false
512 opts.PassUserHeaders = true
513 opts.PreferEmailToUser = false
516 const emailAddress = "john.doe@example.com"
517 const userName = "9fcab5c9b889a557"
519 session := &sessions.SessionState{
522 AccessToken: "oauth_token",
523 CreatedAt: time.Now(),
526 rw := httptest.NewRecorder()
527 req, _ := http.NewRequest("GET", opts.ProxyPrefix+"/testCase0", nil)
528 proxy := NewOAuthProxy(opts, func(email string) bool {
529 return email == emailAddress
531 proxy.addHeadersForProxying(rw, req, session)
532 assert.Equal(t, userName, req.Header["X-Forwarded-User"][0])
535 opts.PreferEmailToUser = true
537 rw := httptest.NewRecorder()
538 req, _ := http.NewRequest("GET", opts.ProxyPrefix+"/testCase1", nil)
540 proxy := NewOAuthProxy(opts, func(email string) bool {
541 return email == emailAddress
543 proxy.addHeadersForProxying(rw, req, session)
544 assert.Equal(t, emailAddress, req.Header["X-Forwarded-User"][0])
548type PassAccessTokenTest struct {
549 providerServer *httptest.Server
554type PassAccessTokenTestOptions struct {
559func NewPassAccessTokenTest(opts PassAccessTokenTestOptions) *PassAccessTokenTest {
560 t := &PassAccessTokenTest{}
562 t.providerServer = httptest.NewServer(
563 http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
567 payload = `{"access_token": "my_auth_token"}`
569 payload = r.Header.Get("X-Forwarded-Access-Token")
571 payload = "No access token found."
575 w.Write([]byte(payload))
578 t.opts = NewOptions()
579 t.opts.Upstreams = append(t.opts.Upstreams, t.providerServer.URL)
580 if opts.ProxyUpstream != "" {
581 t.opts.Upstreams = append(t.opts.Upstreams, opts.ProxyUpstream)
583 // The CookieSecret must be 32 bytes in order to create the AES
585 t.opts.CookieSecret = "xyzzyplughxyzzyplughxyzzyplughxp"
586 t.opts.ClientID = "slgkj"
587 t.opts.ClientSecret = "gfjgojl"
588 t.opts.CookieSecure = false
589 t.opts.PassAccessToken = opts.PassAccessToken
592 providerURL, _ := url.Parse(t.providerServer.URL)
593 const emailAddress = "michael.bland@gsa.gov"
595 t.opts.provider = NewTestProvider(providerURL, emailAddress)
596 t.proxy = NewOAuthProxy(t.opts, func(email string) bool {
597 return email == emailAddress
602func (patTest *PassAccessTokenTest) Close() {
603 patTest.providerServer.Close()
606func (patTest *PassAccessTokenTest) getCallbackEndpoint() (httpCode int,
608 rw := httptest.NewRecorder()
609 req, err := http.NewRequest("GET", "/oauth2/callback?code=callback_code&state=nonce:",
610 strings.NewReader(""))
614 req.AddCookie(patTest.proxy.MakeCSRFCookie(req, "nonce", time.Hour, time.Now()))
615 patTest.proxy.ServeHTTP(rw, req)
616 return rw.Code, rw.HeaderMap["Set-Cookie"][1]
619// getEndpointWithCookie makes a requests againt the oauthproxy with passed requestPath
620// and cookie and returns body and status code.
621func (patTest *PassAccessTokenTest) getEndpointWithCookie(cookie string, endpoint string) (httpCode int, accessToken string) {
622 cookieName := patTest.proxy.CookieName
624 keyPrefix := cookieName + "="
626 for _, field := range strings.Split(cookie, "; ") {
627 value = strings.TrimPrefix(field, keyPrefix)
638 req, err := http.NewRequest("GET", endpoint, strings.NewReader(""))
642 req.AddCookie(&http.Cookie{
646 Expires: time.Now().Add(time.Duration(24)),
650 rw := httptest.NewRecorder()
651 patTest.proxy.ServeHTTP(rw, req)
652 return rw.Code, rw.Body.String()
655func TestForwardAccessTokenUpstream(t *testing.T) {
656 patTest := NewPassAccessTokenTest(PassAccessTokenTestOptions{
657 PassAccessToken: true,
659 defer patTest.Close()
661 // A successful validation will redirect and set the auth cookie.
662 code, cookie := patTest.getCallbackEndpoint()
664 t.Fatalf("expected 302; got %d", code)
666 assert.NotEqual(t, nil, cookie)
668 // Now we make a regular request; the access_token from the cookie is
669 // forwarded as the "X-Forwarded-Access-Token" header. The token is
670 // read by the test provider server and written in the response body.
671 code, payload := patTest.getEndpointWithCookie(cookie, "/")
673 t.Fatalf("expected 200; got %d", code)
675 assert.Equal(t, "my_auth_token", payload)
678func TestStaticProxyUpstream(t *testing.T) {
679 patTest := NewPassAccessTokenTest(PassAccessTokenTestOptions{
680 PassAccessToken: true,
681 ProxyUpstream: "static://200/static-proxy",
684 defer patTest.Close()
686 // A successful validation will redirect and set the auth cookie.
687 code, cookie := patTest.getCallbackEndpoint()
689 t.Fatalf("expected 302; got %d", code)
691 assert.NotEqual(t, nil, cookie)
693 // Now we make a regular request againts the upstream proxy; And validate
694 // the returned status code through the static proxy.
695 code, payload := patTest.getEndpointWithCookie(cookie, "/static-proxy")
697 t.Fatalf("expected 200; got %d", code)
699 assert.Equal(t, "Authenticated", payload)
702func TestDoNotForwardAccessTokenUpstream(t *testing.T) {
703 patTest := NewPassAccessTokenTest(PassAccessTokenTestOptions{
704 PassAccessToken: false,
706 defer patTest.Close()
708 // A successful validation will redirect and set the auth cookie.
709 code, cookie := patTest.getCallbackEndpoint()
711 t.Fatalf("expected 302; got %d", code)
713 assert.NotEqual(t, nil, cookie)
715 // Now we make a regular request, but the access token header should
717 code, payload := patTest.getEndpointWithCookie(cookie, "/")
719 t.Fatalf("expected 200; got %d", code)
721 assert.Equal(t, "No access token found.", payload)
724type SignInPageTest struct {
727 signInRegexp *regexp.Regexp
728 signInProviderRegexp *regexp.Regexp
731const signInRedirectPattern = `<input type="hidden" name="rd" value="(.*)">`
732const signInSkipProvider = `>Found<`
734func NewSignInPageTest(skipProvider bool) *SignInPageTest {
735 var sipTest SignInPageTest
737 sipTest.opts = NewOptions()
738 sipTest.opts.CookieSecret = "adklsj2"
739 sipTest.opts.ClientID = "lkdgj"
740 sipTest.opts.ClientSecret = "sgiufgoi"
741 sipTest.opts.SkipProviderButton = skipProvider
742 sipTest.opts.Validate()
744 sipTest.proxy = NewOAuthProxy(sipTest.opts, func(email string) bool {
747 sipTest.signInRegexp = regexp.MustCompile(signInRedirectPattern)
748 sipTest.signInProviderRegexp = regexp.MustCompile(signInSkipProvider)
753func (sipTest *SignInPageTest) GetEndpoint(endpoint string) (int, string) {
754 rw := httptest.NewRecorder()
755 req, _ := http.NewRequest("GET", endpoint, strings.NewReader(""))
756 sipTest.proxy.ServeHTTP(rw, req)
757 return rw.Code, rw.Body.String()
760func TestSignInPageIncludesTargetRedirect(t *testing.T) {
761 sipTest := NewSignInPageTest(false)
762 const endpoint = "/some/random/endpoint"
764 code, body := sipTest.GetEndpoint(endpoint)
765 assert.Equal(t, 403, code)
767 match := sipTest.signInRegexp.FindStringSubmatch(body)
769 t.Fatal("Did not find pattern in body: " +
770 signInRedirectPattern + "\nBody:\n" + body)
772 if match[1] != endpoint {
773 t.Fatal(`expected redirect to "` + endpoint +
774 `", but was "` + match[1] + `"`)
778func TestSignInPageDirectAccessRedirectsToRoot(t *testing.T) {
779 sipTest := NewSignInPageTest(false)
780 code, body := sipTest.GetEndpoint("/oauth2/sign_in")
781 assert.Equal(t, 200, code)
783 match := sipTest.signInRegexp.FindStringSubmatch(body)
785 t.Fatal("Did not find pattern in body: " +
786 signInRedirectPattern + "\nBody:\n" + body)
789 t.Fatal(`expected redirect to "/", but was "` + match[1] + `"`)
793func TestSignInPageSkipProvider(t *testing.T) {
794 sipTest := NewSignInPageTest(true)
795 const endpoint = "/some/random/endpoint"
797 code, body := sipTest.GetEndpoint(endpoint)
798 assert.Equal(t, 302, code)
800 match := sipTest.signInProviderRegexp.FindStringSubmatch(body)
802 t.Fatal("Did not find pattern in body: " +
803 signInSkipProvider + "\nBody:\n" + body)
807func TestSignInPageSkipProviderDirect(t *testing.T) {
808 sipTest := NewSignInPageTest(true)
809 const endpoint = "/sign_in"
811 code, body := sipTest.GetEndpoint(endpoint)
812 assert.Equal(t, 302, code)
814 match := sipTest.signInProviderRegexp.FindStringSubmatch(body)
816 t.Fatal("Did not find pattern in body: " +
817 signInSkipProvider + "\nBody:\n" + body)
821type ProcessCookieTest struct {
824 rw *httptest.ResponseRecorder
826 provider TestProvider
831type ProcessCookieTestOpts struct {
832 providerValidateCookieResponse bool
835type OptionsModifier func(*Options)
837func NewProcessCookieTest(opts ProcessCookieTestOpts, modifiers ...OptionsModifier) *ProcessCookieTest {
838 var pcTest ProcessCookieTest
840 pcTest.opts = NewOptions()
841 for _, modifier := range modifiers {
842 modifier(pcTest.opts)
844 pcTest.opts.ClientID = "asdfljk"
845 pcTest.opts.ClientSecret = "lkjfdsig"
846 pcTest.opts.CookieSecret = "0123456789abcdefabcd"
847 // First, set the CookieRefresh option so proxy.AesCipher is created,
848 // needed to encrypt the access_token.
849 pcTest.opts.CookieRefresh = time.Hour
850 pcTest.opts.Validate()
852 pcTest.proxy = NewOAuthProxy(pcTest.opts, func(email string) bool {
853 return pcTest.validateUser
855 pcTest.proxy.provider = &TestProvider{
856 ValidToken: opts.providerValidateCookieResponse,
859 // Now, zero-out proxy.CookieRefresh for the cases that don't involve
860 // access_token validation.
861 pcTest.proxy.CookieRefresh = time.Duration(0)
862 pcTest.rw = httptest.NewRecorder()
863 pcTest.req, _ = http.NewRequest("GET", "/", strings.NewReader(""))
864 pcTest.validateUser = true
868func NewProcessCookieTestWithDefaults() *ProcessCookieTest {
869 return NewProcessCookieTest(ProcessCookieTestOpts{
870 providerValidateCookieResponse: true,
874func NewProcessCookieTestWithOptionsModifiers(modifiers ...OptionsModifier) *ProcessCookieTest {
875 return NewProcessCookieTest(ProcessCookieTestOpts{
876 providerValidateCookieResponse: true,
880func (p *ProcessCookieTest) SaveSession(s *sessions.SessionState) error {
881 err := p.proxy.SaveSession(p.rw, p.req, s)
885 for _, cookie := range p.rw.Result().Cookies() {
886 p.req.AddCookie(cookie)
891func (p *ProcessCookieTest) LoadCookiedSession() (*sessions.SessionState, error) {
892 return p.proxy.LoadCookiedSession(p.req)
895func TestLoadCookiedSession(t *testing.T) {
896 pcTest := NewProcessCookieTestWithDefaults()
898 startSession := &sessions.SessionState{Email: "john.doe@example.com", AccessToken: "my_access_token", CreatedAt: time.Now()}
899 pcTest.SaveSession(startSession)
901 session, err := pcTest.LoadCookiedSession()
902 assert.Equal(t, nil, err)
903 assert.Equal(t, startSession.Email, session.Email)
904 assert.Equal(t, "john.doe@example.com", session.User)
905 assert.Equal(t, startSession.AccessToken, session.AccessToken)
908func TestProcessCookieNoCookieError(t *testing.T) {
909 pcTest := NewProcessCookieTestWithDefaults()
911 session, err := pcTest.LoadCookiedSession()
912 assert.Equal(t, "Cookie \"_oauth2_proxy\" not present", err.Error())
914 t.Errorf("expected nil session. got %#v", session)
918func TestProcessCookieRefreshNotSet(t *testing.T) {
919 pcTest := NewProcessCookieTestWithOptionsModifiers(func(opts *Options) {
920 opts.CookieExpire = time.Duration(23) * time.Hour
922 reference := time.Now().Add(time.Duration(-2) * time.Hour)
924 startSession := &sessions.SessionState{Email: "michael.bland@gsa.gov", AccessToken: "my_access_token", CreatedAt: reference}
925 pcTest.SaveSession(startSession)
927 session, err := pcTest.LoadCookiedSession()
928 assert.Equal(t, nil, err)
929 if session.Age() < time.Duration(-2)*time.Hour {
930 t.Errorf("cookie too young %v", session.Age())
932 assert.Equal(t, startSession.Email, session.Email)
935func TestProcessCookieFailIfCookieExpired(t *testing.T) {
936 pcTest := NewProcessCookieTestWithOptionsModifiers(func(opts *Options) {
937 opts.CookieExpire = time.Duration(24) * time.Hour
939 reference := time.Now().Add(time.Duration(25) * time.Hour * -1)
940 startSession := &sessions.SessionState{Email: "michael.bland@gsa.gov", AccessToken: "my_access_token", CreatedAt: reference}
941 pcTest.SaveSession(startSession)
943 session, err := pcTest.LoadCookiedSession()
944 assert.NotEqual(t, nil, err)
946 t.Errorf("expected nil session %#v", session)
950func TestProcessCookieFailIfRefreshSetAndCookieExpired(t *testing.T) {
951 pcTest := NewProcessCookieTestWithOptionsModifiers(func(opts *Options) {
952 opts.CookieExpire = time.Duration(24) * time.Hour
954 reference := time.Now().Add(time.Duration(25) * time.Hour * -1)
955 startSession := &sessions.SessionState{Email: "michael.bland@gsa.gov", AccessToken: "my_access_token", CreatedAt: reference}
956 pcTest.SaveSession(startSession)
958 pcTest.proxy.CookieRefresh = time.Hour
959 session, err := pcTest.LoadCookiedSession()
960 assert.NotEqual(t, nil, err)
962 t.Errorf("expected nil session %#v", session)
966func NewUserInfoEndpointTest() *ProcessCookieTest {
967 pcTest := NewProcessCookieTestWithDefaults()
968 pcTest.req, _ = http.NewRequest("GET",
969 pcTest.opts.ProxyPrefix+"/userinfo", nil)
973func TestUserInfoEndpointAccepted(t *testing.T) {
974 test := NewUserInfoEndpointTest()
975 startSession := &sessions.SessionState{
976 Email: "john.doe@example.com", AccessToken: "my_access_token"}
977 test.SaveSession(startSession)
979 test.proxy.ServeHTTP(test.rw, test.req)
980 assert.Equal(t, http.StatusOK, test.rw.Code)
981 bodyBytes, _ := ioutil.ReadAll(test.rw.Body)
982 assert.Equal(t, "{\"email\":\"john.doe@example.com\"}\n", string(bodyBytes))
985func TestUserInfoEndpointUnauthorizedOnNoCookieSetError(t *testing.T) {
986 test := NewUserInfoEndpointTest()
988 test.proxy.ServeHTTP(test.rw, test.req)
989 assert.Equal(t, http.StatusUnauthorized, test.rw.Code)
992func NewAuthOnlyEndpointTest(modifiers ...OptionsModifier) *ProcessCookieTest {
993 pcTest := NewProcessCookieTestWithOptionsModifiers(modifiers...)
994 pcTest.req, _ = http.NewRequest("GET",
995 pcTest.opts.ProxyPrefix+"/auth", nil)
999func TestAuthOnlyEndpointAccepted(t *testing.T) {
1000 test := NewAuthOnlyEndpointTest()
1001 startSession := &sessions.SessionState{
1002 Email: "michael.bland@gsa.gov", AccessToken: "my_access_token", CreatedAt: time.Now()}
1003 test.SaveSession(startSession)
1005 test.proxy.ServeHTTP(test.rw, test.req)
1006 assert.Equal(t, http.StatusAccepted, test.rw.Code)
1007 bodyBytes, _ := ioutil.ReadAll(test.rw.Body)
1008 assert.Equal(t, "", string(bodyBytes))
1011func TestAuthOnlyEndpointUnauthorizedOnNoCookieSetError(t *testing.T) {
1012 test := NewAuthOnlyEndpointTest()
1014 test.proxy.ServeHTTP(test.rw, test.req)
1015 assert.Equal(t, http.StatusUnauthorized, test.rw.Code)
1016 bodyBytes, _ := ioutil.ReadAll(test.rw.Body)
1017 assert.Equal(t, "unauthorized request\n", string(bodyBytes))
1020func TestAuthOnlyEndpointUnauthorizedOnExpiration(t *testing.T) {
1021 test := NewAuthOnlyEndpointTest(func(opts *Options) {
1022 opts.CookieExpire = time.Duration(24) * time.Hour
1024 reference := time.Now().Add(time.Duration(25) * time.Hour * -1)
1025 startSession := &sessions.SessionState{
1026 Email: "michael.bland@gsa.gov", AccessToken: "my_access_token", CreatedAt: reference}
1027 test.SaveSession(startSession)
1029 test.proxy.ServeHTTP(test.rw, test.req)
1030 assert.Equal(t, http.StatusUnauthorized, test.rw.Code)
1031 bodyBytes, _ := ioutil.ReadAll(test.rw.Body)
1032 assert.Equal(t, "unauthorized request\n", string(bodyBytes))
1035func TestAuthOnlyEndpointUnauthorizedOnEmailValidationFailure(t *testing.T) {
1036 test := NewAuthOnlyEndpointTest()
1037 startSession := &sessions.SessionState{
1038 Email: "michael.bland@gsa.gov", AccessToken: "my_access_token", CreatedAt: time.Now()}
1039 test.SaveSession(startSession)
1040 test.validateUser = false
1042 test.proxy.ServeHTTP(test.rw, test.req)
1043 assert.Equal(t, http.StatusUnauthorized, test.rw.Code)
1044 bodyBytes, _ := ioutil.ReadAll(test.rw.Body)
1045 assert.Equal(t, "unauthorized request\n", string(bodyBytes))
1048func TestAuthOnlyEndpointSetXAuthRequestHeaders(t *testing.T) {
1049 var pcTest ProcessCookieTest
1051 pcTest.opts = NewOptions()
1052 pcTest.opts.SetXAuthRequest = true
1053 pcTest.opts.Validate()
1055 pcTest.proxy = NewOAuthProxy(pcTest.opts, func(email string) bool {
1056 return pcTest.validateUser
1058 pcTest.proxy.provider = &TestProvider{
1062 pcTest.validateUser = true
1064 pcTest.rw = httptest.NewRecorder()
1065 pcTest.req, _ = http.NewRequest("GET",
1066 pcTest.opts.ProxyPrefix+"/auth", nil)
1068 startSession := &sessions.SessionState{
1069 User: "oauth_user", Email: "oauth_user@example.com", AccessToken: "oauth_token", CreatedAt: time.Now()}
1070 pcTest.SaveSession(startSession)
1072 pcTest.proxy.ServeHTTP(pcTest.rw, pcTest.req)
1073 assert.Equal(t, http.StatusAccepted, pcTest.rw.Code)
1074 assert.Equal(t, "oauth_user", pcTest.rw.HeaderMap["X-Auth-Request-User"][0])
1075 assert.Equal(t, "oauth_user@example.com", pcTest.rw.HeaderMap["X-Auth-Request-Email"][0])
1078func TestAuthSkippedForPreflightRequests(t *testing.T) {
1079 upstream := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
1081 w.Write([]byte("response"))
1083 defer upstream.Close()
1085 opts := NewOptions()
1086 opts.Upstreams = append(opts.Upstreams, upstream.URL)
1087 opts.ClientID = "aljsal"
1088 opts.ClientSecret = "jglkfsdgj"
1089 opts.CookieSecret = "dkfjgdls"
1090 opts.SkipAuthPreflight = true
1093 upstreamURL, _ := url.Parse(upstream.URL)
1094 opts.provider = NewTestProvider(upstreamURL, "")
1096 proxy := NewOAuthProxy(opts, func(string) bool { return false })
1097 rw := httptest.NewRecorder()
1098 req, _ := http.NewRequest("OPTIONS", "/preflight-request", nil)
1099 proxy.ServeHTTP(rw, req)
1101 assert.Equal(t, 200, rw.Code)
1102 assert.Equal(t, "response", rw.Body.String())
1105type SignatureAuthenticator struct {
1106 auth hmacauth.HmacAuth
1109func (v *SignatureAuthenticator) Authenticate(w http.ResponseWriter, r *http.Request) {
1110 result, headerSig, computedSig := v.auth.AuthenticateRequest(r)
1111 if result == hmacauth.ResultNoSignature {
1112 w.Write([]byte("no signature received"))
1113 } else if result == hmacauth.ResultMatch {
1114 w.Write([]byte("signatures match"))
1115 } else if result == hmacauth.ResultMismatch {
1116 w.Write([]byte("signatures do not match:" +
1117 "\n received: " + headerSig +
1118 "\n computed: " + computedSig))
1120 panic("Unknown result value: " + result.String())
1124type SignatureTest struct {
1126 upstream *httptest.Server
1128 provider *httptest.Server
1130 rw *httptest.ResponseRecorder
1131 authenticator *SignatureAuthenticator
1134func NewSignatureTest() *SignatureTest {
1135 opts := NewOptions()
1136 opts.CookieSecret = "cookie secret"
1137 opts.ClientID = "client ID"
1138 opts.ClientSecret = "client secret"
1139 opts.EmailDomains = []string{"acm.org"}
1141 authenticator := &SignatureAuthenticator{}
1142 upstream := httptest.NewServer(
1143 http.HandlerFunc(authenticator.Authenticate))
1144 upstreamURL, _ := url.Parse(upstream.URL)
1145 opts.Upstreams = append(opts.Upstreams, upstream.URL)
1147 providerHandler := func(w http.ResponseWriter, r *http.Request) {
1148 w.Write([]byte(`{"access_token": "my_auth_token"}`))
1150 provider := httptest.NewServer(http.HandlerFunc(providerHandler))
1151 providerURL, _ := url.Parse(provider.URL)
1152 opts.provider = NewTestProvider(providerURL, "mbland@acm.org")
1154 return &SignatureTest{
1160 httptest.NewRecorder(),
1165func (st *SignatureTest) Close() {
1170// fakeNetConn simulates an http.Request.Body buffer that will be consumed
1171// when it is read by the hmacauth.HmacAuth if not handled properly. See:
1172// https://github.com/18F/hmacauth/pull/4
1173type fakeNetConn struct {
1177func (fnc *fakeNetConn) Read(p []byte) (n int, err error) {
1178 if bodyLen := len(fnc.reqBody); bodyLen != 0 {
1179 copy(p, fnc.reqBody)
1181 return bodyLen, io.EOF
1186func (st *SignatureTest) MakeRequestWithExpectedKey(method, body, key string) {
1187 err := st.opts.Validate()
1191 proxy := NewOAuthProxy(st.opts, func(email string) bool { return true })
1193 var bodyBuf io.ReadCloser
1195 bodyBuf = ioutil.NopCloser(&fakeNetConn{reqBody: body})
1197 req := httptest.NewRequest(method, "/foo/bar", bodyBuf)
1198 req.Header = st.header
1200 state := &sessions.SessionState{
1201 Email: "mbland@acm.org", AccessToken: "my_access_token"}
1202 err = proxy.SaveSession(st.rw, req, state)
1206 for _, c := range st.rw.Result().Cookies() {
1209 // This is used by the upstream to validate the signature.
1210 st.authenticator.auth = hmacauth.NewHmacAuth(
1211 crypto.SHA1, []byte(key), SignatureHeader, SignatureHeaders)
1212 proxy.ServeHTTP(st.rw, req)
1215func TestNoRequestSignature(t *testing.T) {
1216 st := NewSignatureTest()
1218 st.MakeRequestWithExpectedKey("GET", "", "")
1219 assert.Equal(t, 200, st.rw.Code)
1220 assert.Equal(t, st.rw.Body.String(), "no signature received")
1223func TestRequestSignatureGetRequest(t *testing.T) {
1224 st := NewSignatureTest()
1226 st.opts.SignatureKey = "sha1:7d9e1aa87a5954e6f9fc59266b3af9d7c35fda2d"
1227 st.MakeRequestWithExpectedKey("GET", "", "7d9e1aa87a5954e6f9fc59266b3af9d7c35fda2d")
1228 assert.Equal(t, 200, st.rw.Code)
1229 assert.Equal(t, st.rw.Body.String(), "signatures match")
1232func TestRequestSignaturePostRequest(t *testing.T) {
1233 st := NewSignatureTest()
1235 st.opts.SignatureKey = "sha1:d90df39e2d19282840252612dd7c81421a372f61"
1236 payload := `{ "hello": "world!" }`
1237 st.MakeRequestWithExpectedKey("POST", payload, "d90df39e2d19282840252612dd7c81421a372f61")
1238 assert.Equal(t, 200, st.rw.Code)
1239 assert.Equal(t, st.rw.Body.String(), "signatures match")
1242func TestGetRedirect(t *testing.T) {
1243 options := NewOptions()
1244 _ = options.Validate()
1245 require.NotEmpty(t, options.ProxyPrefix)
1246 proxy := NewOAuthProxy(options, func(s string) bool { return false })
1251 expectedRedirect string
1254 name: "request outside of ProxyPrefix redirects to original URL",
1256 expectedRedirect: "/foo/bar",
1259 name: "request under ProxyPrefix redirects to root",
1260 url: proxy.ProxyPrefix + "/foo/bar",
1261 expectedRedirect: "/",
1264 for _, tt := range tests {
1265 t.Run(tt.name, func(t *testing.T) {
1266 req, _ := http.NewRequest("GET", tt.url, nil)
1267 redirect, err := proxy.GetRedirect(req)
1269 assert.NoError(t, err)
1270 assert.Equal(t, tt.expectedRedirect, redirect)
1275type ajaxRequestTest struct {
1280func newAjaxRequestTest() *ajaxRequestTest {
1281 test := &ajaxRequestTest{}
1282 test.opts = NewOptions()
1283 test.opts.CookieSecret = "sdflsw"
1284 test.opts.ClientID = "gkljfdl"
1285 test.opts.ClientSecret = "sdflkjs"
1286 test.opts.Validate()
1287 test.proxy = NewOAuthProxy(test.opts, func(email string) bool {
1293func (test *ajaxRequestTest) getEndpoint(endpoint string, header http.Header) (int, http.Header, error) {
1294 rw := httptest.NewRecorder()
1295 req, err := http.NewRequest(http.MethodGet, endpoint, strings.NewReader(""))
1300 test.proxy.ServeHTTP(rw, req)
1301 return rw.Code, rw.Header(), nil
1304func testAjaxUnauthorizedRequest(t *testing.T, header http.Header) {
1305 test := newAjaxRequestTest()
1308 code, rh, err := test.getEndpoint(endpoint, header)
1309 assert.NoError(t, err)
1310 assert.Equal(t, http.StatusUnauthorized, code)
1311 mime := rh.Get("Content-Type")
1312 assert.Equal(t, applicationJSON, mime)
1314func TestAjaxUnauthorizedRequest1(t *testing.T) {
1315 header := make(http.Header)
1316 header.Add("accept", applicationJSON)
1318 testAjaxUnauthorizedRequest(t, header)
1321func TestAjaxUnauthorizedRequest2(t *testing.T) {
1322 header := make(http.Header)
1323 header.Add("Accept", applicationJSON)
1325 testAjaxUnauthorizedRequest(t, header)
1328func TestAjaxForbiddendRequest(t *testing.T) {
1329 test := newAjaxRequestTest()
1331 header := make(http.Header)
1332 code, rh, err := test.getEndpoint(endpoint, header)
1333 assert.NoError(t, err)
1334 assert.Equal(t, http.StatusForbidden, code)
1335 mime := rh.Get("Content-Type")
1336 assert.NotEqual(t, applicationJSON, mime)
1339func TestClearSplitCookie(t *testing.T) {
1340 opts := NewOptions()
1341 opts.CookieName = "oauth2"
1342 opts.CookieDomain = "abc"
1343 store, err := cookie.NewCookieSessionStore(&opts.SessionOptions, &opts.CookieOptions)
1344 assert.Equal(t, err, nil)
1345 p := OAuthProxy{CookieName: opts.CookieName, CookieDomain: opts.CookieDomain, sessionStore: store}
1346 var rw = httptest.NewRecorder()
1347 req := httptest.NewRequest("get", "/", nil)
1349 req.AddCookie(&http.Cookie{
1353 req.AddCookie(&http.Cookie{
1357 req.AddCookie(&http.Cookie{
1362 p.ClearSessionCookie(rw, req)
1363 header := rw.Header()
1365 assert.Equal(t, 2, len(header["Set-Cookie"]), "should have 3 set-cookie header entries")
1368func TestClearSingleCookie(t *testing.T) {
1369 opts := NewOptions()
1370 opts.CookieName = "oauth2"
1371 opts.CookieDomain = "abc"
1372 store, err := cookie.NewCookieSessionStore(&opts.SessionOptions, &opts.CookieOptions)
1373 assert.Equal(t, err, nil)
1374 p := OAuthProxy{CookieName: opts.CookieName, CookieDomain: opts.CookieDomain, sessionStore: store}
1375 var rw = httptest.NewRecorder()
1376 req := httptest.NewRequest("get", "/", nil)
1378 req.AddCookie(&http.Cookie{
1382 req.AddCookie(&http.Cookie{
1387 p.ClearSessionCookie(rw, req)
1388 header := rw.Header()
1390 assert.Equal(t, 1, len(header["Set-Cookie"]), "should have 1 set-cookie header entries")
1393type NoOpKeySet struct {
1396func (NoOpKeySet) VerifySignature(ctx context.Context, jwt string) (payload []byte, err error) {
1397 splitStrings := strings.Split(jwt, ".")
1398 payloadString := splitStrings[1]
1399 jsonString, err := base64.RawURLEncoding.DecodeString(payloadString)
1400 return []byte(jsonString), err
1403func TestGetJwtSession(t *testing.T) {
1406 "sub": "1234567890",
1407 "aud": "https://test.myapp.com",
1409 "email": "john@example.com",
1410 "iss": "https://issuer.example.com",
1415 goodJwt := "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9." +
1416 "eyJzdWIiOiIxMjM0NTY3ODkwIiwiYXVkIjoiaHR0cHM6Ly90ZXN0Lm15YXBwLmNvbSIsIm5hbWUiOiJKb2huIERvZSIsImVtY" +
1417 "WlsIjoiam9obkBleGFtcGxlLmNvbSIsImlzcyI6Imh0dHBzOi8vaXNzdWVyLmV4YW1wbGUuY29tIiwiaWF0IjoxNTUzNjkxMj" +
1418 "E1LCJleHAiOjE5MTIxNTE4MjF9." +
1419 "rLVyzOnEldUq_pNkfa-WiV8TVJYWyZCaM2Am_uo8FGg11zD7l-qmz3x1seTvqpH6Y0Ty00fmv6dJnGnC8WMnPXQiodRTfhBSe" +
1420 "OKZMu0HkMD2sg52zlKkbfLTO6ic5VnbVgwjjrB8am_Ta6w7kyFUaB5C1BsIrrLMldkWEhynbb8"
1422 keyset := NoOpKeySet{}
1423 verifier := oidc.NewVerifier("https://issuer.example.com", keyset,
1424 &oidc.Config{ClientID: "https://test.myapp.com", SkipExpiryCheck: true})
1426 test := NewAuthOnlyEndpointTest(func(opts *Options) {
1427 opts.PassAuthorization = true
1428 opts.SetAuthorization = true
1429 opts.SetXAuthRequest = true
1430 opts.SkipJwtBearerTokens = true
1431 opts.jwtBearerVerifiers = append(opts.jwtBearerVerifiers, verifier)
1433 tp, _ := test.proxy.provider.(*TestProvider)
1434 tp.GroupValidator = func(s string) bool {
1438 authHeader := fmt.Sprintf("Bearer %s", goodJwt)
1439 test.req.Header = map[string][]string{
1440 "Authorization": {authHeader},
1444 session, _ := test.proxy.GetJwtSession(test.req)
1445 assert.Equal(t, session.User, "john@example.com")
1446 assert.Equal(t, session.Email, "john@example.com")
1447 assert.Equal(t, session.ExpiresOn, time.Unix(1912151821, 0))
1448 assert.Equal(t, session.IDToken, goodJwt)
1450 test.proxy.ServeHTTP(test.rw, test.req)
1451 if test.rw.Code >= 400 {
1452 t.Fatalf("expected 3xx got %d", test.rw.Code)
1455 // Check PassAuthorization, should overwrite Basic header
1456 assert.Equal(t, test.req.Header.Get("Authorization"), authHeader)
1457 assert.Equal(t, test.req.Header.Get("X-Forwarded-User"), "john@example.com")
1458 assert.Equal(t, test.req.Header.Get("X-Forwarded-Email"), "john@example.com")
1460 // SetAuthorization and SetXAuthRequest
1461 assert.Equal(t, test.rw.Header().Get("Authorization"), authHeader)
1462 assert.Equal(t, test.rw.Header().Get("X-Auth-Request-User"), "john@example.com")
1463 assert.Equal(t, test.rw.Header().Get("X-Auth-Request-Email"), "john@example.com")
1466func TestFindJwtBearerToken(t *testing.T) {
1467 p := OAuthProxy{CookieName: "oauth2", CookieDomain: "abc"}
1468 getReq := &http.Request{URL: &url.URL{Scheme: "http", Host: "example.com"}}
1470 validToken := "eyJfoobar.eyJfoobar.12345asdf"
1474 getReq.Header = map[string][]string{
1475 "Authorization": {fmt.Sprintf("Bearer %s", validToken)},
1478 token, _ = p.findBearerToken(getReq)
1479 assert.Equal(t, validToken, token)
1481 // Basic - no password
1482 getReq.SetBasicAuth(token, "")
1483 token, _ = p.findBearerToken(getReq)
1484 assert.Equal(t, validToken, token)
1486 // Basic - sentinel password
1487 getReq.SetBasicAuth(token, "x-oauth-basic")
1488 token, _ = p.findBearerToken(getReq)
1489 assert.Equal(t, validToken, token)
1491 // Basic - any username, password matching jwt pattern
1492 getReq.SetBasicAuth("any-username-you-could-wish-for", token)
1493 token, _ = p.findBearerToken(getReq)
1494 assert.Equal(t, validToken, token)
1496 failures := []string{
1498 "eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.dGVzdA.dGVzdA.dGVzdA.dGVzdA.dGVzdA",
1500 "eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.dGVzdA.dGVzdA.dGVzdA",
1501 // Invalid encrypted key
1502 "eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.//////.dGVzdA.dGVzdA.dGVzdA",
1504 "eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.dGVzdA.//////.dGVzdA.dGVzdA",
1505 // Invalid ciphertext
1506 "eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.dGVzdA.dGVzdA.//////.dGVzdA",
1508 "eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.dGVzdA.dGVzdA.dGVzdA.//////",
1510 "W10.dGVzdA.dGVzdA.dGVzdA.dGVzdA",
1512 "######.dGVzdA.dGVzdA.dGVzdA.dGVzdA",
1513 // Missing alc/enc params
1514 "e30.dGVzdA.dGVzdA.dGVzdA.dGVzdA",
1517 for _, failure := range failures {
1518 getReq.Header = map[string][]string{
1519 "Authorization": {fmt.Sprintf("Bearer %s", failure)},
1521 _, err := p.findBearerToken(getReq)
1522 assert.Error(t, err)
1525 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