summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/controllers/sessions/controller.go2
-rw-r--r--app/controllers/sessions/controller_test.go37
-rw-r--r--pkg/oidc/oidc_test.go6
-rw-r--r--pkg/test/oidc_server.go54
4 files changed, 31 insertions, 68 deletions
diff --git a/app/controllers/sessions/controller.go b/app/controllers/sessions/controller.go
index 1ceb9ec..c14a300 100644
--- a/app/controllers/sessions/controller.go
+++ b/app/controllers/sessions/controller.go
@@ -2,6 +2,7 @@ package sessions
import (
"context"
+ "fmt"
"net/http"
"gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/pkg/oidc"
@@ -36,6 +37,7 @@ func (c *Controller) Create(w http.ResponseWriter, r *http.Request) {
ctx := context.WithValue(r.Context(), oauth2.HTTPClient, c.http)
token, err := c.cfg.Config.Exchange(ctx, r.URL.Query().Get("code"))
if err != nil {
+ fmt.Printf("%v\n", err)
w.WriteHeader(http.StatusBadRequest)
return
}
diff --git a/app/controllers/sessions/controller_test.go b/app/controllers/sessions/controller_test.go
index 1b829bf..a5167cc 100644
--- a/app/controllers/sessions/controller_test.go
+++ b/app/controllers/sessions/controller_test.go
@@ -5,9 +5,11 @@ import (
"encoding/json"
"net/http"
"net/url"
- "strings"
+ "strconv"
"testing"
+ "time"
+ "github.com/oauth2-proxy/mockoidc"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/xlgmokha/x/pkg/x"
@@ -16,10 +18,16 @@ import (
)
func TestSessions(t *testing.T) {
- srv := test.OIDCServer()
+ srv := test.NewOIDCServer(t)
defer srv.Close()
- cfg, err := oidc.New(t.Context(), srv.URL, "client_id", "client_secret", "callback_url")
+ cfg, err := oidc.New(
+ t.Context(),
+ srv.Issuer(),
+ srv.MockOIDC.Config().ClientID,
+ srv.MockOIDC.Config().ClientSecret,
+ "callback_url",
+ )
require.NoError(t, err)
controller := New(cfg, http.DefaultClient)
mux := http.NewServeMux()
@@ -36,10 +44,9 @@ func TestSessions(t *testing.T) {
require.NotEmpty(t, w.Header().Get("Location"))
redirectURL, err := url.Parse(w.Header().Get("Location"))
require.NoError(t, err)
- assert.Equal(t, strings.TrimPrefix(srv.URL, "http://"), redirectURL.Host)
- assert.Equal(t, "/oauth/authorize", redirectURL.Path)
+ assert.Equal(t, srv.AuthorizationEndpoint(), redirectURL.Scheme+"://"+redirectURL.Host+redirectURL.Path)
assert.NotEmpty(t, redirectURL.Query().Get("state"))
- assert.Equal(t, "client_id", redirectURL.Query().Get("client_id"))
+ assert.Equal(t, srv.MockOIDC.Config().ClientID, redirectURL.Query().Get("client_id"))
assert.Equal(t, "openid profile email", redirectURL.Query().Get("scope"))
assert.Equal(t, "todo", redirectURL.Query().Get("audience"))
assert.Equal(t, cfg.Config.RedirectURL, redirectURL.Query().Get("redirect_uri"))
@@ -64,7 +71,15 @@ func TestSessions(t *testing.T) {
})
t.Run("with a valid authorization code grant", func(t *testing.T) {
- r, w := test.RequestResponse("GET", "/session/callback?code=code")
+ code := strconv.FormatInt(time.Now().Unix(), 10)
+ user := mockoidc.DefaultUser()
+ srv.QueueUser(user)
+ srv.QueueCode(code)
+
+ _, err := http.Get(srv.AuthCodeURL("state"))
+ require.NoError(srv, err)
+
+ r, w := test.RequestResponse("GET", "/session/callback?code="+code)
mux.ServeHTTP(w, r)
@@ -80,16 +95,16 @@ func TestSessions(t *testing.T) {
require.NoError(t, json.Unmarshal(data, &tokens))
t.Run("stores the id token in a session cookie", func(t *testing.T) {
- assert.Equal(t, "eyJ0eXAiOiJKV1QiLCJraWQiOiJ0ZDBTbWRKUTRxUGg1cU5Lek0yNjBDWHgyVWgtd2hHLU1Eam9PS1dmdDhFIiwiYWxnIjoiUlMyNTYifQ.eyJpc3MiOiJodHRwOi8vZ2RrLnRlc3Q6MzAwMCIsInN1YiI6IjEiLCJhdWQiOiJlMzFlMWRhMGI4ZjZiNmUzNWNhNzBjNzkwYjEzYzA0MDZlNDRhY2E2YjJiZjY3ZjU1ZGU3MzU1YTk3OWEyMjRmIiwiZXhwIjoxNzQ0NzM3NDI3LCJpYXQiOjE3NDQ3MzczMDcsImF1dGhfdGltZSI6MTc0NDczNDY0OSwic3ViX2xlZ2FjeSI6IjI0NzRjZjBiMjIxMTY4OGE1NzI5N2FjZTBlMjYwYTE1OTQ0NzU0ZDE2YjFiZDQyYzlkNjc3OWM5MDAzNjc4MDciLCJuYW1lIjoiQWRtaW5pc3RyYXRvciIsIm5pY2tuYW1lIjoicm9vdCIsInByZWZlcnJlZF91c2VybmFtZSI6InJvb3QiLCJlbWFpbCI6ImFkbWluQGV4YW1wbGUuY29tIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsInByb2ZpbGUiOiJodHRwOi8vZ2RrLnRlc3Q6MzAwMC9yb290IiwicGljdHVyZSI6Imh0dHBzOi8vd3d3LmdyYXZhdGFyLmNvbS9hdmF0YXIvMjU4ZDhkYzkxNmRiOGNlYTJjYWZiNmMzY2QwY2IwMjQ2ZWZlMDYxNDIxZGJkODNlYzNhMzUwNDI4Y2FiZGE0Zj9zPTgwJmQ9aWRlbnRpY29uIiwiZ3JvdXBzX2RpcmVjdCI6WyJ0b29sYm94IiwiZ2l0bGFiLW9yZyIsImdudXdnZXQiLCJDb21taXQ0NTEiLCJqYXNoa2VuYXMiLCJmbGlnaHRqcyIsInR3aXR0ZXIiLCJnaXRsYWItZXhhbXBsZXMiLCJnaXRsYWItZXhhbXBsZXMvc2VjdXJpdHkiLCI0MTI3MDgiLCJnaXRsYWItZXhhbXBsZXMvZGVtby1ncm91cCIsImN1c3RvbS1yb2xlcy1yb290LWdyb3VwIiwiNDM0MDQ0LWdyb3VwLTEiLCI0MzQwNDQtZ3JvdXAtMiIsImdpdGxhYi1vcmcxIiwiZ2l0bGFiLW9yZy9zZWN1cmUiLCJnaXRsYWItb3JnL3NlY3VyZS9tYW5hZ2VycyIsImdpdGxhYi1vcmcvc2VjdXJpdHktcHJvZHVjdHMiLCJnaXRsYWItb3JnL3NlY3VyaXR5LXByb2R1Y3RzL2FuYWx5emVycyIsImN1c3RvbS1yb2xlcy1yb290LWdyb3VwL2FhIiwiY3VzdG9tLXJvbGVzLXJvb3QtZ3JvdXAvYWEvYWFhIiwibWFzc19pbnNlcnRfZ3JvdXBfXzBfMTAwIl19.SZu_l7tQ2Kkeogq0z8cRaDWPfv52JTo-RkiExbnud_lrfrXXneS77BIzaGKX_bzq4SM_oO_Q63AzK66B1r6Gp7ACo4DjOUEIWETg7ZBKcDzEZnresB7kmI_MJ5rfIJTmnH75GOfc_pl5l8T896TbaShN6zSpaXXIVEfhyUrflSWb4hhA7Hbwy2b6laXiaDv0qpcn1udPVYMTsll8I5ni_2yzuEPSVRgrcQoQ46OwVDZIi9tlfdT2qNVjH6FxJ3mkBcxtIVjf3_JYAawFEscg2uvQYwFWj9T6LleMknAh3QFJJMrS6mPqlXJGPUE5pTQgsBInfEikfm9PXxezA-IY6g", tokens["id_token"])
+ assert.NotEmpty(t, tokens["id_token"])
})
t.Run("stores the access token in a session cookie", func(t *testing.T) {
- assert.Equal(t, "14fa6e71afaabbe5e31ef2b47ccab7ca7a3c26f8dfdb74acce3eca30099af028", tokens["access_token"])
- assert.Equal(t, "Bearer", tokens["token_type"])
+ assert.NotEmpty(t, tokens["access_token"])
+ assert.Equal(t, "bearer", tokens["token_type"])
})
t.Run("stores the refresh token in a session cookie", func(t *testing.T) {
- assert.Equal(t, "365b261d4b25ba37e7c1e14e6501902aeecfb7fffc4602c44d6ac22b4c715b0f", tokens["refresh_token"])
+ assert.NotEmpty(t, tokens["refresh_token"])
})
t.Run("redirects to the homepage", func(t *testing.T) {
diff --git a/pkg/oidc/oidc_test.go b/pkg/oidc/oidc_test.go
index b7715cf..3a0daf0 100644
--- a/pkg/oidc/oidc_test.go
+++ b/pkg/oidc/oidc_test.go
@@ -11,12 +11,12 @@ import (
func TestOpenID(t *testing.T) {
t.Run("GET /.well-known/openid-configuration", func(t *testing.T) {
- srv := test.OIDCServer()
+ srv := test.NewOIDCServer(t)
defer srv.Close()
- openID, err := New(context.Background(), srv.URL, "client_id", "client_secret", "https://example.com/oauth/callback")
+ openID, err := New(context.Background(), srv.Issuer(), "client_id", "client_secret", "https://example.com/oauth/callback")
require.NoError(t, err)
- assert.Equal(t, srv.URL+"/oauth/authorize", openID.Provider.Endpoint().AuthURL)
+ assert.Equal(t, srv.AuthorizationEndpoint(), openID.Provider.Endpoint().AuthURL)
})
}
diff --git a/pkg/test/oidc_server.go b/pkg/test/oidc_server.go
index a3ae9e3..5e007d6 100644
--- a/pkg/test/oidc_server.go
+++ b/pkg/test/oidc_server.go
@@ -2,7 +2,6 @@ package test
import (
"net/http"
- "net/http/httptest"
"strconv"
"testing"
"time"
@@ -10,62 +9,9 @@ import (
"github.com/coreos/go-oidc/v3/oidc"
"github.com/oauth2-proxy/mockoidc"
"github.com/stretchr/testify/require"
- "github.com/xlgmokha/x/pkg/serde"
"golang.org/x/oauth2"
)
-func OIDCServer() *httptest.Server {
- srv := httptest.NewServer(nil)
- srv.Config = &http.Server{
- Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- switch r.URL.Path {
- case "/.well-known/openid-configuration":
- metadata := map[string]interface{}{
- "authorization_endpoint": srv.URL + "/oauth/authorize",
- "claims_supported": []string{"aud"},
- "code_challenge_methods_supported": []string{"plain"},
- "device_authorization_endpoint": srv.URL + "/device/authorize",
- "id_token_signing_alg_values_supported": []string{"RS256"},
- "issuer": srv.URL,
- "jwks_uri": srv.URL + "/jwks",
- "mfa_challenge_endpoint": srv.URL + "/mfa",
- "registration_endpoint": srv.URL + "/users/new",
- "request_uri_parameter_supported": false,
- "response_modes_supported": []string{"query"},
- "response_types_supported": []string{"code"},
- "revocation_endpoint": srv.URL + "/revoke",
- "scopes_supported": []string{"oidc"},
- "subject_types_supported": []string{"public"},
- "token_endpoint": srv.URL + "/token",
- "token_endpoint_auth_methods_supported": []string{"client_secret_post"},
- "userinfo_endpoint": srv.URL + "/users/me",
- }
-
- serde.ToJSON(w, metadata)
- case "/token":
- if err := r.ParseForm(); err != nil {
- w.WriteHeader(http.StatusBadRequest)
- return
- }
- if r.Form["grant_type"][0] == "authorization_code" && r.Form["code"][0] == "code" {
- w.Header().Add("Content-Type", "application/json")
- serde.ToJSON(w, map[string]string{
- "access_token": "14fa6e71afaabbe5e31ef2b47ccab7ca7a3c26f8dfdb74acce3eca30099af028",
- "token_type": "Bearer",
- "refresh_token": "365b261d4b25ba37e7c1e14e6501902aeecfb7fffc4602c44d6ac22b4c715b0f",
- // "expiry": "2025-04-15T19:16:38.78960504-06:00"
- "expiry": time.Now().Add(1 * time.Hour).Format(time.RFC3339),
- "id_token": "eyJ0eXAiOiJKV1QiLCJraWQiOiJ0ZDBTbWRKUTRxUGg1cU5Lek0yNjBDWHgyVWgtd2hHLU1Eam9PS1dmdDhFIiwiYWxnIjoiUlMyNTYifQ.eyJpc3MiOiJodHRwOi8vZ2RrLnRlc3Q6MzAwMCIsInN1YiI6IjEiLCJhdWQiOiJlMzFlMWRhMGI4ZjZiNmUzNWNhNzBjNzkwYjEzYzA0MDZlNDRhY2E2YjJiZjY3ZjU1ZGU3MzU1YTk3OWEyMjRmIiwiZXhwIjoxNzQ0NzM3NDI3LCJpYXQiOjE3NDQ3MzczMDcsImF1dGhfdGltZSI6MTc0NDczNDY0OSwic3ViX2xlZ2FjeSI6IjI0NzRjZjBiMjIxMTY4OGE1NzI5N2FjZTBlMjYwYTE1OTQ0NzU0ZDE2YjFiZDQyYzlkNjc3OWM5MDAzNjc4MDciLCJuYW1lIjoiQWRtaW5pc3RyYXRvciIsIm5pY2tuYW1lIjoicm9vdCIsInByZWZlcnJlZF91c2VybmFtZSI6InJvb3QiLCJlbWFpbCI6ImFkbWluQGV4YW1wbGUuY29tIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsInByb2ZpbGUiOiJodHRwOi8vZ2RrLnRlc3Q6MzAwMC9yb290IiwicGljdHVyZSI6Imh0dHBzOi8vd3d3LmdyYXZhdGFyLmNvbS9hdmF0YXIvMjU4ZDhkYzkxNmRiOGNlYTJjYWZiNmMzY2QwY2IwMjQ2ZWZlMDYxNDIxZGJkODNlYzNhMzUwNDI4Y2FiZGE0Zj9zPTgwJmQ9aWRlbnRpY29uIiwiZ3JvdXBzX2RpcmVjdCI6WyJ0b29sYm94IiwiZ2l0bGFiLW9yZyIsImdudXdnZXQiLCJDb21taXQ0NTEiLCJqYXNoa2VuYXMiLCJmbGlnaHRqcyIsInR3aXR0ZXIiLCJnaXRsYWItZXhhbXBsZXMiLCJnaXRsYWItZXhhbXBsZXMvc2VjdXJpdHkiLCI0MTI3MDgiLCJnaXRsYWItZXhhbXBsZXMvZGVtby1ncm91cCIsImN1c3RvbS1yb2xlcy1yb290LWdyb3VwIiwiNDM0MDQ0LWdyb3VwLTEiLCI0MzQwNDQtZ3JvdXAtMiIsImdpdGxhYi1vcmcxIiwiZ2l0bGFiLW9yZy9zZWN1cmUiLCJnaXRsYWItb3JnL3NlY3VyZS9tYW5hZ2VycyIsImdpdGxhYi1vcmcvc2VjdXJpdHktcHJvZHVjdHMiLCJnaXRsYWItb3JnL3NlY3VyaXR5LXByb2R1Y3RzL2FuYWx5emVycyIsImN1c3RvbS1yb2xlcy1yb290LWdyb3VwL2FhIiwiY3VzdG9tLXJvbGVzLXJvb3QtZ3JvdXAvYWEvYWFhIiwibWFzc19pbnNlcnRfZ3JvdXBfXzBfMTAwIl19.SZu_l7tQ2Kkeogq0z8cRaDWPfv52JTo-RkiExbnud_lrfrXXneS77BIzaGKX_bzq4SM_oO_Q63AzK66B1r6Gp7ACo4DjOUEIWETg7ZBKcDzEZnresB7kmI_MJ5rfIJTmnH75GOfc_pl5l8T896TbaShN6zSpaXXIVEfhyUrflSWb4hhA7Hbwy2b6laXiaDv0qpcn1udPVYMTsll8I5ni_2yzuEPSVRgrcQoQ46OwVDZIi9tlfdT2qNVjH6FxJ3mkBcxtIVjf3_JYAawFEscg2uvQYwFWj9T6LleMknAh3QFJJMrS6mPqlXJGPUE5pTQgsBInfEikfm9PXxezA-IY6g",
- })
- }
- default:
- w.WriteHeader(http.StatusNotFound)
- }
- }),
- }
- return srv
-}
-
type TestServer struct {
*mockoidc.MockOIDC
*oauth2.Config