diff options
| author | mo khan <mo@mokhan.ca> | 2025-05-11 19:56:54 -0600 |
|---|---|---|
| committer | mo khan <mo@mokhan.ca> | 2025-05-11 21:22:02 -0600 |
| commit | 61a24b36f334b709f0eac0dd7746f83719747963 (patch) | |
| tree | 8930c6539c2158969be83aaa0fc058fc49e0f0ef /app | |
| parent | 5cc8d582127abed58433c85526d03a257748ca0c (diff) | |
refactor: use same cookie names as envoy plugin
Diffstat (limited to 'app')
| -rw-r--r-- | app/cfg/cfg.go | 2 | ||||
| -rw-r--r-- | app/controllers/sessions/controller.go | 15 | ||||
| -rw-r--r-- | app/controllers/sessions/controller_test.go | 54 | ||||
| -rw-r--r-- | app/middleware/id_token.go | 2 | ||||
| -rw-r--r-- | app/middleware/id_token_test.go | 9 | ||||
| -rw-r--r-- | app/middleware/token_parser.go | 13 |
6 files changed, 40 insertions, 55 deletions
diff --git a/app/cfg/cfg.go b/app/cfg/cfg.go index d8ca805..1dffa16 100644 --- a/app/cfg/cfg.go +++ b/app/cfg/cfg.go @@ -14,9 +14,7 @@ var OAuthClientID string = env.Fetch("OAUTH_CLIENT_ID", "client_id") var OAuthClientSecret string = env.Fetch("OAUTH_CLIENT_SECRET", "client_secret") var OAuthRedirectURL string = env.Fetch("OAUTH_REDIRECT_URL", "") -var SessionCookie string = "__s" var CSRFCookie string = "__csrf" - var IDTokenCookie string = "id_token" var BearerTokenCookie string = "bearer_token" var RefreshTokenCookie string = "refresh_token" diff --git a/app/controllers/sessions/controller.go b/app/controllers/sessions/controller.go index bf7d813..2853358 100644 --- a/app/controllers/sessions/controller.go +++ b/app/controllers/sessions/controller.go @@ -100,22 +100,19 @@ func (c *Controller) Create(w http.ResponseWriter, r *http.Request) { return } - encoded, err := tokens.ToBase64String() - if err != nil { - pls.LogError(r.Context(), err) - w.WriteHeader(http.StatusBadRequest) - return - } - web.ExpireCookie(w, cfg.CSRFCookie) - web.WriteCookie(w, web.NewCookie(cfg.SessionCookie, encoded)) + web.WriteCookie(w, web.NewCookie(cfg.IDTokenCookie, tokens.IDToken.String())) + web.WriteCookie(w, web.NewCookie(cfg.BearerTokenCookie, tokens.AccessToken)) + web.WriteCookie(w, web.NewCookie(cfg.RefreshTokenCookie, tokens.RefreshToken)) c.redirectTo(w, r, "/dashboard") } func (c *Controller) Destroy(w http.ResponseWriter, r *http.Request) { web.ExpireCookie(w, cfg.CSRFCookie) - web.ExpireCookie(w, cfg.SessionCookie) + web.ExpireCookie(w, cfg.IDTokenCookie) + web.ExpireCookie(w, cfg.BearerTokenCookie) + web.ExpireCookie(w, cfg.RefreshTokenCookie) c.redirectTo(w, r, "/") } diff --git a/app/controllers/sessions/controller_test.go b/app/controllers/sessions/controller_test.go index 9b701d6..00e3f4e 100644 --- a/app/controllers/sessions/controller_test.go +++ b/app/controllers/sessions/controller_test.go @@ -1,9 +1,6 @@ package sessions import ( - "encoding/base64" - "encoding/json" - "fmt" "net/http" "net/url" "testing" @@ -133,29 +130,28 @@ func TestSessions(t *testing.T) { return ck }) - cookie := x.Find(cookies, func(item *http.Cookie) bool { - return item.Name == xcfg.SessionCookie - }) - data, err := base64.URLEncoding.DecodeString(web.CookieValueFrom(cookie)) - require.NoError(t, err) - tokens := map[string]interface{}{} - require.NoError(t, json.Unmarshal(data, &tokens)) - t.Run("stores the id token in a session cookie", func(t *testing.T) { - require.NotEmpty(t, tokens["id_token"]) + cookie := x.Find(cookies, func(item *http.Cookie) bool { + return item.Name == xcfg.IDTokenCookie + }) - idToken := srv.Verify(tokens["id_token"].(string)) + require.NotNil(t, cookie) + + idToken := srv.Verify(cookie.Value) assert.Equal(t, user.Subject, idToken.Subject) }) t.Run("stores the access token in a session cookie", func(t *testing.T) { - assert.NotEmpty(t, tokens["access_token"]) - assert.Equal(t, "bearer", tokens["token_type"]) + cookie := x.Find(cookies, func(item *http.Cookie) bool { + return item.Name == xcfg.BearerTokenCookie + }) + + require.NotNil(t, cookie) keypair, err := mockoidc.DefaultKeypair() require.NoError(t, err) - token, err := keypair.VerifyJWT(tokens["access_token"].(string), nil) + token, err := keypair.VerifyJWT(cookie.Value, nil) require.NoError(t, err) sub, err := token.Claims.GetSubject() @@ -164,12 +160,15 @@ func TestSessions(t *testing.T) { }) t.Run("stores the refresh token in a session cookie", func(t *testing.T) { - assert.NotEmpty(t, tokens["refresh_token"]) + cookie := x.Find(cookies, func(item *http.Cookie) bool { + return item.Name == xcfg.RefreshTokenCookie + }) + require.NotNil(t, cookie) keypair, err := mockoidc.DefaultKeypair() require.NoError(t, err) - token, err := keypair.VerifyJWT(tokens["refresh_token"].(string), nil) + token, err := keypair.VerifyJWT(cookie.Value, nil) require.NoError(t, err) sub, err := token.Claims.GetSubject() @@ -183,11 +182,13 @@ func TestSessions(t *testing.T) { }) t.Run("applies the appropriate cookie settings", func(t *testing.T) { - assert.Equal(t, "/", cookie.Path) - assert.Equal(t, xcfg.SessionCookie, cookie.Name) - assert.True(t, cookie.HttpOnly) - assert.True(t, cookie.Secure) - assert.NotEmpty(t, cookie.Value) + x.Each(cookies, func(cookie *http.Cookie) { + t.Logf("%v: %v\n", cookie.Name, cookie.Value) + assert.Equal(t, "/", cookie.Path) + assert.NotEmpty(t, cookie.Name) + assert.True(t, cookie.HttpOnly) + assert.True(t, cookie.Secure) + }) }) }) }) @@ -204,7 +205,6 @@ func TestSessions(t *testing.T) { require.Equal(t, http.StatusOK, w.Code) items, err := serde.FromJSON[map[string]interface{}](w.Body) require.NoError(t, err) - fmt.Printf("%v\n", items) assert.Equal(t, srv.Issuer(), items["iss"]) }) @@ -219,7 +219,7 @@ func TestSessions(t *testing.T) { t.Run("POST /session/destroy", func(t *testing.T) { t.Run("clears the session cookie", func(t *testing.T) { - cookie := web.NewCookie(xcfg.SessionCookie, "value") + cookie := web.NewCookie(xcfg.IDTokenCookie, "value") r, w := test.RequestResponse("POST", "/session/destroy", test.WithCookie(cookie)) mux.ServeHTTP(w, r) @@ -229,7 +229,9 @@ func TestSessions(t *testing.T) { expected := []string{ "__csrf=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT; Max-Age=0; HttpOnly; Secure", - "__s=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT; Max-Age=0; HttpOnly; Secure", + "id_token=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT; Max-Age=0; HttpOnly; Secure", + "bearer_token=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT; Max-Age=0; HttpOnly; Secure", + "refresh_token=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT; Max-Age=0; HttpOnly; Secure", } assert.ElementsMatch(t, expected, w.Header().Values("Set-Cookie")) }) diff --git a/app/middleware/id_token.go b/app/middleware/id_token.go index e0b5b0d..dbaf691 100644 --- a/app/middleware/id_token.go +++ b/app/middleware/id_token.go @@ -21,7 +21,7 @@ func IDToken(cfg *oidc.OpenID, parsers ...TokenParser) func(http.Handler) http.H if err != nil { pls.LogError(r.Context(), err) - web.ExpireCookie(w, xcfg.SessionCookie) + web.ExpireCookie(w, xcfg.IDTokenCookie) } else { log.WithFields(r.Context(), log.Fields{"id_token": idToken}) next.ServeHTTP( diff --git a/app/middleware/id_token_test.go b/app/middleware/id_token_test.go index 31a4333..45221ff 100644 --- a/app/middleware/id_token_test.go +++ b/app/middleware/id_token_test.go @@ -11,7 +11,6 @@ import ( "github.com/stretchr/testify/require" "github.com/xlgmokha/x/pkg/log" "github.com/xlgmokha/x/pkg/test" - "github.com/xlgmokha/x/pkg/x" xcfg "gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/app/cfg" "gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/pkg/oidc" "gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/pkg/web" @@ -40,9 +39,7 @@ func TestIDToken(t *testing.T) { t.Run("attaches the token to the request context", func(t *testing.T) { user := mockoidc.DefaultUser() - token, rawIDToken := srv.CreateTokensFor(user) - tokens := &oidc.Tokens{Token: token, IDToken: oidc.RawToken(rawIDToken)} - encoded := x.Must(tokens.ToBase64String()) + _, rawIDToken := srv.CreateTokensFor(user) server := middleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { token := xcfg.IDToken.From(r.Context()) @@ -55,7 +52,7 @@ func TestIDToken(t *testing.T) { r, w := test.RequestResponse( "GET", "/example", - test.WithCookie(web.NewCookie(xcfg.SessionCookie, encoded)), + test.WithCookie(web.NewCookie(xcfg.IDTokenCookie, rawIDToken)), ) server.ServeHTTP(w, r) @@ -74,7 +71,7 @@ func TestIDToken(t *testing.T) { r, w := test.RequestResponse( "GET", "/example", - test.WithCookie(web.NewCookie(xcfg.SessionCookie, "invalid")), + test.WithCookie(web.NewCookie(xcfg.IDTokenCookie, "invalid")), ) server.ServeHTTP(w, r) diff --git a/app/middleware/token_parser.go b/app/middleware/token_parser.go index 08219b4..22a7af9 100644 --- a/app/middleware/token_parser.go +++ b/app/middleware/token_parser.go @@ -6,25 +6,16 @@ import ( "github.com/xlgmokha/x/pkg/x" "gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/app/cfg" "gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/pkg/oidc" - "gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/pkg/pls" - "gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/pkg/web" ) type TokenParser x.Mapper[*http.Request, oidc.RawToken] func IDTokenFromSessionCookie(r *http.Request) oidc.RawToken { - cookies := r.CookiesNamed(cfg.SessionCookie) + cookies := r.CookiesNamed(cfg.IDTokenCookie) if len(cookies) != 1 { return "" } - value := web.CookieValueFrom(cookies[0]) - tokens, err := oidc.TokensFromBase64String(value) - if err != nil { - pls.LogError(r.Context(), err) - return "" - } - - return tokens.IDToken + return oidc.RawToken(cookies[0].Value) } |
