summaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'pkg')
-rw-r--r--pkg/web/middleware/enforce_authn.go1
-rw-r--r--pkg/web/middleware/enforce_authn_test.go11
-rw-r--r--pkg/web/middleware/unpack_token.go38
-rw-r--r--pkg/web/middleware/unpack_token_test.go76
4 files changed, 126 insertions, 0 deletions
diff --git a/pkg/web/middleware/enforce_authn.go b/pkg/web/middleware/enforce_authn.go
new file mode 100644
index 0000000..c870d7c
--- /dev/null
+++ b/pkg/web/middleware/enforce_authn.go
@@ -0,0 +1 @@
+package middleware
diff --git a/pkg/web/middleware/enforce_authn_test.go b/pkg/web/middleware/enforce_authn_test.go
new file mode 100644
index 0000000..285db5b
--- /dev/null
+++ b/pkg/web/middleware/enforce_authn_test.go
@@ -0,0 +1,11 @@
+package middleware
+
+import "testing"
+
+func TestEnforceAuthn(t *testing.T) {
+ t.Run("when an active session cookie is provided", func(t *testing.T) {
+ t.Run("attaches a user to the request context", func(t *testing.T) {
+
+ })
+ })
+}
diff --git a/pkg/web/middleware/unpack_token.go b/pkg/web/middleware/unpack_token.go
new file mode 100644
index 0000000..8993df1
--- /dev/null
+++ b/pkg/web/middleware/unpack_token.go
@@ -0,0 +1,38 @@
+package middleware
+
+import (
+ "net/http"
+
+ "github.com/xlgmokha/x/pkg/context"
+ "gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/pkg/oidc"
+)
+
+var IDTokenContextKey context.Key[*oidc.IDToken] = context.Key[*oidc.IDToken]("id_token")
+
+func UnpackToken() func(http.Handler) http.Handler {
+ return func(next http.Handler) http.Handler {
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ cookies := r.CookiesNamed("session")
+ if len(cookies) == 1 {
+ tokens, err := oidc.TokensFromBase64String(cookies[0].Value)
+ if err != nil {
+ next.ServeHTTP(w, r)
+ return
+ }
+
+ idToken, err := tokens.ParseIDToken()
+ if err != nil {
+ next.ServeHTTP(w, r)
+ return
+ }
+
+ next.ServeHTTP(
+ w,
+ r.WithContext(IDTokenContextKey.With(r.Context(), idToken)),
+ )
+ } else {
+ next.ServeHTTP(w, r)
+ }
+ })
+ }
+}
diff --git a/pkg/web/middleware/unpack_token_test.go b/pkg/web/middleware/unpack_token_test.go
new file mode 100644
index 0000000..a6f591e
--- /dev/null
+++ b/pkg/web/middleware/unpack_token_test.go
@@ -0,0 +1,76 @@
+package middleware
+
+import (
+ "net/http"
+ "testing"
+ "time"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+ "github.com/xlgmokha/x/pkg/x"
+ "gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/pkg/oidc"
+ "gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/pkg/test"
+ "gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/pkg/web/cookie"
+)
+
+func TestUnpackToken(t *testing.T) {
+ middleware := UnpackToken()
+
+ t.Run("when an active session cookie is provided", func(t *testing.T) {
+ t.Run("attaches the token to the request context", func(t *testing.T) {
+ tokens := &oidc.Tokens{IDToken: "eyJ0eXAiOiJKV1QiLCJraWQiOiJ0ZDBTbWRKUTRxUGg1cU5Lek0yNjBDWHgyVWgtd2hHLU1Eam9PS1dmdDhFIiwiYWxnIjoiUlMyNTYifQ.eyJpc3MiOiJodHRwOi8vZ2RrLnRlc3Q6MzAwMCIsInN1YiI6IjEiLCJhdWQiOiJlMzFlMWRhMGI4ZjZiNmUzNWNhNzBjNzkwYjEzYzA0MDZlNDRhY2E2YjJiZjY3ZjU1ZGU3MzU1YTk3OWEyMjRmIiwiZXhwIjoxNzQ0NzM3NDI3LCJpYXQiOjE3NDQ3MzczMDcsImF1dGhfdGltZSI6MTc0NDczNDY0OSwic3ViX2xlZ2FjeSI6IjI0NzRjZjBiMjIxMTY4OGE1NzI5N2FjZTBlMjYwYTE1OTQ0NzU0ZDE2YjFiZDQyYzlkNjc3OWM5MDAzNjc4MDciLCJuYW1lIjoiQWRtaW5pc3RyYXRvciIsIm5pY2tuYW1lIjoicm9vdCIsInByZWZlcnJlZF91c2VybmFtZSI6InJvb3QiLCJlbWFpbCI6ImFkbWluQGV4YW1wbGUuY29tIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsInByb2ZpbGUiOiJodHRwOi8vZ2RrLnRlc3Q6MzAwMC9yb290IiwicGljdHVyZSI6Imh0dHBzOi8vd3d3LmdyYXZhdGFyLmNvbS9hdmF0YXIvMjU4ZDhkYzkxNmRiOGNlYTJjYWZiNmMzY2QwY2IwMjQ2ZWZlMDYxNDIxZGJkODNlYzNhMzUwNDI4Y2FiZGE0Zj9zPTgwJmQ9aWRlbnRpY29uIiwiZ3JvdXBzX2RpcmVjdCI6WyJ0b29sYm94IiwiZ2l0bGFiLW9yZyIsImdudXdnZXQiLCJDb21taXQ0NTEiLCJqYXNoa2VuYXMiLCJmbGlnaHRqcyIsInR3aXR0ZXIiLCJnaXRsYWItZXhhbXBsZXMiLCJnaXRsYWItZXhhbXBsZXMvc2VjdXJpdHkiLCI0MTI3MDgiLCJnaXRsYWItZXhhbXBsZXMvZGVtby1ncm91cCIsImN1c3RvbS1yb2xlcy1yb290LWdyb3VwIiwiNDM0MDQ0LWdyb3VwLTEiLCI0MzQwNDQtZ3JvdXAtMiIsImdpdGxhYi1vcmcxIiwiZ2l0bGFiLW9yZy9zZWN1cmUiLCJnaXRsYWItb3JnL3NlY3VyZS9tYW5hZ2VycyIsImdpdGxhYi1vcmcvc2VjdXJpdHktcHJvZHVjdHMiLCJnaXRsYWItb3JnL3NlY3VyaXR5LXByb2R1Y3RzL2FuYWx5emVycyIsImN1c3RvbS1yb2xlcy1yb290LWdyb3VwL2FhIiwiY3VzdG9tLXJvbGVzLXJvb3QtZ3JvdXAvYWEvYWFhIiwibWFzc19pbnNlcnRfZ3JvdXBfXzBfMTAwIl19.SZu_l7tQ2Kkeogq0z8cRaDWPfv52JTo-RkiExbnud_lrfrXXneS77BIzaGKX_bzq4SM_oO_Q63AzK66B1r6Gp7ACo4DjOUEIWETg7ZBKcDzEZnresB7kmI_MJ5rfIJTmnH75GOfc_pl5l8T896TbaShN6zSpaXXIVEfhyUrflSWb4hhA7Hbwy2b6laXiaDv0qpcn1udPVYMTsll8I5ni_2yzuEPSVRgrcQoQ46OwVDZIi9tlfdT2qNVjH6FxJ3mkBcxtIVjf3_JYAawFEscg2uvQYwFWj9T6LleMknAh3QFJJMrS6mPqlXJGPUE5pTQgsBInfEikfm9PXxezA-IY6g"}
+ encoded := x.Must(tokens.ToBase64String())
+
+ server := middleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ token := IDTokenContextKey.From(r.Context())
+ require.NotNil(t, token)
+ assert.Equal(t, "root", token.Nickname)
+
+ w.WriteHeader(http.StatusTeapot)
+ }))
+
+ r, w := test.RequestResponse(
+ "GET",
+ "/example",
+ test.WithCookie(cookie.New("session", encoded, time.Now().Add(1*time.Hour))),
+ )
+ server.ServeHTTP(w, r)
+
+ assert.Equal(t, http.StatusTeapot, w.Code)
+ })
+ })
+
+ t.Run("when an invalid session 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, IDTokenContextKey.From(r.Context()))
+
+ w.WriteHeader(http.StatusTeapot)
+ }))
+
+ r, w := test.RequestResponse(
+ "GET",
+ "/example",
+ test.WithCookie(cookie.New("session", "invalid", time.Now().Add(1*time.Hour))),
+ )
+ server.ServeHTTP(w, r)
+
+ assert.Equal(t, http.StatusTeapot, w.Code)
+ })
+ })
+
+ t.Run("when no cookies are 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, IDTokenContextKey.From(r.Context()))
+
+ w.WriteHeader(http.StatusTeapot)
+ }))
+
+ r, w := test.RequestResponse("GET", "/example")
+ server.ServeHTTP(w, r)
+
+ assert.Equal(t, http.StatusTeapot, w.Code)
+ })
+ })
+}