summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormo khan <mo@mokhan.ca>2025-05-08 11:01:44 -0600
committermo khan <mo@mokhan.ca>2025-05-08 11:01:44 -0600
commitd4758497b63644b2baaef2115984fe7ba14fff2a (patch)
tree3b14c93d7fc261ff9eb8067885342011abcf466b
parentb7a520b8ef410d422db653d2680a2aafe3341013 (diff)
feat: test out a redirect page in staging
-rw-r--r--app/cfg/cfg.go4
-rw-r--r--app/controllers/sessions/controller.go96
-rw-r--r--app/controllers/sessions/controller_test.go27
-rw-r--r--app/controllers/sessions/dto.go5
-rw-r--r--app/views/sessions/redirect.html.tmpl9
5 files changed, 59 insertions, 82 deletions
diff --git a/app/cfg/cfg.go b/app/cfg/cfg.go
index 5b3025e..0700c5e 100644
--- a/app/cfg/cfg.go
+++ b/app/cfg/cfg.go
@@ -14,5 +14,5 @@ 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", "http://localhost:8080/session/callback")
-var SessionCookie string = "__Host-session"
-var CSRFCookie string = "__Host-csrf"
+var SessionCookie string = "__s"
+var CSRFCookie string = "__csrf"
diff --git a/app/controllers/sessions/controller.go b/app/controllers/sessions/controller.go
index 61fdaf8..d5b2ba6 100644
--- a/app/controllers/sessions/controller.go
+++ b/app/controllers/sessions/controller.go
@@ -2,12 +2,12 @@ package sessions
import (
"net/http"
- "time"
"github.com/xlgmokha/x/pkg/cookie"
- "github.com/xlgmokha/x/pkg/log"
+ "github.com/xlgmokha/x/pkg/env"
"gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/app/cfg"
"gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/app/middleware"
+ "gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/app/views"
"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"
@@ -36,14 +36,8 @@ func (c *Controller) New(w http.ResponseWriter, r *http.Request) {
}
url, nonce := c.svc.GenerateRedirectURL()
- // This cookie must be sent as part of a redirect that originates from the OIDC Provider
- cookie.Write(w, web.NewCookie(
- cfg.CSRFCookie,
- nonce,
- cookie.WithSameSite(http.SameSiteLaxMode),
- cookie.WithExpiration(time.Now().Add(10*time.Minute)),
- ))
- http.Redirect(w, r, url, http.StatusFound)
+ cookie.Write(w, web.NewCookie(cfg.CSRFCookie, nonce))
+ c.redirectTo(w, r, url)
}
/*
@@ -78,53 +72,6 @@ When it is decoded it has the following form:
}
```
-
-The `id_token` is a JWT that looks like the following body when it is decoded:
-
-```json
-
- {
- "iss": "http://gdk.test:3000",
- "sub": "1",
- "aud": "e31e1da0b8f6b6e35ca70c790b13c0406e44aca6b2bf67f55de7355a979a224f",
- "exp": 1745595639,
- "iat": 1745595519,
- "auth_time": 1745503338,
- "sub_legacy": "2474cf0b2211688a57297ace0e260a15944754d16b1bd42c9d6779c900367807",
- "name": "Administrator",
- "nickname": "root",
- "preferred_username": "root",
- "email": "admin@example.com",
- "email_verified": true,
- "profile": "http://gdk.test:3000/root",
- "picture": "https://www.gravatar.com/avatar/258d8dc916db8cea2cafb6c3cd0cb0246efe061421dbd83ec3a350428cabda4f?s=80&d=identicon",
- "groups_direct": [
- "gitlab-org",
- "toolbox",
- "mass_insert_group__0_100",
- "custom-roles-root-group/aa",
- "custom-roles-root-group/aa/aaa",
- "gnuwget",
- "Commit451",
- "jashkenas",
- "flightjs",
- "twitter",
- "gitlab-examples",
- "gitlab-examples/security",
- "412708",
- "gitlab-examples/demo-group",
- "custom-roles-root-group",
- "434044-group-1",
- "434044-group-2",
- "gitlab-org1",
- "gitlab-org/secure",
- "gitlab-org/secure/managers",
- "gitlab-org/security-products",
- "gitlab-org/security-products/analyzers"
- ]
- }
-
-```
*/
func (c *Controller) Create(w http.ResponseWriter, r *http.Request) {
tokens, err := c.svc.Exchange(r)
@@ -141,21 +88,28 @@ func (c *Controller) Create(w http.ResponseWriter, r *http.Request) {
return
}
- ck := web.NewCookie(cfg.SessionCookie, encoded,
- cookie.WithSameSite(http.SameSiteLaxMode),
- cookie.WithExpiration(tokens.Expiry),
- )
- log.WithFields(r.Context(), log.Fields{"cookie": ck, "error": ck.Valid()})
- if err := web.WriteCookie(w, ck); err != nil {
- pls.LogError(r.Context(), err)
- w.WriteHeader(http.StatusBadRequest)
- return
- }
- web.ExpireCookie(w, "oauth_state")
- http.Redirect(w, r, "/dashboard", http.StatusFound)
+ web.ExpireCookie(w, cfg.CSRFCookie)
+ web.WriteCookie(w, web.NewCookie(cfg.SessionCookie, encoded))
+
+ c.redirectTo(w, r, "/dashboard")
}
func (c *Controller) Destroy(w http.ResponseWriter, r *http.Request) {
- web.ExpireCookie(w, "session")
- http.Redirect(w, r, "/", http.StatusFound)
+ web.ExpireCookie(w, cfg.CSRFCookie)
+ web.ExpireCookie(w, cfg.SessionCookie)
+ c.redirectTo(w, r, "/")
+}
+
+func (c *Controller) redirectTo(w http.ResponseWriter, r *http.Request, location string) {
+ if env.Fetch("APP_ENV", "development") == "production" {
+ w.WriteHeader(http.StatusOK)
+ w.Header().Add("Content-Type", "text/html")
+
+ if err := views.Render(w, "sessions/redirect", &RedirectDTO{URL: location}); err != nil {
+ pls.LogError(r.Context(), err)
+ w.WriteHeader(http.StatusInternalServerError)
+ }
+ } else {
+ http.Redirect(w, r, location, http.StatusFound)
+ }
}
diff --git a/app/controllers/sessions/controller_test.go b/app/controllers/sessions/controller_test.go
index 82c56d5..6dcb3f3 100644
--- a/app/controllers/sessions/controller_test.go
+++ b/app/controllers/sessions/controller_test.go
@@ -6,7 +6,6 @@ import (
"net/http"
"net/url"
"testing"
- "time"
"github.com/oauth2-proxy/mockoidc"
"github.com/stretchr/testify/assert"
@@ -65,7 +64,8 @@ func TestSessions(t *testing.T) {
cookie, err := http.ParseSetCookie(w.Header().Get("Set-Cookie"))
require.NoError(t, err)
require.NotZero(t, cookie)
- assert.Equal(t, http.SameSiteLaxMode, cookie.SameSite)
+
+ assert.Equal(t, xcfg.CSRFCookie, cookie.Name)
})
})
@@ -124,10 +124,16 @@ func TestSessions(t *testing.T) {
mux.ServeHTTP(w, r)
- setCookieValue := w.Header().Get("Set-Cookie")
- cookie, err := http.ParseSetCookie(setCookieValue)
- require.NoError(t, err)
- require.NotZero(t, cookie)
+ cookieValues := w.Header().Values("Set-Cookie")
+ cookies := x.Map(cookieValues, func(line string) *http.Cookie {
+ ck, err := http.ParseSetCookie(line)
+ require.NoError(t, err)
+ 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{}{}
@@ -177,8 +183,6 @@ 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.Equal(t, http.SameSiteLaxMode, cookie.SameSite)
- assert.Equal(t, x.Must(time.Parse(time.RFC3339, tokens["expiry"].(string))).Unix(), cookie.Expires.Unix())
assert.True(t, cookie.HttpOnly)
assert.True(t, cookie.Secure)
assert.NotEmpty(t, cookie.Value)
@@ -195,7 +199,12 @@ func TestSessions(t *testing.T) {
require.Equal(t, http.StatusFound, w.Code)
assert.Equal(t, "/", w.Header().Get("Location"))
- assert.Equal(t, "session=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT; Max-Age=0; HttpOnly; Secure", w.Header().Get("Set-Cookie"))
+
+ 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",
+ }
+ assert.ElementsMatch(t, expected, w.Header().Values("Set-Cookie"))
})
})
}
diff --git a/app/controllers/sessions/dto.go b/app/controllers/sessions/dto.go
new file mode 100644
index 0000000..4bb959f
--- /dev/null
+++ b/app/controllers/sessions/dto.go
@@ -0,0 +1,5 @@
+package sessions
+
+type RedirectDTO struct {
+ URL string
+}
diff --git a/app/views/sessions/redirect.html.tmpl b/app/views/sessions/redirect.html.tmpl
new file mode 100644
index 0000000..e70e1d5
--- /dev/null
+++ b/app/views/sessions/redirect.html.tmpl
@@ -0,0 +1,9 @@
+<!doctype html>
+<html lang="en">
+ <head>
+ <meta http-equiv="refresh" content="0;URL='{{ .URL }}'"/>
+ </head>
+ <body>
+ <p>Moved to <a href="{{ .URL }}">location</a>.</p>
+ </body>
+</html>