Beispiel #1
0
func TestCallbackHandler_AccessTokenError(t *testing.T) {
	requestSecret := "request_secret"
	_, server := testutils.NewErrorServer("OAuth1 Service Down", http.StatusInternalServerError)
	defer server.Close()

	config := &oauth1.Config{
		Endpoint: oauth1.Endpoint{
			AccessTokenURL: server.URL,
		},
	}
	success := testutils.AssertSuccessNotCalled(t)
	failure := func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
		err := gologin.ErrorFromContext(ctx)
		if assert.NotNil(t, err) {
			assert.Equal(t, "oauth1: Response missing oauth_token or oauth_token_secret", err.Error())
		}
		fmt.Fprintf(w, "failure handler called")
	}

	// CallbackHandler cannot get the OAuth1 access token, assert that:
	// - failure handler is called
	// - error about missing oauth_token and oauth_token_secret is added to the ctx
	callbackHandler := CallbackHandler(config, success, ctxh.ContextHandlerFunc(failure))
	w := httptest.NewRecorder()
	req, _ := http.NewRequest("GET", "/?oauth_token=any_token&oauth_verifier=any_verifier", nil)
	ctx := WithRequestToken(context.Background(), "", requestSecret)
	callbackHandler.ServeHTTP(ctx, w, req)
	assert.Equal(t, "failure handler called", w.Body.String())
}
Beispiel #2
0
func TestLoginHandler_RequestTokenError(t *testing.T) {
	_, server := testutils.NewErrorServer("OAuth1 Service Down", http.StatusInternalServerError)
	defer server.Close()

	config := &oauth1.Config{
		Endpoint: oauth1.Endpoint{
			RequestTokenURL: server.URL,
		},
	}
	success := testutils.AssertSuccessNotCalled(t)
	failure := func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
		err := gologin.ErrorFromContext(ctx)
		if assert.NotNil(t, err) {
			// first validation in OAuth1 impl failed
			assert.Equal(t, "oauth1: oauth_callback_confirmed was not true", err.Error())
		}
		fmt.Fprintf(w, "failure handler called")
	}

	// LoginHandler cannot get the OAuth1 request token, assert that:
	// - failure handler is called
	// - error is added to the ctx of the failure handler
	loginHandler := LoginHandler(config, success, ctxh.ContextHandlerFunc(failure))
	w := httptest.NewRecorder()
	req, _ := http.NewRequest("GET", "/", nil)
	loginHandler.ServeHTTP(context.Background(), w, req)
	assert.Equal(t, "failure handler called", w.Body.String())
}
Beispiel #3
0
func TestAuthRedirectHandler_AuthorizationURL(t *testing.T) {
	requestToken := "request_token"
	config := &oauth1.Config{
		Endpoint: oauth1.Endpoint{
			AuthorizeURL: "%gh&%ij", // always causes AuthorizationURL parse error
		},
	}
	failure := func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
		err := gologin.ErrorFromContext(ctx)
		if assert.NotNil(t, err) {
			assert.Equal(t, "parse %gh&%ij: invalid URL escape \"%gh\"", err.Error())
		}
		fmt.Fprintf(w, "failure handler called")
	}

	// AuthRedirectHandler cannot construct the AuthorizationURL, assert that:
	// - failure handler is called
	// - error about authorization URL is added to the ctx
	authRedirectHandler := AuthRedirectHandler(config, ctxh.ContextHandlerFunc(failure))
	w := httptest.NewRecorder()
	req, _ := http.NewRequest("GET", "/", nil)
	ctx := WithRequestToken(context.Background(), requestToken, "")
	authRedirectHandler.ServeHTTP(ctx, w, req)
	assert.Equal(t, "failure handler called", w.Body.String())
}
Beispiel #4
0
func TestGithubHandler_ErrorGettingUser(t *testing.T) {
	proxyClient, server := testutils.NewErrorServer("Github Service Down", http.StatusInternalServerError)
	defer server.Close()
	// oauth2 Client will use the proxy client's base Transport
	ctx := context.WithValue(context.Background(), oauth2.HTTPClient, proxyClient)
	anyToken := &oauth2.Token{AccessToken: "any-token"}
	ctx = oauth2Login.WithToken(ctx, anyToken)

	config := &oauth2.Config{}
	success := testutils.AssertSuccessNotCalled(t)
	failure := func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
		err := gologin.ErrorFromContext(ctx)
		if assert.NotNil(t, err) {
			assert.Equal(t, ErrUnableToGetGithubUser, err)
		}
		fmt.Fprintf(w, "failure handler called")
	}

	// GithubHandler cannot get Github User, assert that:
	// - failure handler is called
	// - error cannot get Github User added to the failure handler ctx
	githubHandler := githubHandler(config, success, ctxh.ContextHandlerFunc(failure))
	w := httptest.NewRecorder()
	req, _ := http.NewRequest("GET", "/", nil)
	githubHandler.ServeHTTP(ctx, w, req)
	assert.Equal(t, "failure handler called", w.Body.String())
}
Beispiel #5
0
func TestCallbackHandler_ExchangeError(t *testing.T) {
	_, server := testutils.NewErrorServer("OAuth2 Service Down", http.StatusInternalServerError)
	defer server.Close()

	config := &oauth2.Config{
		Endpoint: oauth2.Endpoint{
			TokenURL: server.URL,
		},
	}
	success := testutils.AssertSuccessNotCalled(t)
	failure := func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
		err := gologin.ErrorFromContext(ctx)
		if assert.NotNil(t, err) {
			// error from golang.org/x/oauth2 config.Exchange as provider is down
			assert.True(t, strings.HasPrefix(err.Error(), "oauth2: cannot fetch token"))
		}
		fmt.Fprintf(w, "failure handler called")
	}

	// CallbackHandler cannot exchange for an Access Token, assert that:
	// - failure handler is called
	// - error with the reason the exchange failed is added to the ctx
	callbackHandler := CallbackHandler(config, success, ctxh.ContextHandlerFunc(failure))
	w := httptest.NewRecorder()
	req, _ := http.NewRequest("GET", "/?code=any_code&state=d4e5f6", nil)
	ctx := WithState(context.Background(), "d4e5f6")
	callbackHandler.ServeHTTP(ctx, w, req)
	assert.Equal(t, "failure handler called", w.Body.String())
}
Beispiel #6
0
func TestCallbackHandler_ParseCallbackError(t *testing.T) {
	config := &oauth2.Config{}
	success := testutils.AssertSuccessNotCalled(t)
	failure := func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
		err := gologin.ErrorFromContext(ctx)
		if assert.NotNil(t, err) {
			assert.Equal(t, "oauth2: Request missing code or state", err.Error())
		}
		fmt.Fprintf(w, "failure handler called")
	}

	// CallbackHandler called without code or state, assert that:
	// - failure handler is called
	// - error about missing code or state is added to the ctx
	callbackHandler := CallbackHandler(config, success, ctxh.ContextHandlerFunc(failure))
	w := httptest.NewRecorder()
	req, _ := http.NewRequest("GET", "/?code=any_code", nil)
	callbackHandler.ServeHTTP(context.Background(), w, req)
	assert.Equal(t, "failure handler called", w.Body.String())

	w = httptest.NewRecorder()
	req, _ = http.NewRequest("GET", "/?state=any_state", nil)
	callbackHandler.ServeHTTP(context.Background(), w, req)
	assert.Equal(t, "failure handler called", w.Body.String())
}
Beispiel #7
0
func TestTokenHandler_NonPostPassesError(t *testing.T) {
	config := &oauth1.Config{}
	failure := func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
		// assert that Method not allowed error passed through ctx
		err := gologin.ErrorFromContext(ctx)
		if assert.Error(t, err) {
			assert.Equal(t, err, fmt.Errorf("Method not allowed"))
		}
	}
	ts := httptest.NewServer(ctxh.NewHandler(TokenHandler(config, assertSuccessNotCalled(t), ctxh.ContextHandlerFunc(failure))))
	http.Get(ts.URL)
}
Beispiel #8
0
func TestTokenHandler_UnauthorizedPassesError(t *testing.T) {
	proxyClient, server := testutils.UnauthorizedTestServer()
	defer server.Close()
	// oauth1 Client will use the proxy client's base Transport
	ctx := context.WithValue(context.Background(), oauth1.HTTPClient, proxyClient)

	config := &oauth1.Config{}
	failure := func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
		// assert that error passed through ctx
		err := gologin.ErrorFromContext(ctx)
		if assert.Error(t, err) {
			assert.Equal(t, err, ErrUnableToGetTwitterUser)
		}
	}
	handler := TokenHandler(config, assertSuccessNotCalled(t), ctxh.ContextHandlerFunc(failure))
	ts := httptest.NewServer(ctxh.NewHandlerWithContext(ctx, handler))
	http.PostForm(ts.URL, url.Values{accessTokenField: {testTwitterToken}, accessTokenSecretField: {testTwitterTokenSecret}})
}
Beispiel #9
0
func TestAuthRedirectHandler_MissingCtxRequestToken(t *testing.T) {
	config := &oauth1.Config{}
	failure := func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
		err := gologin.ErrorFromContext(ctx)
		if assert.NotNil(t, err) {
			assert.Equal(t, "oauth1: Context missing request token or secret", err.Error())
		}
		fmt.Fprintf(w, "failure handler called")
	}

	// CallbackHandler cannot get the request token from the ctx, assert that:
	// - failure handler is called
	// - error about missing request token is added to the ctx
	authRedirectHandler := AuthRedirectHandler(config, ctxh.ContextHandlerFunc(failure))
	w := httptest.NewRecorder()
	req, _ := http.NewRequest("GET", "/", nil)
	authRedirectHandler.ServeHTTP(context.Background(), w, req)
	assert.Equal(t, "failure handler called", w.Body.String())
}
Beispiel #10
0
func TestLoginHandler_MissingCtxState(t *testing.T) {
	config := &oauth2.Config{}
	failure := func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
		err := gologin.ErrorFromContext(ctx)
		if assert.NotNil(t, err) {
			assert.Equal(t, "oauth2: Context missing state value", err.Error())
		}
		fmt.Fprintf(w, "failure handler called")
	}

	// LoginHandler cannot get the state from the ctx, assert that:
	// - failure handler is called
	// - error about missing state is added to the ctx
	loginHandler := LoginHandler(config, ctxh.ContextHandlerFunc(failure))
	w := httptest.NewRecorder()
	req, _ := http.NewRequest("GET", "/", nil)
	loginHandler.ServeHTTP(context.Background(), w, req)
	assert.Equal(t, "failure handler called", w.Body.String())
}
Beispiel #11
0
func TestCallbackHandler_MissingCtxRequestSecret(t *testing.T) {
	config := &oauth1.Config{}
	success := testutils.AssertSuccessNotCalled(t)
	failure := func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
		err := gologin.ErrorFromContext(ctx)
		if assert.NotNil(t, err) {
			assert.Equal(t, "oauth1: Context missing request token or secret", err.Error())
		}
		fmt.Fprintf(w, "failure handler called")
	}

	// CallbackHandler cannot get the request secret from the ctx, assert that:
	// - failure handler is called
	// - error about missing request secret is added to the ctx
	callbackHandler := CallbackHandler(config, success, ctxh.ContextHandlerFunc(failure))
	w := httptest.NewRecorder()
	req, _ := http.NewRequest("GET", "/?oauth_token=any_token&oauth_verifier=any_verifier", nil)
	callbackHandler.ServeHTTP(context.Background(), w, req)
	assert.Equal(t, "failure handler called", w.Body.String())
}
Beispiel #12
0
func TestGithubHandler_MissingCtxToken(t *testing.T) {
	config := &oauth2.Config{}
	success := testutils.AssertSuccessNotCalled(t)
	failure := func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
		err := gologin.ErrorFromContext(ctx)
		if assert.NotNil(t, err) {
			assert.Equal(t, "oauth2: Context missing Token", err.Error())
		}
		fmt.Fprintf(w, "failure handler called")
	}

	// GithubHandler called without Token in ctx, assert that:
	// - failure handler is called
	// - error about ctx missing token is added to the failure handler ctx
	githubHandler := githubHandler(config, success, ctxh.ContextHandlerFunc(failure))
	w := httptest.NewRecorder()
	req, _ := http.NewRequest("GET", "/", nil)
	githubHandler.ServeHTTP(context.Background(), w, req)
	assert.Equal(t, "failure handler called", w.Body.String())
}
Beispiel #13
0
func TestCallbackHandler_MissingCtxState(t *testing.T) {
	config := &oauth2.Config{}
	success := testutils.AssertSuccessNotCalled(t)
	failure := func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
		err := gologin.ErrorFromContext(ctx)
		if assert.NotNil(t, err) {
			assert.Equal(t, "oauth2: Context missing state value", err.Error())
		}
		fmt.Fprintf(w, "failure handler called")
	}

	// CallbackHandler cannot get the state parameter from the ctx, assert that:
	// - failure handler is called
	// - error about missing state ctx param is added to the failure handler ctx
	callbackHandler := CallbackHandler(config, success, ctxh.ContextHandlerFunc(failure))
	w := httptest.NewRecorder()
	req, _ := http.NewRequest("GET", "/?code=any_code&state=d4e5f6", nil)
	ctxh.NewHandler(callbackHandler).ServeHTTP(w, req)
	assert.Equal(t, "failure handler called", w.Body.String())
}
Beispiel #14
0
func TestCallbackHandler_ParseAuthorizationCallbackError(t *testing.T) {
	config := &oauth1.Config{}
	success := testutils.AssertSuccessNotCalled(t)
	failure := func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
		err := gologin.ErrorFromContext(ctx)
		if assert.NotNil(t, err) {
			assert.Equal(t, "oauth1: Request missing oauth_token or oauth_verifier", err.Error())
		}
		fmt.Fprintf(w, "failure handler called")
	}

	// CallbackHandler called without oauth_token or oauth_verifier, assert that:
	// - failure handler is called
	// - error about missing oauth_token or oauth_verifier is added to the ctx
	callbackHandler := CallbackHandler(config, success, ctxh.ContextHandlerFunc(failure))
	w := httptest.NewRecorder()
	req, _ := http.NewRequest("GET", "/?oauth_verifier=", nil)
	ctxh.NewHandler(callbackHandler).ServeHTTP(w, req)
	assert.Equal(t, "failure handler called", w.Body.String())
}
Beispiel #15
0
func TestCallbackHandler_StateMismatch(t *testing.T) {
	config := &oauth2.Config{}
	success := testutils.AssertSuccessNotCalled(t)
	failure := func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
		err := gologin.ErrorFromContext(ctx)
		if assert.NotNil(t, err) {
			assert.Equal(t, "oauth2: Invalid OAuth2 state parameter", err.Error())
		}
		fmt.Fprintf(w, "failure handler called")
	}

	// CallbackHandler ctx state does not match state param, assert that:
	// - failure handler is called
	// - error about invalid state param is added to the failure handler ctx
	callbackHandler := CallbackHandler(config, success, ctxh.ContextHandlerFunc(failure))
	w := httptest.NewRecorder()
	req, _ := http.NewRequest("GET", "/?code=any_code&state=d4e5f6", nil)
	ctx := WithState(context.Background(), "differentState")
	callbackHandler.ServeHTTP(ctx, w, req)
	assert.Equal(t, "failure handler called", w.Body.String())
}