diff options
Diffstat (limited to 'pkg/web')
| -rw-r--r-- | pkg/web/middleware/enforce_authn.go | 1 | ||||
| -rw-r--r-- | pkg/web/middleware/enforce_authn_test.go | 11 | ||||
| -rw-r--r-- | pkg/web/middleware/unpack_token.go | 38 | ||||
| -rw-r--r-- | pkg/web/middleware/unpack_token_test.go | 76 |
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) + }) + }) +} |
