summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authormo khan <mo@mokhan.ca>2025-05-15 14:42:08 -0600
committermo khan <mo@mokhan.ca>2025-05-15 14:42:08 -0600
commitc151c1a77d31c5e01885691b6df1ea7b0be0b0e5 (patch)
tree254aed8be6abaffaeba71df5bcb35d41d52bb2b2 /app
parent3d01a69471fc4f0ae9f2f4145620b6aea50f2216 (diff)
parentb6968005e1e1758e37edc7830c02e2217ee5fd90 (diff)
Merge branch 'envoy-cleanup' into 'main'
Delete code that is now handled by envoy See merge request gitlab-org/software-supply-chain-security/authorization/sparkled!7
Diffstat (limited to 'app')
-rw-r--r--app/app.go13
-rw-r--r--app/cfg/cfg.go5
-rw-r--r--app/controllers/sessions/controller.go130
-rw-r--r--app/controllers/sessions/controller_test.go253
-rw-r--r--app/controllers/sessions/dto.go19
-rw-r--r--app/controllers/sessions/service.go80
-rw-r--r--app/controllers/sessions/service_test.go92
-rw-r--r--app/init.go25
-rw-r--r--app/middleware/from_cookie.go15
-rw-r--r--app/middleware/id_token.go7
-rw-r--r--app/middleware/id_token_test.go12
-rw-r--r--app/middleware/init.go13
-rw-r--r--app/middleware/raw_token.go7
-rw-r--r--app/middleware/token_parser.go14
-rw-r--r--app/middleware/user.go2
-rw-r--r--app/middleware/user_test.go2
-rw-r--r--app/views/dashboard/nav.html.tmpl4
-rw-r--r--app/views/sessions/redirect.html.tmpl9
18 files changed, 63 insertions, 639 deletions
diff --git a/app/app.go b/app/app.go
index d959c4d..23f49bb 100644
--- a/app/app.go
+++ b/app/app.go
@@ -4,16 +4,16 @@ import (
"net/http"
"path/filepath"
+ "github.com/coreos/go-oidc/v3/oidc"
"github.com/rs/zerolog"
"github.com/xlgmokha/x/pkg/ioc"
"github.com/xlgmokha/x/pkg/log"
+ "gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/app/cfg"
"gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/app/controllers/dashboard"
"gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/app/controllers/health"
- "gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/app/controllers/sessions"
"gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/app/controllers/sparkles"
"gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/app/domain"
"gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/app/middleware"
- "gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/pkg/oidc"
)
type Mountable interface {
@@ -26,7 +26,6 @@ func New(rootDir string) http.Handler {
mountable := []Mountable{
ioc.MustResolve[*dashboard.Controller](ioc.Default),
ioc.MustResolve[*health.Controller](ioc.Default),
- ioc.MustResolve[*sessions.Controller](ioc.Default),
ioc.MustResolve[*sparkles.Controller](ioc.Default),
}
for _, m := range mountable {
@@ -37,9 +36,11 @@ func New(rootDir string) http.Handler {
mux.Handle("GET /", http.FileServer(dir))
logger := ioc.MustResolve[*zerolog.Logger](ioc.Default)
- oidc := ioc.MustResolve[*oidc.OpenID](ioc.Default)
users := ioc.MustResolve[domain.Repository[*domain.User]](ioc.Default)
-
- chain := middleware.IDToken(oidc, middleware.IDTokenFromSessionCookie)(middleware.User(users)(mux))
+ chain := middleware.IDToken(
+ ioc.MustResolve[*oidc.Provider](ioc.Default),
+ ioc.MustResolve[*oidc.Config](ioc.Default),
+ middleware.FromCookie(cfg.IDTokenCookie),
+ )(middleware.User(users)(mux))
return log.HTTP(logger)(chain)
}
diff --git a/app/cfg/cfg.go b/app/cfg/cfg.go
index 1dffa16..b423413 100644
--- a/app/cfg/cfg.go
+++ b/app/cfg/cfg.go
@@ -1,20 +1,17 @@
package cfg
import (
+ "github.com/coreos/go-oidc/v3/oidc"
"github.com/xlgmokha/x/pkg/context"
"github.com/xlgmokha/x/pkg/env"
"gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/app/domain"
- "gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/pkg/oidc"
)
var CurrentUser context.Key[*domain.User] = context.Key[*domain.User]("current_user")
var IDToken context.Key[*oidc.IDToken] = context.Key[*oidc.IDToken]("id_token")
var OIDCIssuer string = env.Fetch("OIDC_ISSUER", "https://gitlab.com")
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 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
deleted file mode 100644
index 898244c..0000000
--- a/app/controllers/sessions/controller.go
+++ /dev/null
@@ -1,130 +0,0 @@
-package sessions
-
-import (
- "net/http"
-
- "github.com/xlgmokha/x/pkg/cookie"
- "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/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 Controller struct {
- svc *Service
-}
-
-func New(cfg *oidc.OpenID, http *http.Client) *Controller {
- return &Controller{
- svc: NewService(cfg, http),
- }
-}
-
-func (c *Controller) MountTo(mux *http.ServeMux) {
- mux.HandleFunc("GET /session/new", c.New)
- mux.HandleFunc("GET /session", c.Show)
- mux.HandleFunc("GET /session/callback", c.Create)
- mux.HandleFunc("POST /session/destroy", c.Destroy)
-}
-
-func (c *Controller) New(w http.ResponseWriter, r *http.Request) {
- if middleware.IsLoggedIn(r) {
- http.Redirect(w, r, "/dashboard", http.StatusFound)
- return
- }
-
- url, nonce := c.svc.GenerateRedirectURL(r)
- cookie.Write(w, web.NewCookie(cfg.CSRFCookie, nonce))
- c.redirectTo(w, r, url)
-}
-
-func (c *Controller) Show(w http.ResponseWriter, r *http.Request) {
- cookie, err := r.Cookie(cfg.IDTokenCookie)
- if err != nil {
- pls.LogError(r.Context(), err)
- w.WriteHeader(http.StatusNotFound)
- return
- }
-
- token, err := c.svc.JWTBody(r.Context(), oidc.RawToken(cookie.Value))
- if err != nil {
- pls.LogError(r.Context(), err)
- w.WriteHeader(http.StatusNotFound)
- return
- }
-
- w.WriteHeader(http.StatusOK)
- w.Write(token)
-}
-
-/*
-This is the callback endpoint from the OIDC Provider:
-
-It will exchange a grant for the following tokens:
-
-* access_token
-* id_token
-* refresh_token
-
-# These tokens are encoded as a Base64 JSON string and stored in a session cookie
-
-For Example:
-
-The following is an example of the base64 value stored in the session cookie:
-
-```base64
-eyJhY2Nlc3NfdG9rZW4iOiJkNzQ2ZTVmMGQ2NmYyNTgxM2ZjYzIyYzNjY2E0YmYxYjNmOTQwMjQ5NTkxYTg4YzZmMDBjMDQzZTMxYTVkZDRhIiwidG9rZW5fdHlwZSI6IkJlYXJlciIsInJlZnJlc2hfdG9rZW4iOiIyZGUxNTFhMGQ2ZGJhNzU5MDVmNGRmZTRlZThkNmQ5MGNjZmRkYzYxYjJkNGRlNzU2ODRiYzFjYmY5YjE0ODBlIiwiZXhwaXJ5IjoiMjAyNS0wNC0yNVQxMTozODozOS4zNDAwNDc4MjQtMDY6MDAiLCJpZF90b2tlbiI6ImV5SjBlWEFpT2lKS1YxUWlMQ0pyYVdRaU9pSjBaREJUYldSS1VUUnhVR2cxY1U1TGVrMHlOakJEV0hneVZXZ3RkMmhITFUxRWFtOVBTMWRtZERoRklpd2lZV3huSWpvaVVsTXlOVFlpZlEuZXlKcGMzTWlPaUpvZEhSd09pOHZaMlJyTG5SbGMzUTZNekF3TUNJc0luTjFZaUk2SWpFaUxDSmhkV1FpT2lKbE16RmxNV1JoTUdJNFpqWmlObVV6TldOaE56QmpOemt3WWpFell6QTBNRFpsTkRSaFkyRTJZakppWmpZM1pqVTFaR1UzTXpVMVlUazNPV0V5TWpSbUlpd2laWGh3SWpveE56UTFOVGsxTmpNNUxDSnBZWFFpT2pFM05EVTFPVFUxTVRrc0ltRjFkR2hmZEdsdFpTSTZNVGMwTlRVd016TXpPQ3dpYzNWaVgyeGxaMkZqZVNJNklqSTBOelJqWmpCaU1qSXhNVFk0T0dFMU56STVOMkZqWlRCbE1qWXdZVEUxT1RRME56VTBaREUyWWpGaVpEUXlZemxrTmpjM09XTTVNREF6TmpjNE1EY2lMQ0p1WVcxbElqb2lRV1J0YVc1cGMzUnlZWFJ2Y2lJc0ltNXBZMnR1WVcxbElqb2ljbTl2ZENJc0luQnlaV1psY25KbFpGOTFjMlZ5Ym1GdFpTSTZJbkp2YjNRaUxDSmxiV0ZwYkNJNkltRmtiV2x1UUdWNFlXMXdiR1V1WTI5dElpd2laVzFoYVd4ZmRtVnlhV1pwWldRaU9uUnlkV1VzSW5CeWIyWnBiR1VpT2lKb2RIUndPaTh2WjJSckxuUmxjM1E2TXpBd01DOXliMjkwSWl3aWNHbGpkSFZ5WlNJNkltaDBkSEJ6T2k4dmQzZDNMbWR5WVhaaGRHRnlMbU52YlM5aGRtRjBZWEl2TWpVNFpEaGtZemt4Tm1SaU9HTmxZVEpqWVdaaU5tTXpZMlF3WTJJd01qUTJaV1psTURZeE5ESXhaR0prT0RObFl6TmhNelV3TkRJNFkyRmlaR0UwWmo5elBUZ3dKbVE5YVdSbGJuUnBZMjl1SWl3aVozSnZkWEJ6WDJScGNtVmpkQ0k2V3lKbmFYUnNZV0l0YjNKbklpd2lkRzl2YkdKdmVDSXNJbTFoYzNOZmFXNXpaWEowWDJkeWIzVndYMTh3WHpFd01DSXNJbU4xYzNSdmJTMXliMnhsY3kxeWIyOTBMV2R5YjNWd0wyRmhJaXdpWTNWemRHOXRMWEp2YkdWekxYSnZiM1F0WjNKdmRYQXZZV0V2WVdGaElpd2laMjUxZDJkbGRDSXNJa052YlcxcGREUTFNU0lzSW1waGMyaHJaVzVoY3lJc0ltWnNhV2RvZEdweklpd2lkSGRwZEhSbGNpSXNJbWRwZEd4aFlpMWxlR0Z0Y0d4bGN5SXNJbWRwZEd4aFlpMWxlR0Z0Y0d4bGN5OXpaV04xY21sMGVTSXNJalF4TWpjd09DSXNJbWRwZEd4aFlpMWxlR0Z0Y0d4bGN5OWtaVzF2TFdkeWIzVndJaXdpWTNWemRHOXRMWEp2YkdWekxYSnZiM1F0WjNKdmRYQWlMQ0kwTXpRd05EUXRaM0p2ZFhBdE1TSXNJalF6TkRBME5DMW5jbTkxY0MweUlpd2laMmwwYkdGaUxXOXlaekVpTENKbmFYUnNZV0l0YjNKbkwzTmxZM1Z5WlNJc0ltZHBkR3hoWWkxdmNtY3ZjMlZqZFhKbEwyMWhibUZuWlhKeklpd2laMmwwYkdGaUxXOXlaeTl6WldOMWNtbDBlUzF3Y205a2RXTjBjeUlzSW1kcGRHeGhZaTF2Y21jdmMyVmpkWEpwZEhrdGNISnZaSFZqZEhNdllXNWhiSGw2WlhKeklsMTkuZ2Fwc01vcVJSOWZyVS1MQTVYaUtaMC1PYWVkNG1SSXNiOG5JbEJuVUswM1lTVTY4R2Y5WlhLV1F0VHMwbGpCekNxLWZhOXBWY0I5YU1TUnZ0bGJuZ0doNFU0aWpWUGU0am5vWC01VXJZaTJpTEYxdDJ5VGRFWEhDSWg2bXNBLXJEUTUwR2UxNUtaSmRXTE0tbFo0VGhNNENlbGpQMWF4NUJjeUV0UG1pcmZIaHppR3pKYmFEczRVMk5aaW1hcHo3Q1hSX3FaeHI0ajYyQW00dmVYXzhPaDFhT1I2bUtDMTlCZUlqeFozWlZ3Z0x3UUVsaFlLcEhUWTRSS2ZnUkh3TVlXVGZIZUF0VTM4UTV0VW9DSGU0RW1wcEIza0x0aW1Gemp2YWhnMGRjazBzc3FTWkh4X252cXJldjctSVdKa096OVRSVG04SU1xU3h4OUxxd1pCVFRRIn0=
-```
-
-When it is decoded it has the following form:
-
-```json
-
- {
- "access_token": "d746e5f0d66f25813fcc22c3cca4bf1b3f940249591a88c6f00c043e31a5dd4a",
- "token_type": "Bearer",
- "refresh_token": "2de151a0d6dba75905f4dfe4ee8d6d90ccfddc61b2d4de75684bc1cbf9b1480e",
- "expiry": "2025-04-25T11:38:39.340047824-06:00",
- "id_token": "eyJ0eXAiOiJKV1QiLCJraWQiOiJ0ZDBTbWRKUTRxUGg1cU5Lek0yNjBDWHgyVWgtd2hHLU1Eam9PS1dmdDhFIiwiYWxnIjoiUlMyNTYifQ.eyJpc3MiOiJodHRwOi8vZ2RrLnRlc3Q6MzAwMCIsInN1YiI6IjEiLCJhdWQiOiJlMzFlMWRhMGI4ZjZiNmUzNWNhNzBjNzkwYjEzYzA0MDZlNDRhY2E2YjJiZjY3ZjU1ZGU3MzU1YTk3OWEyMjRmIiwiZXhwIjoxNzQ1NTk1NjM5LCJpYXQiOjE3NDU1OTU1MTksImF1dGhfdGltZSI6MTc0NTUwMzMzOCwic3ViX2xlZ2FjeSI6IjI0NzRjZjBiMjIxMTY4OGE1NzI5N2FjZTBlMjYwYTE1OTQ0NzU0ZDE2YjFiZDQyYzlkNjc3OWM5MDAzNjc4MDciLCJuYW1lIjoiQWRtaW5pc3RyYXRvciIsIm5pY2tuYW1lIjoicm9vdCIsInByZWZlcnJlZF91c2VybmFtZSI6InJvb3QiLCJlbWFpbCI6ImFkbWluQGV4YW1wbGUuY29tIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsInByb2ZpbGUiOiJodHRwOi8vZ2RrLnRlc3Q6MzAwMC9yb290IiwicGljdHVyZSI6Imh0dHBzOi8vd3d3LmdyYXZhdGFyLmNvbS9hdmF0YXIvMjU4ZDhkYzkxNmRiOGNlYTJjYWZiNmMzY2QwY2IwMjQ2ZWZlMDYxNDIxZGJkODNlYzNhMzUwNDI4Y2FiZGE0Zj9zPTgwJmQ9aWRlbnRpY29uIiwiZ3JvdXBzX2RpcmVjdCI6WyJnaXRsYWItb3JnIiwidG9vbGJveCIsIm1hc3NfaW5zZXJ0X2dyb3VwX18wXzEwMCIsImN1c3RvbS1yb2xlcy1yb290LWdyb3VwL2FhIiwiY3VzdG9tLXJvbGVzLXJvb3QtZ3JvdXAvYWEvYWFhIiwiZ251d2dldCIsIkNvbW1pdDQ1MSIsImphc2hrZW5hcyIsImZsaWdodGpzIiwidHdpdHRlciIsImdpdGxhYi1leGFtcGxlcyIsImdpdGxhYi1leGFtcGxlcy9zZWN1cml0eSIsIjQxMjcwOCIsImdpdGxhYi1leGFtcGxlcy9kZW1vLWdyb3VwIiwiY3VzdG9tLXJvbGVzLXJvb3QtZ3JvdXAiLCI0MzQwNDQtZ3JvdXAtMSIsIjQzNDA0NC1ncm91cC0yIiwiZ2l0bGFiLW9yZzEiLCJnaXRsYWItb3JnL3NlY3VyZSIsImdpdGxhYi1vcmcvc2VjdXJlL21hbmFnZXJzIiwiZ2l0bGFiLW9yZy9zZWN1cml0eS1wcm9kdWN0cyIsImdpdGxhYi1vcmcvc2VjdXJpdHktcHJvZHVjdHMvYW5hbHl6ZXJzIl19.gapsMoqRR9frU-LA5XiKZ0-Oaed4mRIsb8nIlBnUK03YSU68Gf9ZXKWQtTs0ljBzCq-fa9pVcB9aMSRvtlbngGh4U4ijVPe4jnoX-5UrYi2iLF1t2yTdEXHCIh6msA-rDQ50Ge15KZJdWLM-lZ4ThM4CeljP1ax5BcyEtPmirfHhziGzJbaDs4U2NZimapz7CXR_qZxr4j62Am4veX_8Oh1aOR6mKC19BeIjxZ3ZVwgLwQElhYKpHTY4RKfgRHwMYWTfHeAtU38Q5tUoCHe4EmppB3kLtimFzjvahg0dck0ssqSZHx_nvqrev7-IWJkOz9TRTm8IMqSxx9LqwZBTTQ"
- }
-
-```
-*/
-func (c *Controller) Create(w http.ResponseWriter, r *http.Request) {
- if middleware.IsLoggedIn(r) {
- http.Redirect(w, r, "/dashboard", http.StatusFound)
- return
- }
-
- tokens, err := c.svc.Exchange(r)
- if err != nil {
- pls.LogError(r.Context(), err)
- w.WriteHeader(http.StatusBadRequest)
- return
- }
-
- web.ExpireCookie(w, cfg.CSRFCookie)
- 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.IDTokenCookie)
- web.ExpireCookie(w, cfg.BearerTokenCookie)
- web.ExpireCookie(w, cfg.RefreshTokenCookie)
- c.redirectTo(w, r, "/")
-}
-
-func (c *Controller) redirectTo(w http.ResponseWriter, r *http.Request, location string) {
- if env.Fetch("APP_ENV", "development") == "production" {
- (&RedirectDTO{URL: location}).ServeHTTP(w, r)
- } else {
- http.Redirect(w, r, location, http.StatusFound)
- }
-}
diff --git a/app/controllers/sessions/controller_test.go b/app/controllers/sessions/controller_test.go
deleted file mode 100644
index 3e7f662..0000000
--- a/app/controllers/sessions/controller_test.go
+++ /dev/null
@@ -1,253 +0,0 @@
-package sessions
-
-import (
- "net/http"
- "net/url"
- "testing"
-
- "github.com/oauth2-proxy/mockoidc"
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
- "github.com/xlgmokha/x/pkg/serde"
- "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/app/domain"
- "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"
-)
-
-func TestSessions(t *testing.T) {
- srv := oidc.NewTestServer(t)
- defer srv.Close()
-
- clientID := srv.MockOIDC.Config().ClientID
- clientSecret := srv.MockOIDC.Config().ClientSecret
- cfg := oidc.New(
- srv.Provider,
- clientID,
- clientSecret,
- "callback_url",
- )
- controller := New(cfg, http.DefaultClient)
- mux := http.NewServeMux()
- controller.MountTo(mux)
-
- t.Run("GET /session/new", func(t *testing.T) {
- t.Run("without an authenticated session", func(t *testing.T) {
- r, w := test.RequestResponse("GET", "/session/new")
-
- mux.ServeHTTP(w, r)
-
- t.Run("redirect to the OIDC Provider", func(t *testing.T) {
- require.Equal(t, http.StatusFound, w.Code)
- require.NotEmpty(t, w.Header().Get("Location"))
- redirectURL, err := url.Parse(w.Header().Get("Location"))
- require.NoError(t, err)
- assert.Equal(t, srv.AuthorizationEndpoint(), redirectURL.Scheme+"://"+redirectURL.Host+redirectURL.Path)
- assert.NotEmpty(t, redirectURL.Query().Get("state"))
- 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, cfg.Config.ClientID, redirectURL.Query().Get("audience"))
- assert.Equal(t, cfg.Config.RedirectURL, redirectURL.Query().Get("redirect_uri"))
- assert.Equal(t, "code", redirectURL.Query().Get("response_type"))
- })
-
- t.Run("generates a CSRF token", func(t *testing.T) {
- cookieHeader := w.Header().Get("Set-Cookie")
- require.NotEmpty(t, cookieHeader)
-
- cookie, err := http.ParseSetCookie(w.Header().Get("Set-Cookie"))
- require.NoError(t, err)
- require.NotZero(t, cookie)
-
- assert.Equal(t, xcfg.CSRFCookie, cookie.Name)
- })
- })
-
- t.Run("with an active authenicated session", func(t *testing.T) {
- t.Run("redirects to the dashboard", func(t *testing.T) {
- user := &domain.User{}
- r, w := test.RequestResponse(
- "GET",
- "/session/new",
- test.WithContextKeyValue(t.Context(), xcfg.CurrentUser, user),
- )
-
- mux.ServeHTTP(w, r)
-
- require.Equal(t, http.StatusFound, w.Code)
- assert.Equal(t, "/dashboard", w.Header().Get("Location"))
- })
- })
- })
-
- t.Run("GET /session/callback", func(t *testing.T) {
- t.Run("with an invalid csrf token", func(t *testing.T) {
- user := mockoidc.DefaultUser()
- code := srv.CreateAuthorizationCodeFor(user)
- nonce := pls.GenerateRandomHex(32)
-
- r, w := test.RequestResponse(
- "GET",
- "/session/callback?code="+code+"&state=invalid",
- test.WithCookie(web.NewCookie(xcfg.CSRFCookie, nonce)),
- )
-
- mux.ServeHTTP(w, r)
-
- require.Equal(t, http.StatusBadRequest, w.Code)
- })
-
- t.Run("with an invalid authorization code grant", func(t *testing.T) {
- r, w := test.RequestResponse("GET", "/session/callback?code=invalid")
-
- mux.ServeHTTP(w, r)
-
- assert.Equal(t, http.StatusBadRequest, w.Code)
- })
-
- t.Run("when already logged in", func(t *testing.T) {
- t.Run("redirects to the dashboard", func(t *testing.T) {
- user := &domain.User{}
- r, w := test.RequestResponse(
- "GET",
- "/session/callback?code=valid",
- test.WithContextKeyValue(t.Context(), xcfg.CurrentUser, user),
- )
-
- mux.ServeHTTP(w, r)
-
- require.Equal(t, http.StatusFound, w.Code)
- assert.Equal(t, "/dashboard", w.Header().Get("Location"))
- })
- })
-
- t.Run("with a valid authorization code grant", func(t *testing.T) {
- user := mockoidc.DefaultUser()
- code := srv.CreateAuthorizationCodeFor(user)
- nonce := pls.GenerateRandomHex(32)
-
- r, w := test.RequestResponse(
- "GET",
- "/session/callback?code="+code+"&state="+nonce,
- test.WithCookie(web.NewCookie(xcfg.CSRFCookie, nonce)),
- )
-
- mux.ServeHTTP(w, r)
-
- 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
- })
-
- t.Run("stores the id token in a session cookie", func(t *testing.T) {
- cookie := x.Find(cookies, func(item *http.Cookie) bool {
- return item.Name == xcfg.IDTokenCookie
- })
-
- 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) {
- 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(cookie.Value, nil)
- require.NoError(t, err)
-
- sub, err := token.Claims.GetSubject()
- require.NoError(t, err)
- assert.Equal(t, user.Subject, sub)
- })
-
- t.Run("stores the refresh token in a session cookie", func(t *testing.T) {
- 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(cookie.Value, nil)
- require.NoError(t, err)
-
- sub, err := token.Claims.GetSubject()
- require.NoError(t, err)
- assert.Equal(t, user.Subject, sub)
- })
-
- t.Run("redirects to the homepage", func(t *testing.T) {
- require.Equal(t, http.StatusFound, w.Code)
- assert.Equal(t, "/dashboard", w.Header().Get("Location"))
- })
-
- t.Run("applies the appropriate cookie settings", func(t *testing.T) {
- 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)
- })
- })
- })
- })
-
- t.Run("GET /session", func(t *testing.T) {
- t.Run("with an id_token cookie", func(t *testing.T) {
- user := mockoidc.DefaultUser()
- _, rawIDToken := srv.CreateTokensFor(user)
- cookie := &http.Cookie{Name: xcfg.IDTokenCookie, Value: rawIDToken}
- r, w := test.RequestResponse("GET", "/session", test.WithCookie(cookie))
-
- mux.ServeHTTP(w, r)
-
- require.Equal(t, http.StatusOK, w.Code)
- items, err := serde.FromJSON[map[string]interface{}](w.Body)
- require.NoError(t, err)
- assert.Equal(t, srv.Issuer(), items["iss"])
- })
-
- t.Run("without an id_token cookie", func(t *testing.T) {
- r, w := test.RequestResponse("GET", "/session")
-
- mux.ServeHTTP(w, r)
-
- require.Equal(t, http.StatusNotFound, w.Code)
- })
- })
-
- t.Run("POST /session/destroy", func(t *testing.T) {
- t.Run("clears the session cookie", func(t *testing.T) {
- cookie := web.NewCookie(xcfg.IDTokenCookie, "value")
- r, w := test.RequestResponse("POST", "/session/destroy", test.WithCookie(cookie))
-
- mux.ServeHTTP(w, r)
-
- require.Equal(t, http.StatusFound, w.Code)
- assert.Equal(t, "/", w.Header().Get("Location"))
-
- expected := []string{
- "__csrf=; 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/controllers/sessions/dto.go b/app/controllers/sessions/dto.go
deleted file mode 100644
index a3ce6ba..0000000
--- a/app/controllers/sessions/dto.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package sessions
-
-import (
- "net/http"
-
- "gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/app/views"
- "gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/pkg/pls"
-)
-
-type RedirectDTO struct {
- URL string
-}
-
-func (d *RedirectDTO) ServeHTTP(w http.ResponseWriter, r *http.Request) {
- w.WriteHeader(http.StatusOK)
- w.Header().Add("Content-Type", "text/html")
-
- pls.LogError(r.Context(), views.Render(w, "sessions/redirect", d))
-}
diff --git a/app/controllers/sessions/service.go b/app/controllers/sessions/service.go
deleted file mode 100644
index c0466e4..0000000
--- a/app/controllers/sessions/service.go
+++ /dev/null
@@ -1,80 +0,0 @@
-package sessions
-
-import (
- "context"
- "encoding/base64"
- "errors"
- "net/http"
- "net/url"
- "strings"
-
- "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"
- "golang.org/x/oauth2"
-)
-
-type Service struct {
- cfg *oidc.OpenID
- http *http.Client
-}
-
-func NewService(cfg *oidc.OpenID, http *http.Client) *Service {
- return &Service{
- cfg: cfg,
- http: http,
- }
-}
-
-func (svc *Service) GenerateRedirectURL(r *http.Request) (string, string) {
- nonce := pls.GenerateRandomHex(32)
- url := svc.cfg.Config.AuthCodeURL(
- nonce,
- oauth2.SetAuthURLParam("audience", svc.cfg.Config.ClientID),
- oauth2.SetAuthURLParam("redirect_uri", svc.redirectURIFor(r)),
- )
- return url, nonce
-}
-
-func (svc *Service) Exchange(r *http.Request) (*oidc.Tokens, error) {
- cookies := r.CookiesNamed(cfg.CSRFCookie)
- if len(cookies) != 1 {
- return nil, errors.New("Missing CSRF token")
- }
-
- state := r.URL.Query().Get("state")
- if state != cookies[0].Value {
- return nil, errors.New("Invalid CSRF token")
- }
-
- ctx := context.WithValue(r.Context(), oauth2.HTTPClient, svc.http)
-
- token, err := svc.cfg.Config.Exchange(ctx, r.URL.Query().Get("code"))
- if err != nil {
- return nil, err
- }
-
- tokens := &oidc.Tokens{Token: token}
- if rawIDToken, ok := token.Extra("id_token").(string); ok {
- tokens.IDToken = oidc.RawToken(rawIDToken)
- }
- return tokens, nil
-}
-
-func (svc *Service) JWTBody(ctx context.Context, raw oidc.RawToken) ([]byte, error) {
- sections := strings.SplitN(raw.String(), ".", 3)
- if len(sections) != 3 {
- return nil, errors.New("Invalid JWT")
- }
-
- return base64.RawURLEncoding.DecodeString(sections[1])
-}
-
-func (svc *Service) redirectURIFor(r *http.Request) string {
- if len(svc.cfg.Config.RedirectURL) > 0 {
- return svc.cfg.Config.RedirectURL
- }
- redirectURL, _ := url.Parse(r.URL.String())
- redirectURL.Path = "/session/callback"
- return redirectURL.String()
-}
diff --git a/app/controllers/sessions/service_test.go b/app/controllers/sessions/service_test.go
deleted file mode 100644
index 05baa2f..0000000
--- a/app/controllers/sessions/service_test.go
+++ /dev/null
@@ -1,92 +0,0 @@
-package sessions
-
-import (
- "net/http"
- "testing"
-
- "github.com/oauth2-proxy/mockoidc"
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
- "github.com/xlgmokha/x/pkg/test"
- 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/pls"
- "gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/pkg/web"
-)
-
-func TestService(t *testing.T) {
- srv := oidc.NewTestServer(t)
- defer srv.Close()
-
- clientID := srv.MockOIDC.Config().ClientID
- clientSecret := srv.MockOIDC.Config().ClientSecret
- cfg := oidc.New(
- srv.Provider,
- clientID,
- clientSecret,
- "/session/callback",
- )
- svc := NewService(cfg, http.DefaultClient)
-
- t.Run("Exchange", func(t *testing.T) {
- t.Run("when the csrf token is missing", func(t *testing.T) {
- r := test.Request("GET", "/session/callback")
- tokens, err := svc.Exchange(r)
-
- require.Error(t, err)
- assert.Nil(t, tokens)
- })
-
- t.Run("when the csrf token is invalid", func(t *testing.T) {
- user := mockoidc.DefaultUser()
- code := srv.CreateAuthorizationCodeFor(user)
- nonce := pls.GenerateRandomHex(32)
-
- r := test.Request(
- "GET",
- "/session/callback?code="+code+"&state=invalid",
- test.WithCookie(web.NewCookie(xcfg.CSRFCookie, nonce)),
- )
- tokens, err := svc.Exchange(r)
-
- require.Error(t, err)
- assert.Nil(t, tokens)
- })
-
- t.Run("with an invalid authorization code grant", func(t *testing.T) {
- nonce := pls.GenerateRandomHex(32)
-
- r := test.Request(
- "GET", "/session/callback?code=invalid",
- test.WithCookie(web.NewCookie(xcfg.CSRFCookie, nonce)),
- )
-
- tokens, err := svc.Exchange(r)
-
- require.Error(t, err)
- assert.Nil(t, tokens)
- })
-
- t.Run("with a valid grant", func(t *testing.T) {
- user := mockoidc.DefaultUser()
- code := srv.CreateAuthorizationCodeFor(user)
- nonce := pls.GenerateRandomHex(32)
-
- r := test.Request(
- "GET",
- "/session/callback?code="+code+"&state="+nonce,
- test.WithCookie(web.NewCookie(xcfg.CSRFCookie, nonce)),
- )
-
- tokens, err := svc.Exchange(r)
-
- require.NoError(t, err)
- assert.NotNil(t, tokens)
- assert.NotEmpty(t, tokens.AccessToken)
- assert.NotEmpty(t, tokens.Expiry)
- assert.NotEmpty(t, tokens.TokenType)
- assert.NotEmpty(t, tokens.RefreshToken)
- assert.NotEmpty(t, tokens.IDToken)
- })
- })
-}
diff --git a/app/init.go b/app/init.go
index 8de5461..7ea0dd2 100644
--- a/app/init.go
+++ b/app/init.go
@@ -5,18 +5,16 @@ import (
"net/http"
"os"
- xoidc "github.com/coreos/go-oidc/v3/oidc"
+ "github.com/coreos/go-oidc/v3/oidc"
"github.com/rs/zerolog"
"github.com/xlgmokha/x/pkg/ioc"
"github.com/xlgmokha/x/pkg/log"
"gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/app/cfg"
"gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/app/controllers/dashboard"
"gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/app/controllers/health"
- "gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/app/controllers/sessions"
"gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/app/controllers/sparkles"
"gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/app/db"
"gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/app/domain"
- "gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/pkg/oidc"
"gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/pkg/web"
"golang.org/x/oauth2"
)
@@ -50,25 +48,16 @@ func init() {
},
}
})
- ioc.Register[*xoidc.Provider](ioc.Default, func() *xoidc.Provider {
+ ioc.Register[*oidc.Provider](ioc.Default, func() *oidc.Provider {
ctx := context.WithValue(context.Background(), oauth2.HTTPClient, ioc.MustResolve[*http.Client](ioc.Default))
- return oidc.NewProvider(ctx, cfg.OIDCIssuer, func(err error) {
+ return web.NewOIDCProvider(ctx, cfg.OIDCIssuer, func(err error) {
ioc.MustResolve[*zerolog.Logger](ioc.Default).Err(err).Send()
})
})
- ioc.RegisterSingleton[*oidc.OpenID](ioc.Default, func() *oidc.OpenID {
- return oidc.New(
- ioc.MustResolve[*xoidc.Provider](ioc.Default),
- cfg.OAuthClientID,
- cfg.OAuthClientSecret,
- cfg.OAuthRedirectURL,
- )
- })
- ioc.Register[*sessions.Controller](ioc.Default, func() *sessions.Controller {
- return sessions.New(
- ioc.MustResolve[*oidc.OpenID](ioc.Default),
- ioc.MustResolve[*http.Client](ioc.Default),
- )
+ ioc.Register[*oidc.Config](ioc.Default, func() *oidc.Config {
+ return &oidc.Config{
+ ClientID: cfg.OAuthClientID,
+ }
})
http.DefaultClient = ioc.MustResolve[*http.Client](ioc.Default)
diff --git a/app/middleware/from_cookie.go b/app/middleware/from_cookie.go
new file mode 100644
index 0000000..316d6e4
--- /dev/null
+++ b/app/middleware/from_cookie.go
@@ -0,0 +1,15 @@
+package middleware
+
+import "net/http"
+
+func FromCookie(name string) TokenParser {
+ return func(r *http.Request) RawToken {
+ cookies := r.CookiesNamed(name)
+
+ if len(cookies) != 1 {
+ return ""
+ }
+
+ return RawToken(cookies[0].Value)
+ }
+}
diff --git a/app/middleware/id_token.go b/app/middleware/id_token.go
index dbaf691..8084af0 100644
--- a/app/middleware/id_token.go
+++ b/app/middleware/id_token.go
@@ -3,21 +3,22 @@ package middleware
import (
"net/http"
+ "github.com/coreos/go-oidc/v3/oidc"
"github.com/xlgmokha/x/pkg/log"
"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/pls"
"gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/pkg/web"
)
-func IDToken(cfg *oidc.OpenID, parsers ...TokenParser) func(http.Handler) http.Handler {
+func IDToken(provider *oidc.Provider, config *oidc.Config, parsers ...TokenParser) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
for _, parser := range parsers {
rawIDToken := parser(r)
if x.IsPresent(rawIDToken) {
- idToken, err := cfg.ValidateIDToken(r.Context(), rawIDToken)
+ verifier := provider.VerifierContext(r.Context(), config)
+ idToken, err := verifier.Verify(r.Context(), rawIDToken.String())
if err != nil {
pls.LogError(r.Context(), err)
diff --git a/app/middleware/id_token_test.go b/app/middleware/id_token_test.go
index b363d2c..5487ada 100644
--- a/app/middleware/id_token_test.go
+++ b/app/middleware/id_token_test.go
@@ -4,23 +4,23 @@ import (
"net/http"
"testing"
+ "github.com/coreos/go-oidc/v3/oidc"
"github.com/oauth2-proxy/mockoidc"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/xlgmokha/x/pkg/test"
+ "gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/app/cfg"
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"
)
func TestIDToken(t *testing.T) {
- srv := oidc.NewTestServer(t)
+ srv := web.NewOIDCServer(t)
defer srv.Close()
- openID := oidc.New(srv.Provider, srv.MockOIDC.ClientID, srv.MockOIDC.ClientSecret, "https://example.com/oauth/callback")
- middleware := IDToken(openID, IDTokenFromSessionCookie)
+ middleware := IDToken(srv.Provider, &oidc.Config{ClientID: srv.MockOIDC.ClientID}, FromCookie(cfg.IDTokenCookie))
- t.Run("when an active session cookie is provided", func(t *testing.T) {
+ t.Run("when an active id_token cookie is provided", func(t *testing.T) {
t.Run("attaches the token to the request context", func(t *testing.T) {
user := mockoidc.DefaultUser()
@@ -45,7 +45,7 @@ func TestIDToken(t *testing.T) {
})
})
- t.Run("when an invalid session cookie is provided", func(t *testing.T) {
+ t.Run("when an invalid id_token cookie is provided", func(t *testing.T) {
t.Run("forwards the request", func(t *testing.T) {
server := middleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
require.Nil(t, xcfg.IDToken.From(r.Context()))
diff --git a/app/middleware/init.go b/app/middleware/init.go
index f1a693d..874ca52 100644
--- a/app/middleware/init.go
+++ b/app/middleware/init.go
@@ -1,14 +1,23 @@
package middleware
import (
+ "github.com/coreos/go-oidc/v3/oidc"
"github.com/xlgmokha/x/pkg/mapper"
"gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/app/domain"
- "gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/pkg/oidc"
)
+type CustomClaims struct {
+ Name string `json:"name"`
+ Nickname string `json:"nickname"`
+ Email string `json:"email"`
+ ProfileURL string `json:"profile"`
+ Picture string `json:"picture"`
+ Groups []string `json:"groups_direct"`
+}
+
func init() {
mapper.Register(func(idToken *oidc.IDToken) *domain.User {
- customClaims := &oidc.CustomClaims{}
+ customClaims := &CustomClaims{}
if err := idToken.Claims(customClaims); err != nil {
return &domain.User{ID: domain.ID(idToken.Subject)}
}
diff --git a/app/middleware/raw_token.go b/app/middleware/raw_token.go
new file mode 100644
index 0000000..f7aa264
--- /dev/null
+++ b/app/middleware/raw_token.go
@@ -0,0 +1,7 @@
+package middleware
+
+type RawToken string
+
+func (r RawToken) String() string {
+ return string(r)
+}
diff --git a/app/middleware/token_parser.go b/app/middleware/token_parser.go
index 22a7af9..48034f0 100644
--- a/app/middleware/token_parser.go
+++ b/app/middleware/token_parser.go
@@ -4,18 +4,6 @@ import (
"net/http"
"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"
)
-type TokenParser x.Mapper[*http.Request, oidc.RawToken]
-
-func IDTokenFromSessionCookie(r *http.Request) oidc.RawToken {
- cookies := r.CookiesNamed(cfg.IDTokenCookie)
-
- if len(cookies) != 1 {
- return ""
- }
-
- return oidc.RawToken(cookies[0].Value)
-}
+type TokenParser x.Mapper[*http.Request, RawToken]
diff --git a/app/middleware/user.go b/app/middleware/user.go
index c0181f9..9a88f8e 100644
--- a/app/middleware/user.go
+++ b/app/middleware/user.go
@@ -3,11 +3,11 @@ package middleware
import (
"net/http"
+ "github.com/coreos/go-oidc/v3/oidc"
"github.com/xlgmokha/x/pkg/mapper"
"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/app/domain"
- "gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/pkg/oidc"
"gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/pkg/pls"
)
diff --git a/app/middleware/user_test.go b/app/middleware/user_test.go
index e6ba09d..aed3582 100644
--- a/app/middleware/user_test.go
+++ b/app/middleware/user_test.go
@@ -4,13 +4,13 @@ import (
"net/http"
"testing"
+ "github.com/coreos/go-oidc/v3/oidc"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/xlgmokha/x/pkg/test"
"gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/app/cfg"
"gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/app/db"
"gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/app/domain"
- "gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/pkg/oidc"
"gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/pkg/pls"
)
diff --git a/app/views/dashboard/nav.html.tmpl b/app/views/dashboard/nav.html.tmpl
index c43ea48..c9c4a84 100644
--- a/app/views/dashboard/nav.html.tmpl
+++ b/app/views/dashboard/nav.html.tmpl
@@ -13,7 +13,7 @@
<li><a href="/dashboard">Dashboard</a></li>
<li><a href="{{ .CurrentUser.ProfileURL }}">Profile</a></li>
<li>
- <form action="/session/destroy" method="post">
+ <form action="/signout" method="post">
<input type="submit" value="Logout">
</form>
</li>
@@ -21,7 +21,7 @@
</details>
</li>
{{ else }}
- <li><a href="/session/new" class="secondary">Login</a></li>
+ <li><a href="/dashboard" class="secondary">Login</a></li>
{{ end }}
</ul>
</nav>
diff --git a/app/views/sessions/redirect.html.tmpl b/app/views/sessions/redirect.html.tmpl
deleted file mode 100644
index e70e1d5..0000000
--- a/app/views/sessions/redirect.html.tmpl
+++ /dev/null
@@ -1,9 +0,0 @@
-<!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>