From fe50089464bf340cabd9a6cfe756c79e50c30818 Mon Sep 17 00:00:00 2001 From: James Elliott Date: Fri, 22 Dec 2023 09:28:47 +1100 Subject: [PATCH] refactor: several more consts usages (#18) --- access_error.go | 16 +- access_request_handler.go | 2 +- access_request_handler_test.go | 65 ++-- access_write.go | 8 +- access_write_test.go | 7 +- audience_strategy_test.go | 84 ++--- authorize_error.go | 18 +- authorize_error_test.go | 167 ++++----- authorize_helper.go | 21 +- authorize_helper_test.go | 34 +- authorize_request.go | 8 +- authorize_request_handler.go | 2 +- ...orize_request_handler_oidc_request_test.go | 14 +- authorize_request_handler_test.go | 281 +++++++------- authorize_response_test.go | 4 +- authorize_write.go | 10 +- authorize_write_test.go | 63 ++-- client_authentication.go | 4 +- client_authentication_test.go | 245 ++++++------ config_default.go | 7 +- go.sum | 2 - .../oauth2/flow_authorize_code_auth_test.go | 2 +- .../oauth2/flow_authorize_code_token_test.go | 16 +- .../oauth2/flow_client_credentials_test.go | 2 +- handler/oauth2/flow_refresh_test.go | 62 ++-- handler/oauth2/introspector_test.go | 5 +- handler/oauth2/strategy_jwt_test.go | 4 +- handler/openid/flow_explicit_auth_test.go | 2 +- handler/openid/flow_explicit_token.go | 2 +- handler/openid/flow_explicit_token_test.go | 8 +- handler/openid/flow_hybrid_test.go | 26 +- handler/openid/flow_implicit_test.go | 105 +++--- handler/openid/flow_refresh_token.go | 2 +- handler/openid/flow_refresh_token_test.go | 2 +- handler/openid/strategy_jwt.go | 2 +- handler/openid/strategy_jwt_test.go | 2 +- handler/openid/validator.go | 2 +- handler/pkce/handler.go | 2 +- handler/rfc7523/handler_test.go | 76 ++-- handler/verifiable/handler_test.go | 4 +- ...rize_code_grant_public_client_pkce_test.go | 11 +- integration/authorize_code_grant_test.go | 7 +- integration/authorize_form_post_test.go | 19 +- integration/authorize_response_mode_test.go | 34 +- integration/client_credentials_grant_test.go | 19 +- integration/clients/introspect.go | 2 +- integration/clients/jwt_bearer.go | 2 +- integration/helper_endpoints_test.go | 9 +- integration/helper_setup_test.go | 19 +- .../introspect_jwt_bearer_token_test.go | 13 +- integration/introspect_token_test.go | 9 +- integration/oidc_explicit_test.go | 17 +- ...implicit_hybrid_public_client_pkce_test.go | 17 +- integration/oidc_implicit_hybrid_test.go | 2 +- .../pushed_authorize_code_grant_test.go | 31 +- integration/refresh_token_grant_test.go | 23 +- ...e_owner_password_credentials_grant_test.go | 3 +- integration/revoke_token_test.go | 3 +- internal/consts/http.go | 25 ++ internal/consts/spec.go | 9 + introspect.go | 2 +- introspect_test.go | 5 +- introspection_request_handler.go | 2 +- introspection_request_handler_test.go | 13 +- introspection_response_writer.go | 15 +- introspection_response_writer_test.go | 3 +- oauth2.go | 4 +- pushed_authorize_request_handler_test.go | 351 +++++++++--------- pushed_authorize_response_writer.go | 15 +- response_handler.go | 8 +- revoke_handler.go | 7 +- revoke_handler_test.go | 43 +-- scope_strategy_test.go | 12 +- storage/memory.go | 9 +- token/jwt/claims_id_token.go | 3 +- token/jwt/claims_id_token_test.go | 2 +- token/jwt/claims_jwt.go | 3 +- token/jwt/claims_jwt_test.go | 23 +- token/jwt/map_claims.go | 2 +- token/jwt/token.go | 2 +- token/jwt/token_test.go | 5 +- 81 files changed, 1113 insertions(+), 1078 deletions(-) create mode 100644 internal/consts/http.go diff --git a/access_error.go b/access_error.go index 00a10fe6..a225ddd0 100644 --- a/access_error.go +++ b/access_error.go @@ -8,6 +8,8 @@ import ( "encoding/json" "fmt" "net/http" + + "authelia.com/provider/oauth2/internal/consts" ) func (f *Fosite) WriteAccessError(ctx context.Context, rw http.ResponseWriter, req AccessRequester, err error) { @@ -15,17 +17,17 @@ func (f *Fosite) WriteAccessError(ctx context.Context, rw http.ResponseWriter, r } func (f *Fosite) writeJsonError(ctx context.Context, rw http.ResponseWriter, requester AccessRequester, err error) { - rw.Header().Set("Content-Type", "application/json;charset=UTF-8") - rw.Header().Set("Cache-Control", "no-store") - rw.Header().Set("Pragma", "no-cache") + rw.Header().Set(consts.HeaderContentType, consts.ContentTypeApplicationJSON) + rw.Header().Set(consts.HeaderCacheControl, consts.CacheControlNoStore) + rw.Header().Set(consts.HeaderPragma, consts.PragmaNoCache) - rfcerr := ErrorToRFC6749Error(err).WithLegacyFormat(f.Config.GetUseLegacyErrorFormat(ctx)).WithExposeDebug(f.Config.GetSendDebugMessagesToClients(ctx)) + rfc := ErrorToRFC6749Error(err).WithLegacyFormat(f.Config.GetUseLegacyErrorFormat(ctx)).WithExposeDebug(f.Config.GetSendDebugMessagesToClients(ctx)) if requester != nil { - rfcerr = rfcerr.WithLocalizer(f.Config.GetMessageCatalog(ctx), getLangFromRequester(requester)) + rfc = rfc.WithLocalizer(f.Config.GetMessageCatalog(ctx), getLangFromRequester(requester)) } - js, err := json.Marshal(rfcerr) + js, err := json.Marshal(rfc) if err != nil { if f.Config.GetSendDebugMessagesToClients(ctx) { errorMessage := EscapeJSONString(err.Error()) @@ -36,7 +38,7 @@ func (f *Fosite) writeJsonError(ctx context.Context, rw http.ResponseWriter, req return } - rw.WriteHeader(rfcerr.CodeField) + rw.WriteHeader(rfc.CodeField) // ignoring the error because the connection is broken when it happens _, _ = rw.Write(js) } diff --git a/access_request_handler.go b/access_request_handler.go index 331bbba6..945b6530 100644 --- a/access_request_handler.go +++ b/access_request_handler.go @@ -8,10 +8,10 @@ import ( "net/http" "strings" - "authelia.com/provider/oauth2/internal/consts" "github.com/pkg/errors" "authelia.com/provider/oauth2/i18n" + "authelia.com/provider/oauth2/internal/consts" "authelia.com/provider/oauth2/internal/errorsx" ) diff --git a/access_request_handler_test.go b/access_request_handler_test.go index 58535858..24cd659e 100644 --- a/access_request_handler_test.go +++ b/access_request_handler_test.go @@ -18,6 +18,7 @@ import ( . "authelia.com/provider/oauth2" "authelia.com/provider/oauth2/internal" + "authelia.com/provider/oauth2/internal/consts" ) func TestNewAccessRequest(t *testing.T) { @@ -54,7 +55,7 @@ func TestNewAccessRequest(t *testing.T) { header: http.Header{}, method: "POST", form: url.Values{ - "grant_type": {"foo"}, + consts.FormParameterGrantType: {"foo"}, }, mock: func() {}, expectErr: ErrInvalidRequest, @@ -63,19 +64,19 @@ func TestNewAccessRequest(t *testing.T) { header: http.Header{}, method: "POST", form: url.Values{ - "grant_type": {"foo"}, - "client_id": {""}, + consts.FormParameterGrantType: {"foo"}, + consts.FormParameterClientID: {""}, }, expectErr: ErrInvalidRequest, mock: func() {}, }, { header: http.Header{ - "Authorization": {basicAuth("foo", "bar")}, + consts.HeaderAuthorization: {basicAuth("foo", "bar")}, }, method: "POST", form: url.Values{ - "grant_type": {"foo"}, + consts.FormParameterGrantType: {"foo"}, }, expectErr: ErrInvalidClient, mock: func() { @@ -85,22 +86,22 @@ func TestNewAccessRequest(t *testing.T) { }, { header: http.Header{ - "Authorization": {basicAuth("foo", "bar")}, + consts.HeaderAuthorization: {basicAuth("foo", "bar")}, }, method: "GET", form: url.Values{ - "grant_type": {"foo"}, + consts.FormParameterGrantType: {"foo"}, }, expectErr: ErrInvalidRequest, mock: func() {}, }, { header: http.Header{ - "Authorization": {basicAuth("foo", "bar")}, + consts.HeaderAuthorization: {basicAuth("foo", "bar")}, }, method: "POST", form: url.Values{ - "grant_type": {"foo"}, + consts.FormParameterGrantType: {"foo"}, }, expectErr: ErrInvalidClient, mock: func() { @@ -110,11 +111,11 @@ func TestNewAccessRequest(t *testing.T) { }, { header: http.Header{ - "Authorization": {basicAuth("foo", "bar")}, + consts.HeaderAuthorization: {basicAuth("foo", "bar")}, }, method: "POST", form: url.Values{ - "grant_type": {"foo"}, + consts.FormParameterGrantType: {"foo"}, }, expectErr: ErrInvalidClient, mock: func() { @@ -127,11 +128,11 @@ func TestNewAccessRequest(t *testing.T) { }, { header: http.Header{ - "Authorization": {basicAuth("foo", "bar")}, + consts.HeaderAuthorization: {basicAuth("foo", "bar")}, }, method: "POST", form: url.Values{ - "grant_type": {"foo"}, + consts.FormParameterGrantType: {"foo"}, }, expectErr: ErrServerError, mock: func() { @@ -145,11 +146,11 @@ func TestNewAccessRequest(t *testing.T) { }, { header: http.Header{ - "Authorization": {basicAuth("foo", "bar")}, + consts.HeaderAuthorization: {basicAuth("foo", "bar")}, }, method: "POST", form: url.Values{ - "grant_type": {"foo"}, + consts.FormParameterGrantType: {"foo"}, }, mock: func() { store.EXPECT().GetClient(gomock.Any(), gomock.Eq("foo")).Return(client, nil) @@ -168,11 +169,11 @@ func TestNewAccessRequest(t *testing.T) { }, { header: http.Header{ - "Authorization": {basicAuth("foo", "bar")}, + consts.HeaderAuthorization: {basicAuth("foo", "bar")}, }, method: "POST", form: url.Values{ - "grant_type": {"foo"}, + consts.FormParameterGrantType: {"foo"}, }, mock: func() { store.EXPECT().GetClient(gomock.Any(), gomock.Eq("foo")).Return(client, nil) @@ -195,10 +196,11 @@ func TestNewAccessRequest(t *testing.T) { Form: c.form, Method: c.method, } + c.mock() - ctx := NewContext() config.TokenEndpointHandlers = c.handlers - ar, err := provider.NewAccessRequest(ctx, r, new(DefaultSession)) + + ar, err := provider.NewAccessRequest(context.TODO(), r, new(DefaultSession)) if c.expectErr != nil { assert.EqualError(t, err, c.expectErr.Error()) @@ -245,7 +247,7 @@ func TestNewAccessRequestWithoutClientAuth(t *testing.T) { // No registered handlers -> error { form: url.Values{ - "grant_type": {"foo"}, + consts.FormParameterGrantType: {"foo"}, }, mock: func() { store.EXPECT().GetClient(gomock.Any(), gomock.Any()).Times(0) @@ -257,10 +259,10 @@ func TestNewAccessRequestWithoutClientAuth(t *testing.T) { // Handler can skip client auth and ignores missing client. { header: http.Header{ - "Authorization": {basicAuth("foo", "bar")}, + consts.HeaderAuthorization: {basicAuth("foo", "bar")}, }, form: url.Values{ - "grant_type": {"foo"}, + consts.FormParameterGrantType: {"foo"}, }, mock: func() { // despite error from storage, we should success, because client auth is not required @@ -279,7 +281,7 @@ func TestNewAccessRequestWithoutClientAuth(t *testing.T) { // Should pass if no auth is set in the header and can skip! { form: url.Values{ - "grant_type": {"foo"}, + consts.FormParameterGrantType: {"foo"}, }, mock: func() { handler.EXPECT().HandleTokenEndpointRequest(gomock.Any(), gomock.Any()).Return(nil) @@ -296,10 +298,10 @@ func TestNewAccessRequestWithoutClientAuth(t *testing.T) { // Should also pass if client auth is set! { header: http.Header{ - "Authorization": {basicAuth("foo", "bar")}, + consts.HeaderAuthorization: {basicAuth("foo", "bar")}, }, form: url.Values{ - "grant_type": {"foo"}, + consts.FormParameterGrantType: {"foo"}, }, mock: func() { store.EXPECT().GetClient(gomock.Any(), "foo").Return(anotherClient, nil).Times(1) @@ -371,10 +373,10 @@ func TestNewAccessRequestWithMixedClientAuth(t *testing.T) { }{ { header: http.Header{ - "Authorization": {basicAuth("foo", "bar")}, + consts.HeaderAuthorization: {basicAuth("foo", "bar")}, }, form: url.Values{ - "grant_type": {"foo"}, + consts.FormParameterGrantType: {"foo"}, }, mock: func() { store.EXPECT().GetClient(gomock.Any(), gomock.Eq("foo")).Return(client, nil) @@ -389,10 +391,10 @@ func TestNewAccessRequestWithMixedClientAuth(t *testing.T) { }, { header: http.Header{ - "Authorization": {basicAuth("foo", "bar")}, + consts.HeaderAuthorization: {basicAuth("foo", "bar")}, }, form: url.Values{ - "grant_type": {"foo"}, + consts.FormParameterGrantType: {"foo"}, }, mock: func() { store.EXPECT().GetClient(gomock.Any(), gomock.Eq("foo")).Return(client, nil) @@ -414,7 +416,7 @@ func TestNewAccessRequestWithMixedClientAuth(t *testing.T) { { header: http.Header{}, form: url.Values{ - "grant_type": {"foo"}, + consts.FormParameterGrantType: {"foo"}, }, mock: func() { store.EXPECT().GetClient(gomock.Any(), gomock.Any()).Times(0) @@ -433,9 +435,8 @@ func TestNewAccessRequestWithMixedClientAuth(t *testing.T) { Method: c.method, } c.mock() - ctx := NewContext() config.TokenEndpointHandlers = c.handlers - ar, err := provider.NewAccessRequest(ctx, r, new(DefaultSession)) + ar, err := provider.NewAccessRequest(context.TODO(), r, new(DefaultSession)) if c.expectErr != nil { assert.EqualError(t, err, c.expectErr.Error()) diff --git a/access_write.go b/access_write.go index f811af66..2d4f8f66 100644 --- a/access_write.go +++ b/access_write.go @@ -7,11 +7,13 @@ import ( "context" "encoding/json" "net/http" + + "authelia.com/provider/oauth2/internal/consts" ) func (f *Fosite) WriteAccessResponse(ctx context.Context, rw http.ResponseWriter, requester AccessRequester, responder AccessResponder) { - rw.Header().Set("Cache-Control", "no-store") - rw.Header().Set("Pragma", "no-cache") + rw.Header().Set(consts.HeaderCacheControl, consts.CacheControlNoStore) + rw.Header().Set(consts.HeaderPragma, consts.PragmaNoCache) js, err := json.Marshal(responder.ToMap()) if err != nil { @@ -19,7 +21,7 @@ func (f *Fosite) WriteAccessResponse(ctx context.Context, rw http.ResponseWriter return } - rw.Header().Set("Content-Type", "application/json;charset=UTF-8") + rw.Header().Set(consts.HeaderContentType, consts.ContentTypeApplicationJSON) rw.WriteHeader(http.StatusOK) _, _ = rw.Write(js) diff --git a/access_write_test.go b/access_write_test.go index 79fa2c08..4487723d 100644 --- a/access_write_test.go +++ b/access_write_test.go @@ -13,6 +13,7 @@ import ( . "authelia.com/provider/oauth2" . "authelia.com/provider/oauth2/internal" + "authelia.com/provider/oauth2/internal/consts" ) func TestWriteAccessResponse(t *testing.T) { @@ -30,7 +31,7 @@ func TestWriteAccessResponse(t *testing.T) { resp.EXPECT().ToMap().Return(map[string]any{}) provider.WriteAccessResponse(context.Background(), rw, ar, resp) - assert.Equal(t, "application/json;charset=UTF-8", header.Get("Content-Type")) - assert.Equal(t, "no-store", header.Get("Cache-Control")) - assert.Equal(t, "no-cache", header.Get("Pragma")) + assert.Equal(t, consts.ContentTypeApplicationJSON, header.Get(consts.HeaderContentType)) + assert.Equal(t, consts.CacheControlNoStore, header.Get(consts.HeaderCacheControl)) + assert.Equal(t, consts.PragmaNoCache, header.Get(consts.HeaderPragma)) } diff --git a/audience_strategy_test.go b/audience_strategy_test.go index 245b7a60..6e494a4b 100644 --- a/audience_strategy_test.go +++ b/audience_strategy_test.go @@ -32,57 +32,57 @@ func TestDefaultAudienceMatchingStrategy(t *testing.T) { err: true, }, { - h: []string{"https://cloud.ory.sh/api/users"}, - n: []string{"https://cloud.ory.sh/api/users"}, + h: []string{"https://cloud.authelia.com/api/users"}, + n: []string{"https://cloud.authelia.com/api/users"}, err: false, }, { - h: []string{"https://cloud.ory.sh/api/users"}, - n: []string{"https://cloud.ory.sh/api/users/"}, + h: []string{"https://cloud.authelia.com/api/users"}, + n: []string{"https://cloud.authelia.com/api/users/"}, err: false, }, { - h: []string{"https://cloud.ory.sh/api/users/"}, - n: []string{"https://cloud.ory.sh/api/users/"}, + h: []string{"https://cloud.authelia.com/api/users/"}, + n: []string{"https://cloud.authelia.com/api/users/"}, err: false, }, { - h: []string{"https://cloud.ory.sh/api/users/"}, - n: []string{"https://cloud.ory.sh/api/users"}, + h: []string{"https://cloud.authelia.com/api/users/"}, + n: []string{"https://cloud.authelia.com/api/users"}, err: false, }, { - h: []string{"https://cloud.ory.sh/api/users"}, - n: []string{"https://cloud.ory.sh/api/users/1234"}, + h: []string{"https://cloud.authelia.com/api/users"}, + n: []string{"https://cloud.authelia.com/api/users/1234"}, err: false, }, { - h: []string{"https://cloud.ory.sh/api/users"}, - n: []string{"https://cloud.ory.sh/api/users", "https://cloud.ory.sh/api/users/", "https://cloud.ory.sh/api/users/1234"}, + h: []string{"https://cloud.authelia.com/api/users"}, + n: []string{"https://cloud.authelia.com/api/users", "https://cloud.authelia.com/api/users/", "https://cloud.authelia.com/api/users/1234"}, err: false, }, { - h: []string{"https://cloud.ory.sh/api/users", "https://cloud.ory.sh/api/tenants"}, - n: []string{"https://cloud.ory.sh/api/users", "https://cloud.ory.sh/api/users/", "https://cloud.ory.sh/api/users/1234", "https://cloud.ory.sh/api/tenants"}, + h: []string{"https://cloud.authelia.com/api/users", "https://cloud.authelia.com/api/tenants"}, + n: []string{"https://cloud.authelia.com/api/users", "https://cloud.authelia.com/api/users/", "https://cloud.authelia.com/api/users/1234", "https://cloud.authelia.com/api/tenants"}, err: false, }, { - h: []string{"https://cloud.ory.sh/api/users"}, - n: []string{"https://cloud.ory.sh/api/users1234"}, + h: []string{"https://cloud.authelia.com/api/users"}, + n: []string{"https://cloud.authelia.com/api/users1234"}, err: true, }, { - h: []string{"https://cloud.ory.sh/api/users"}, - n: []string{"http://cloud.ory.sh/api/users"}, + h: []string{"https://cloud.authelia.com/api/users"}, + n: []string{"http://cloud.authelia.com/api/users"}, err: true, }, { - h: []string{"https://cloud.ory.sh/api/users"}, - n: []string{"https://cloud.ory.sh:8000/api/users"}, + h: []string{"https://cloud.authelia.com/api/users"}, + n: []string{"https://cloud.authelia.com:8000/api/users"}, err: true, }, { - h: []string{"https://cloud.ory.sh/api/users"}, + h: []string{"https://cloud.authelia.com/api/users"}, n: []string{"https://cloud.ory.xyz/api/users"}, err: true, }, @@ -155,57 +155,57 @@ func TestExactAudienceMatchingStrategy(t *testing.T) { err: true, }, { - h: []string{"https://cloud.ory.sh/api/users"}, - n: []string{"https://cloud.ory.sh/api/users"}, + h: []string{"https://cloud.authelia.com/api/users"}, + n: []string{"https://cloud.authelia.com/api/users"}, err: false, }, { - h: []string{"https://cloud.ory.sh/api/users"}, - n: []string{"https://cloud.ory.sh/api/users/"}, + h: []string{"https://cloud.authelia.com/api/users"}, + n: []string{"https://cloud.authelia.com/api/users/"}, err: true, }, { - h: []string{"https://cloud.ory.sh/api/users/"}, - n: []string{"https://cloud.ory.sh/api/users/"}, + h: []string{"https://cloud.authelia.com/api/users/"}, + n: []string{"https://cloud.authelia.com/api/users/"}, err: false, }, { - h: []string{"https://cloud.ory.sh/api/users/"}, - n: []string{"https://cloud.ory.sh/api/users"}, + h: []string{"https://cloud.authelia.com/api/users/"}, + n: []string{"https://cloud.authelia.com/api/users"}, err: true, }, { - h: []string{"https://cloud.ory.sh/api/users"}, - n: []string{"https://cloud.ory.sh/api/users/1234"}, + h: []string{"https://cloud.authelia.com/api/users"}, + n: []string{"https://cloud.authelia.com/api/users/1234"}, err: true, }, { - h: []string{"https://cloud.ory.sh/api/users"}, - n: []string{"https://cloud.ory.sh/api/users", "https://cloud.ory.sh/api/users/", "https://cloud.ory.sh/api/users/1234"}, + h: []string{"https://cloud.authelia.com/api/users"}, + n: []string{"https://cloud.authelia.com/api/users", "https://cloud.authelia.com/api/users/", "https://cloud.authelia.com/api/users/1234"}, err: true, }, { - h: []string{"https://cloud.ory.sh/api/users", "https://cloud.ory.sh/api/tenants"}, - n: []string{"https://cloud.ory.sh/api/users", "https://cloud.ory.sh/api/users/", "https://cloud.ory.sh/api/users/1234", "https://cloud.ory.sh/api/tenants"}, + h: []string{"https://cloud.authelia.com/api/users", "https://cloud.authelia.com/api/tenants"}, + n: []string{"https://cloud.authelia.com/api/users", "https://cloud.authelia.com/api/users/", "https://cloud.authelia.com/api/users/1234", "https://cloud.authelia.com/api/tenants"}, err: true, }, { - h: []string{"https://cloud.ory.sh/api/users"}, - n: []string{"https://cloud.ory.sh/api/users1234"}, + h: []string{"https://cloud.authelia.com/api/users"}, + n: []string{"https://cloud.authelia.com/api/users1234"}, err: true, }, { - h: []string{"https://cloud.ory.sh/api/users"}, - n: []string{"http://cloud.ory.sh/api/users"}, + h: []string{"https://cloud.authelia.com/api/users"}, + n: []string{"http://cloud.authelia.com/api/users"}, err: true, }, { - h: []string{"https://cloud.ory.sh/api/users"}, - n: []string{"https://cloud.ory.sh:8000/api/users"}, + h: []string{"https://cloud.authelia.com/api/users"}, + n: []string{"https://cloud.authelia.com:8000/api/users"}, err: true, }, { - h: []string{"https://cloud.ory.sh/api/users"}, + h: []string{"https://cloud.authelia.com/api/users"}, n: []string{"https://cloud.ory.xyz/api/users"}, err: true, }, diff --git a/authorize_error.go b/authorize_error.go index 9848dfe1..c7e97669 100644 --- a/authorize_error.go +++ b/authorize_error.go @@ -13,19 +13,19 @@ import ( ) func (f *Fosite) WriteAuthorizeError(ctx context.Context, rw http.ResponseWriter, ar AuthorizeRequester, err error) { - rw.Header().Set("Cache-Control", "no-store") - rw.Header().Set("Pragma", "no-cache") + rw.Header().Set(consts.HeaderCacheControl, consts.CacheControlNoStore) + rw.Header().Set(consts.HeaderPragma, consts.PragmaNoCache) if f.ResponseModeHandler(ctx).ResponseModes().Has(ar.GetResponseMode()) { f.ResponseModeHandler(ctx).WriteAuthorizeError(ctx, rw, ar, err) return } - rfcerr := ErrorToRFC6749Error(err).WithLegacyFormat(f.Config.GetUseLegacyErrorFormat(ctx)).WithExposeDebug(f.Config.GetSendDebugMessagesToClients(ctx)).WithLocalizer(f.Config.GetMessageCatalog(ctx), getLangFromRequester(ar)) + rfc := ErrorToRFC6749Error(err).WithLegacyFormat(f.Config.GetUseLegacyErrorFormat(ctx)).WithExposeDebug(f.Config.GetSendDebugMessagesToClients(ctx)).WithLocalizer(f.Config.GetMessageCatalog(ctx), getLangFromRequester(ar)) if !ar.IsRedirectURIValid() { - rw.Header().Set("Content-Type", "application/json;charset=UTF-8") + rw.Header().Set(consts.HeaderContentType, consts.ContentTypeApplicationJSON) - js, err := json.Marshal(rfcerr) + js, err := json.Marshal(rfc) if err != nil { if f.Config.GetSendDebugMessagesToClients(ctx) { errorMessage := EscapeJSONString(err.Error()) @@ -36,7 +36,7 @@ func (f *Fosite) WriteAuthorizeError(ctx context.Context, rw http.ResponseWriter return } - rw.WriteHeader(rfcerr.CodeField) + rw.WriteHeader(rfc.CodeField) _, _ = rw.Write(js) return } @@ -46,12 +46,12 @@ func (f *Fosite) WriteAuthorizeError(ctx context.Context, rw http.ResponseWriter // The endpoint URI MUST NOT include a fragment component. redirectURI.Fragment = "" - errors := rfcerr.ToValues() + errors := rfc.ToValues() errors.Set(consts.FormParameterState, ar.GetState()) var redirectURIString string if ar.GetResponseMode() == ResponseModeFormPost { - rw.Header().Set("Content-Type", "text/html;charset=UTF-8") + rw.Header().Set(consts.HeaderContentType, consts.ContentTypeTextHTML) WriteAuthorizeFormPostResponse(redirectURI.String(), errors, GetPostFormHTMLTemplate(ctx, f), rw) return } else if ar.GetResponseMode() == ResponseModeFragment { @@ -66,6 +66,6 @@ func (f *Fosite) WriteAuthorizeError(ctx context.Context, rw http.ResponseWriter redirectURIString = redirectURI.String() } - rw.Header().Set("Location", redirectURIString) + rw.Header().Set(consts.HeaderLocation, redirectURIString) rw.WriteHeader(http.StatusSeeOther) } diff --git a/authorize_error_test.go b/authorize_error_test.go index a76f7dc7..20c20e0e 100644 --- a/authorize_error_test.go +++ b/authorize_error_test.go @@ -15,6 +15,7 @@ import ( . "authelia.com/provider/oauth2" . "authelia.com/provider/oauth2/internal" + "authelia.com/provider/oauth2/internal/consts" ) // Test for @@ -61,9 +62,9 @@ func TestWriteAuthorizeError(t *testing.T) { rw.EXPECT().Write(gomock.Any()) }, checkHeader: func(t *testing.T, k int) { - assert.Equal(t, "application/json;charset=UTF-8", header.Get("Content-Type")) - assert.Equal(t, "no-store", header.Get("Cache-Control")) - assert.Equal(t, "no-cache", header.Get("Pragma")) + assert.Equal(t, consts.ContentTypeApplicationJSON, header.Get(consts.HeaderContentType)) + assert.Equal(t, consts.CacheControlNoStore, header.Get(consts.HeaderCacheControl)) + assert.Equal(t, consts.PragmaNoCache, header.Get(consts.HeaderPragma)) }, }, // 1 @@ -74,17 +75,17 @@ func TestWriteAuthorizeError(t *testing.T) { req.EXPECT().IsRedirectURIValid().Return(true) req.EXPECT().GetRedirectURI().Return(copyUrl(purls[0])) req.EXPECT().GetState().Return("foostate") - req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{"code"})) + req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{consts.ResponseTypeAuthorizationCodeFlow})) req.EXPECT().GetResponseMode().Return(ResponseModeQuery).AnyTimes() rw.EXPECT().Header().Times(3).Return(header) rw.EXPECT().WriteHeader(http.StatusSeeOther) }, checkHeader: func(t *testing.T, k int) { a, _ := url.Parse("https://foobar.com/?error=invalid_request&error_debug=with-debug&error_description=The+request+is+missing+a+required+parameter%2C+includes+an+invalid+parameter+value%2C+includes+a+parameter+more+than+once%2C+or+is+otherwise+malformed.&error_hint=Make+sure+that+the+various+parameters+are+correct%2C+be+aware+of+case+sensitivity+and+trim+your+parameters.+Make+sure+that+the+client+you+are+using+has+exactly+whitelisted+the+redirect_uri+you+specified.&state=foostate") - b, _ := url.Parse(header.Get("Location")) + b, _ := url.Parse(header.Get(consts.HeaderLocation)) assert.Equal(t, a, b) - assert.Equal(t, "no-store", header.Get("Cache-Control")) - assert.Equal(t, "no-cache", header.Get("Pragma")) + assert.Equal(t, consts.CacheControlNoStore, header.Get(consts.HeaderCacheControl)) + assert.Equal(t, consts.PragmaNoCache, header.Get(consts.HeaderPragma)) }, }, // 2 @@ -96,17 +97,17 @@ func TestWriteAuthorizeError(t *testing.T) { req.EXPECT().IsRedirectURIValid().Return(true) req.EXPECT().GetRedirectURI().Return(copyUrl(purls[0])) req.EXPECT().GetState().Return("foostate") - req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{"code"})) + req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{consts.ResponseTypeAuthorizationCodeFlow})) req.EXPECT().GetResponseMode().Return(ResponseModeQuery).AnyTimes() rw.EXPECT().Header().Times(3).Return(header) rw.EXPECT().WriteHeader(http.StatusSeeOther) }, checkHeader: func(t *testing.T, k int) { a, _ := url.Parse("https://foobar.com/?error=invalid_request&error_description=The+request+is+missing+a+required+parameter%2C+includes+an+invalid+parameter+value%2C+includes+a+parameter+more+than+once%2C+or+is+otherwise+malformed.+Make+sure+that+the+various+parameters+are+correct%2C+be+aware+of+case+sensitivity+and+trim+your+parameters.+Make+sure+that+the+client+you+are+using+has+exactly+whitelisted+the+redirect_uri+you+specified.+with-debug&state=foostate") - b, _ := url.Parse(header.Get("Location")) + b, _ := url.Parse(header.Get(consts.HeaderLocation)) assert.Equal(t, a, b) - assert.Equal(t, "no-store", header.Get("Cache-Control")) - assert.Equal(t, "no-cache", header.Get("Pragma")) + assert.Equal(t, consts.CacheControlNoStore, header.Get(consts.HeaderCacheControl)) + assert.Equal(t, consts.PragmaNoCache, header.Get(consts.HeaderPragma)) }, }, // 3 @@ -117,17 +118,17 @@ func TestWriteAuthorizeError(t *testing.T) { req.EXPECT().IsRedirectURIValid().Return(true) req.EXPECT().GetRedirectURI().Return(copyUrl(purls[0])) req.EXPECT().GetState().Return("foostate") - req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{"code"})) + req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{consts.ResponseTypeAuthorizationCodeFlow})) req.EXPECT().GetResponseMode().Return(ResponseModeQuery).AnyTimes() rw.EXPECT().Header().Times(3).Return(header) rw.EXPECT().WriteHeader(http.StatusSeeOther) }, checkHeader: func(t *testing.T, k int) { a, _ := url.Parse("https://foobar.com/?error=invalid_request&error_description=The+request+is+missing+a+required+parameter%2C+includes+an+invalid+parameter+value%2C+includes+a+parameter+more+than+once%2C+or+is+otherwise+malformed.+Make+sure+that+the+various+parameters+are+correct%2C+be+aware+of+case+sensitivity+and+trim+your+parameters.+Make+sure+that+the+client+you+are+using+has+exactly+whitelisted+the+redirect_uri+you+specified.&state=foostate") - b, _ := url.Parse(header.Get("Location")) + b, _ := url.Parse(header.Get(consts.HeaderLocation)) assert.Equal(t, a, b) - assert.Equal(t, "no-store", header.Get("Cache-Control")) - assert.Equal(t, "no-cache", header.Get("Pragma")) + assert.Equal(t, consts.CacheControlNoStore, header.Get(consts.HeaderCacheControl)) + assert.Equal(t, consts.PragmaNoCache, header.Get(consts.HeaderPragma)) }, }, // 4 @@ -137,17 +138,17 @@ func TestWriteAuthorizeError(t *testing.T) { req.EXPECT().IsRedirectURIValid().Return(true) req.EXPECT().GetRedirectURI().Return(copyUrl(purls[0])) req.EXPECT().GetState().Return("foostate") - req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{"code"})) + req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{consts.ResponseTypeAuthorizationCodeFlow})) req.EXPECT().GetResponseMode().Return(ResponseModeDefault).AnyTimes() rw.EXPECT().Header().Times(3).Return(header) rw.EXPECT().WriteHeader(http.StatusSeeOther) }, checkHeader: func(t *testing.T, k int) { a, _ := url.Parse("https://foobar.com/?error=invalid_request&error_description=The+request+is+missing+a+required+parameter%2C+includes+an+invalid+parameter+value%2C+includes+a+parameter+more+than+once%2C+or+is+otherwise+malformed.&error_hint=Make+sure+that+the+various+parameters+are+correct%2C+be+aware+of+case+sensitivity+and+trim+your+parameters.+Make+sure+that+the+client+you+are+using+has+exactly+whitelisted+the+redirect_uri+you+specified.&state=foostate") - b, _ := url.Parse(header.Get("Location")) + b, _ := url.Parse(header.Get(consts.HeaderLocation)) assert.Equal(t, a, b) - assert.Equal(t, "no-store", header.Get("Cache-Control")) - assert.Equal(t, "no-cache", header.Get("Pragma")) + assert.Equal(t, consts.CacheControlNoStore, header.Get(consts.HeaderCacheControl)) + assert.Equal(t, consts.PragmaNoCache, header.Get(consts.HeaderPragma)) }, }, // 5 @@ -157,17 +158,17 @@ func TestWriteAuthorizeError(t *testing.T) { req.EXPECT().IsRedirectURIValid().Return(true) req.EXPECT().GetRedirectURI().Return(copyUrl(purls[1])) req.EXPECT().GetState().Return("foostate") - req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{"code"})) + req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{consts.ResponseTypeAuthorizationCodeFlow})) req.EXPECT().GetResponseMode().Return(ResponseModeQuery).AnyTimes() rw.EXPECT().Header().Times(3).Return(header) rw.EXPECT().WriteHeader(http.StatusSeeOther) }, checkHeader: func(t *testing.T, k int) { a, _ := url.Parse("https://foobar.com/?error=invalid_request&error_description=The+request+is+missing+a+required+parameter%2C+includes+an+invalid+parameter+value%2C+includes+a+parameter+more+than+once%2C+or+is+otherwise+malformed.&error_hint=Make+sure+that+the+various+parameters+are+correct%2C+be+aware+of+case+sensitivity+and+trim+your+parameters.+Make+sure+that+the+client+you+are+using+has+exactly+whitelisted+the+redirect_uri+you+specified.&foo=bar&state=foostate") - b, _ := url.Parse(header.Get("Location")) + b, _ := url.Parse(header.Get(consts.HeaderLocation)) assert.Equal(t, a, b) - assert.Equal(t, "no-store", header.Get("Cache-Control")) - assert.Equal(t, "no-cache", header.Get("Pragma")) + assert.Equal(t, consts.CacheControlNoStore, header.Get(consts.HeaderCacheControl)) + assert.Equal(t, consts.PragmaNoCache, header.Get(consts.HeaderPragma)) }, }, // 6 @@ -184,10 +185,10 @@ func TestWriteAuthorizeError(t *testing.T) { }, checkHeader: func(t *testing.T, k int) { a, _ := url.Parse("https://foobar.com/?foo=bar#error=unsupported_grant_type&error_description=The+authorization+grant+type+is+not+supported+by+the+authorization+server.&state=foostate") - b, _ := url.Parse(header.Get("Location")) + b, _ := url.Parse(header.Get(consts.HeaderLocation)) assert.Equal(t, a, b) - assert.Equal(t, "no-store", header.Get("Cache-Control")) - assert.Equal(t, "no-cache", header.Get("Pragma")) + assert.Equal(t, consts.CacheControlNoStore, header.Get(consts.HeaderCacheControl)) + assert.Equal(t, consts.PragmaNoCache, header.Get(consts.HeaderPragma)) }, }, // 7 @@ -204,10 +205,10 @@ func TestWriteAuthorizeError(t *testing.T) { }, checkHeader: func(t *testing.T, k int) { a, _ := url.Parse("https://foobar.com/#error=invalid_request&error_description=The+request+is+missing+a+required+parameter%2C+includes+an+invalid+parameter+value%2C+includes+a+parameter+more+than+once%2C+or+is+otherwise+malformed.&error_hint=Make+sure+that+the+various+parameters+are+correct%2C+be+aware+of+case+sensitivity+and+trim+your+parameters.+Make+sure+that+the+client+you+are+using+has+exactly+whitelisted+the+redirect_uri+you+specified.&state=foostate") - b, _ := url.Parse(header.Get("Location")) - assert.Equal(t, a, b, "\n\t%s\n\t%s", header.Get("Location"), a.String()) - assert.Equal(t, "no-store", header.Get("Cache-Control")) - assert.Equal(t, "no-cache", header.Get("Pragma")) + b, _ := url.Parse(header.Get(consts.HeaderLocation)) + assert.Equal(t, a, b, "\n\t%s\n\t%s", header.Get(consts.HeaderLocation), a.String()) + assert.Equal(t, consts.CacheControlNoStore, header.Get(consts.HeaderCacheControl)) + assert.Equal(t, consts.PragmaNoCache, header.Get(consts.HeaderPragma)) }, }, // 8 @@ -224,10 +225,10 @@ func TestWriteAuthorizeError(t *testing.T) { }, checkHeader: func(t *testing.T, k int) { a, _ := url.Parse("https://foobar.com/?foo=bar#error=invalid_request&error_description=The+request+is+missing+a+required+parameter%2C+includes+an+invalid+parameter+value%2C+includes+a+parameter+more+than+once%2C+or+is+otherwise+malformed.&error_hint=Make+sure+that+the+various+parameters+are+correct%2C+be+aware+of+case+sensitivity+and+trim+your+parameters.+Make+sure+that+the+client+you+are+using+has+exactly+whitelisted+the+redirect_uri+you+specified.&state=foostate") - b, _ := url.Parse(header.Get("Location")) - assert.Equal(t, a, b, "\n\t%s\n\t%s", header.Get("Location"), a.String()) - assert.Equal(t, "no-store", header.Get("Cache-Control")) - assert.Equal(t, "no-cache", header.Get("Pragma")) + b, _ := url.Parse(header.Get(consts.HeaderLocation)) + assert.Equal(t, a, b, "\n\t%s\n\t%s", header.Get(consts.HeaderLocation), a.String()) + assert.Equal(t, consts.CacheControlNoStore, header.Get(consts.HeaderCacheControl)) + assert.Equal(t, consts.PragmaNoCache, header.Get(consts.HeaderPragma)) }, }, // 9 @@ -237,17 +238,17 @@ func TestWriteAuthorizeError(t *testing.T) { req.EXPECT().IsRedirectURIValid().Return(true) req.EXPECT().GetRedirectURI().Return(copyUrl(purls[0])) req.EXPECT().GetState().Return("foostate") - req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{"code", "token"})) + req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{consts.ResponseTypeAuthorizationCodeFlow, consts.ResponseTypeImplicitFlowToken})) req.EXPECT().GetResponseMode().Return(ResponseModeFragment).AnyTimes() rw.EXPECT().Header().Times(3).Return(header) rw.EXPECT().WriteHeader(http.StatusSeeOther) }, checkHeader: func(t *testing.T, k int) { a, _ := url.Parse("https://foobar.com/#error=invalid_request&error_description=The+request+is+missing+a+required+parameter%2C+includes+an+invalid+parameter+value%2C+includes+a+parameter+more+than+once%2C+or+is+otherwise+malformed.&error_hint=Make+sure+that+the+various+parameters+are+correct%2C+be+aware+of+case+sensitivity+and+trim+your+parameters.+Make+sure+that+the+client+you+are+using+has+exactly+whitelisted+the+redirect_uri+you+specified.&state=foostate") - b, _ := url.Parse(header.Get("Location")) - assert.Equal(t, a, b, "\n\t%s\n\t%s", header.Get("Location"), a.String()) - assert.Equal(t, "no-store", header.Get("Cache-Control")) - assert.Equal(t, "no-cache", header.Get("Pragma")) + b, _ := url.Parse(header.Get(consts.HeaderLocation)) + assert.Equal(t, a, b, "\n\t%s\n\t%s", header.Get(consts.HeaderLocation), a.String()) + assert.Equal(t, consts.CacheControlNoStore, header.Get(consts.HeaderCacheControl)) + assert.Equal(t, consts.PragmaNoCache, header.Get(consts.HeaderPragma)) }, }, // 10 @@ -258,17 +259,17 @@ func TestWriteAuthorizeError(t *testing.T) { req.EXPECT().IsRedirectURIValid().Return(true) req.EXPECT().GetRedirectURI().Return(copyUrl(purls[0])) req.EXPECT().GetState().Return("foostate") - req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{"code", "token"})) + req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{consts.ResponseTypeAuthorizationCodeFlow, consts.ResponseTypeImplicitFlowToken})) req.EXPECT().GetResponseMode().Return(ResponseModeFragment).AnyTimes() rw.EXPECT().Header().Times(3).Return(header) rw.EXPECT().WriteHeader(http.StatusSeeOther) }, checkHeader: func(t *testing.T, k int) { a, _ := url.Parse("https://foobar.com/#error=invalid_request&error_debug=with-debug&error_description=The+request+is+missing+a+required+parameter%2C+includes+an+invalid+parameter+value%2C+includes+a+parameter+more+than+once%2C+or+is+otherwise+malformed.&error_hint=Make+sure+that+the+various+parameters+are+correct%2C+be+aware+of+case+sensitivity+and+trim+your+parameters.+Make+sure+that+the+client+you+are+using+has+exactly+whitelisted+the+redirect_uri+you+specified.&state=foostate") - b, _ := url.Parse(header.Get("Location")) - assert.Equal(t, a, b, "\n\t%s\n\t%s", header.Get("Location"), a.String()) - assert.Equal(t, "no-store", header.Get("Cache-Control")) - assert.Equal(t, "no-cache", header.Get("Pragma")) + b, _ := url.Parse(header.Get(consts.HeaderLocation)) + assert.Equal(t, a, b, "\n\t%s\n\t%s", header.Get(consts.HeaderLocation), a.String()) + assert.Equal(t, consts.CacheControlNoStore, header.Get(consts.HeaderCacheControl)) + assert.Equal(t, consts.PragmaNoCache, header.Get(consts.HeaderPragma)) }, }, // 11 @@ -280,19 +281,19 @@ func TestWriteAuthorizeError(t *testing.T) { req.EXPECT().IsRedirectURIValid().Return(true) req.EXPECT().GetRedirectURI().Return(copyUrl(purls[0])) req.EXPECT().GetState().Return("foostate") - req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{"code", "token"})) + req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{consts.ResponseTypeAuthorizationCodeFlow, consts.ResponseTypeImplicitFlowToken})) req.EXPECT().GetResponseMode().Return(ResponseModeFragment).AnyTimes() rw.EXPECT().Header().Times(3).Return(header) rw.EXPECT().WriteHeader(http.StatusSeeOther) }, checkHeader: func(t *testing.T, k int) { a, _ := url.Parse("https://foobar.com/#error=invalid_request&error_description=The+request+is+missing+a+required+parameter%2C+includes+an+invalid+parameter+value%2C+includes+a+parameter+more+than+once%2C+or+is+otherwise+malformed.+Make+sure+that+the+various+parameters+are+correct%2C+be+aware+of+case+sensitivity+and+trim+your+parameters.+Make+sure+that+the+client+you+are+using+has+exactly+whitelisted+the+redirect_uri+you+specified.+with-debug&state=foostate") - b, _ := url.Parse(header.Get("Location")) - assert.NotContains(t, header.Get("Location"), "error_hint") - assert.NotContains(t, header.Get("Location"), "error_debug") - assert.Equal(t, a, b, "\n\t%s\n\t%s", header.Get("Location"), a.String()) - assert.Equal(t, "no-store", header.Get("Cache-Control")) - assert.Equal(t, "no-cache", header.Get("Pragma")) + b, _ := url.Parse(header.Get(consts.HeaderLocation)) + assert.NotContains(t, header.Get(consts.HeaderLocation), "error_hint") + assert.NotContains(t, header.Get(consts.HeaderLocation), "error_debug") + assert.Equal(t, a, b, "\n\t%s\n\t%s", header.Get(consts.HeaderLocation), a.String()) + assert.Equal(t, consts.CacheControlNoStore, header.Get(consts.HeaderCacheControl)) + assert.Equal(t, consts.PragmaNoCache, header.Get(consts.HeaderPragma)) }, }, // 12 @@ -303,20 +304,20 @@ func TestWriteAuthorizeError(t *testing.T) { req.EXPECT().IsRedirectURIValid().Return(true) req.EXPECT().GetRedirectURI().Return(copyUrl(purls[0])) req.EXPECT().GetState().Return("foostate") - req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{"code", "token"})) + req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{consts.ResponseTypeAuthorizationCodeFlow, consts.ResponseTypeImplicitFlowToken})) req.EXPECT().GetResponseMode().Return(ResponseModeFragment).AnyTimes() rw.EXPECT().Header().Times(3).Return(header) rw.EXPECT().WriteHeader(http.StatusSeeOther) }, checkHeader: func(t *testing.T, k int) { a, _ := url.Parse("https://foobar.com/#error=invalid_request&error_description=The+request+is+missing+a+required+parameter%2C+includes+an+invalid+parameter+value%2C+includes+a+parameter+more+than+once%2C+or+is+otherwise+malformed.+Make+sure+that+the+various+parameters+are+correct%2C+be+aware+of+case+sensitivity+and+trim+your+parameters.+Make+sure+that+the+client+you+are+using+has+exactly+whitelisted+the+redirect_uri+you+specified.&state=foostate") - b, _ := url.Parse(header.Get("Location")) - assert.NotContains(t, header.Get("Location"), "error_hint") - assert.NotContains(t, header.Get("Location"), "error_debug") - assert.NotContains(t, header.Get("Location"), "with-debug") - assert.Equal(t, a, b, "\n\t%s\n\t%s", header.Get("Location"), a.String()) - assert.Equal(t, "no-store", header.Get("Cache-Control")) - assert.Equal(t, "no-cache", header.Get("Pragma")) + b, _ := url.Parse(header.Get(consts.HeaderLocation)) + assert.NotContains(t, header.Get(consts.HeaderLocation), "error_hint") + assert.NotContains(t, header.Get(consts.HeaderLocation), "error_debug") + assert.NotContains(t, header.Get(consts.HeaderLocation), "with-debug") + assert.Equal(t, a, b, "\n\t%s\n\t%s", header.Get(consts.HeaderLocation), a.String()) + assert.Equal(t, consts.CacheControlNoStore, header.Get(consts.HeaderCacheControl)) + assert.Equal(t, consts.PragmaNoCache, header.Get(consts.HeaderPragma)) }, }, // 13 @@ -326,17 +327,17 @@ func TestWriteAuthorizeError(t *testing.T) { req.EXPECT().IsRedirectURIValid().Return(true) req.EXPECT().GetRedirectURI().Return(copyUrl(purls[1])) req.EXPECT().GetState().Return("foostate") - req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{"code", "token"})) + req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{consts.ResponseTypeAuthorizationCodeFlow, consts.ResponseTypeImplicitFlowToken})) req.EXPECT().GetResponseMode().Return(ResponseModeFragment).AnyTimes() rw.EXPECT().Header().Times(3).Return(header) rw.EXPECT().WriteHeader(http.StatusSeeOther) }, checkHeader: func(t *testing.T, k int) { a, _ := url.Parse("https://foobar.com/?foo=bar#error=invalid_request&error_description=The+request+is+missing+a+required+parameter%2C+includes+an+invalid+parameter+value%2C+includes+a+parameter+more+than+once%2C+or+is+otherwise+malformed.&error_hint=Make+sure+that+the+various+parameters+are+correct%2C+be+aware+of+case+sensitivity+and+trim+your+parameters.+Make+sure+that+the+client+you+are+using+has+exactly+whitelisted+the+redirect_uri+you+specified.&state=foostate") - b, _ := url.Parse(header.Get("Location")) - assert.Equal(t, a, b, "\n\t%s\n\t%s", header.Get("Location"), a.String()) - assert.Equal(t, "no-store", header.Get("Cache-Control")) - assert.Equal(t, "no-cache", header.Get("Pragma")) + b, _ := url.Parse(header.Get(consts.HeaderLocation)) + assert.Equal(t, a, b, "\n\t%s\n\t%s", header.Get(consts.HeaderLocation), a.String()) + assert.Equal(t, consts.CacheControlNoStore, header.Get(consts.HeaderCacheControl)) + assert.Equal(t, consts.PragmaNoCache, header.Get(consts.HeaderPragma)) }, }, // 14 @@ -347,17 +348,17 @@ func TestWriteAuthorizeError(t *testing.T) { req.EXPECT().IsRedirectURIValid().Return(true) req.EXPECT().GetRedirectURI().Return(copyUrl(purls[1])) req.EXPECT().GetState().Return("foostate") - req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{"code", "token"})) + req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{consts.ResponseTypeAuthorizationCodeFlow, consts.ResponseTypeImplicitFlowToken})) req.EXPECT().GetResponseMode().Return(ResponseModeFragment).AnyTimes() rw.EXPECT().Header().Times(3).Return(header) rw.EXPECT().WriteHeader(http.StatusSeeOther) }, checkHeader: func(t *testing.T, k int) { a, _ := url.Parse("https://foobar.com/?foo=bar#error=invalid_request&error_debug=with-debug&error_description=The+request+is+missing+a+required+parameter%2C+includes+an+invalid+parameter+value%2C+includes+a+parameter+more+than+once%2C+or+is+otherwise+malformed.&error_hint=Make+sure+that+the+various+parameters+are+correct%2C+be+aware+of+case+sensitivity+and+trim+your+parameters.+Make+sure+that+the+client+you+are+using+has+exactly+whitelisted+the+redirect_uri+you+specified.&state=foostate") - b, _ := url.Parse(header.Get("Location")) - assert.Equal(t, a, b, "\n\t%s\n\t%s", header.Get("Location"), a.String()) - assert.Equal(t, "no-store", header.Get("Cache-Control")) - assert.Equal(t, "no-cache", header.Get("Pragma")) + b, _ := url.Parse(header.Get(consts.HeaderLocation)) + assert.Equal(t, a, b, "\n\t%s\n\t%s", header.Get(consts.HeaderLocation), a.String()) + assert.Equal(t, consts.CacheControlNoStore, header.Get(consts.HeaderCacheControl)) + assert.Equal(t, consts.PragmaNoCache, header.Get(consts.HeaderPragma)) }, }, // 15 @@ -368,17 +369,17 @@ func TestWriteAuthorizeError(t *testing.T) { req.EXPECT().IsRedirectURIValid().Return(true) req.EXPECT().GetRedirectURI().Return(copyUrl(purls[1])) req.EXPECT().GetState().Return("foostate") - req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{"id_token"})) + req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{consts.ResponseTypeImplicitFlowIDToken})) req.EXPECT().GetResponseMode().Return(ResponseModeFragment).AnyTimes() rw.EXPECT().Header().Times(3).Return(header) rw.EXPECT().WriteHeader(http.StatusSeeOther) }, checkHeader: func(t *testing.T, k int) { a, _ := url.Parse("https://foobar.com/?foo=bar#error=invalid_request&error_debug=with-debug&error_description=The+request+is+missing+a+required+parameter%2C+includes+an+invalid+parameter+value%2C+includes+a+parameter+more+than+once%2C+or+is+otherwise+malformed.&error_hint=Make+sure+that+the+various+parameters+are+correct%2C+be+aware+of+case+sensitivity+and+trim+your+parameters.+Make+sure+that+the+client+you+are+using+has+exactly+whitelisted+the+redirect_uri+you+specified.&state=foostate") - b, _ := url.Parse(header.Get("Location")) - assert.Equal(t, a, b, "\n\t%s\n\t%s", header.Get("Location"), a.String()) - assert.Equal(t, "no-store", header.Get("Cache-Control")) - assert.Equal(t, "no-cache", header.Get("Pragma")) + b, _ := url.Parse(header.Get(consts.HeaderLocation)) + assert.Equal(t, a, b, "\n\t%s\n\t%s", header.Get(consts.HeaderLocation), a.String()) + assert.Equal(t, consts.CacheControlNoStore, header.Get(consts.HeaderCacheControl)) + assert.Equal(t, consts.PragmaNoCache, header.Get(consts.HeaderPragma)) }, }, // 16 @@ -389,17 +390,17 @@ func TestWriteAuthorizeError(t *testing.T) { req.EXPECT().IsRedirectURIValid().Return(true) req.EXPECT().GetRedirectURI().Return(copyUrl(purls[1])) req.EXPECT().GetState().Return("foostate") - req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{"token"})) + req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{consts.ResponseTypeImplicitFlowToken})) req.EXPECT().GetResponseMode().Return(ResponseModeFragment).AnyTimes() rw.EXPECT().Header().Times(3).Return(header) rw.EXPECT().WriteHeader(http.StatusSeeOther) }, checkHeader: func(t *testing.T, k int) { a, _ := url.Parse("https://foobar.com/?foo=bar#error=invalid_request&error_debug=with-debug&error_description=The+request+is+missing+a+required+parameter%2C+includes+an+invalid+parameter+value%2C+includes+a+parameter+more+than+once%2C+or+is+otherwise+malformed.&error_hint=Make+sure+that+the+various+parameters+are+correct%2C+be+aware+of+case+sensitivity+and+trim+your+parameters.+Make+sure+that+the+client+you+are+using+has+exactly+whitelisted+the+redirect_uri+you+specified.&state=foostate") - b, _ := url.Parse(header.Get("Location")) - assert.Equal(t, a, b, "\n\t%s\n\t%s", header.Get("Location"), a.String()) - assert.Equal(t, "no-store", header.Get("Cache-Control")) - assert.Equal(t, "no-cache", header.Get("Pragma")) + b, _ := url.Parse(header.Get(consts.HeaderLocation)) + assert.Equal(t, a, b, "\n\t%s\n\t%s", header.Get(consts.HeaderLocation), a.String()) + assert.Equal(t, consts.CacheControlNoStore, header.Get(consts.HeaderCacheControl)) + assert.Equal(t, consts.PragmaNoCache, header.Get(consts.HeaderPragma)) }, }, // 17 @@ -410,15 +411,15 @@ func TestWriteAuthorizeError(t *testing.T) { req.EXPECT().IsRedirectURIValid().Return(true) req.EXPECT().GetRedirectURI().Return(copyUrl(purls[1])) req.EXPECT().GetState().Return("foostate") - req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{"token"})) + req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{consts.ResponseTypeImplicitFlowToken})) req.EXPECT().GetResponseMode().Return(ResponseModeFormPost).Times(2) rw.EXPECT().Header().Times(3).Return(header) rw.EXPECT().Write(gomock.Any()).AnyTimes() }, checkHeader: func(t *testing.T, k int) { - assert.Equal(t, "no-store", header.Get("Cache-Control")) - assert.Equal(t, "no-cache", header.Get("Pragma")) - assert.Equal(t, "text/html;charset=UTF-8", header.Get("Content-Type")) + assert.Equal(t, consts.CacheControlNoStore, header.Get(consts.HeaderCacheControl)) + assert.Equal(t, consts.PragmaNoCache, header.Get(consts.HeaderPragma)) + assert.Equal(t, consts.ContentTypeTextHTML, header.Get(consts.HeaderContentType)) }, }, } { diff --git a/authorize_helper.go b/authorize_helper.go index 6815f66a..0f6c2f66 100644 --- a/authorize_helper.go +++ b/authorize_helper.go @@ -5,13 +5,13 @@ package oauth2 import ( "context" - "fmt" "html/template" "io" "net/url" "regexp" "strings" + "authelia.com/provider/oauth2/internal/consts" "authelia.com/provider/oauth2/internal/errorsx" "authelia.com/provider/oauth2/internal/urls" ) @@ -173,14 +173,14 @@ func IsValidRedirectURI(redirectURI *url.URL) bool { } func IsRedirectURISecure(ctx context.Context, redirectURI *url.URL) bool { - return !(redirectURI.Scheme == "http" && !IsLocalhost(redirectURI)) + return !(redirectURI.Scheme == consts.SchemeHTTP && !IsLocalhost(redirectURI)) } // IsRedirectURISecureStrict is stricter than IsRedirectURISecure and it does not allow custom-scheme // URLs because they can be hijacked for native apps. Use claimed HTTPS redirects instead. // See discussion in https://github.com/ory/fosite/pull/489. func IsRedirectURISecureStrict(redirectURI *url.URL) bool { - return redirectURI.Scheme == "https" || (redirectURI.Scheme == "http" && IsLocalhost(redirectURI)) + return redirectURI.Scheme == consts.SchemeHTTPS || (redirectURI.Scheme == consts.SchemeHTTP && IsLocalhost(redirectURI)) } func IsLocalhost(redirectURI *url.URL) bool { @@ -198,21 +198,6 @@ func WriteAuthorizeFormPostResponse(redirectURL string, parameters url.Values, t }) } -// Deprecated: Do not use. -func URLSetFragment(source *url.URL, fragment url.Values) { - var f string - for k, v := range fragment { - for _, vv := range v { - if len(f) != 0 { - f += fmt.Sprintf("&%s=%s", k, vv) - } else { - f += fmt.Sprintf("%s=%s", k, vv) - } - } - } - source.Fragment = f -} - func GetPostFormHTMLTemplate(ctx context.Context, f *Fosite) *template.Template { if t := f.Config.GetFormPostHTMLTemplate(ctx); t != nil { return t diff --git a/authorize_helper_test.go b/authorize_helper_test.go index a66fd10e..f960439f 100644 --- a/authorize_helper_test.go +++ b/authorize_helper_test.go @@ -16,6 +16,7 @@ import ( "authelia.com/provider/oauth2" "authelia.com/provider/oauth2/internal" + "authelia.com/provider/oauth2/internal/consts" ) func TestIsLocalhost(t *testing.T) { @@ -252,28 +253,28 @@ func TestWriteAuthorizeFormPostResponse(t *testing.T) { check func(code string, state string, customParams url.Values, d int) }{ { - parameters: url.Values{"code": {"lshr755nsg39fgur"}, "state": {"924659540232"}}, + parameters: url.Values{consts.FormParameterAuthorizationCode: {"lshr755nsg39fgur"}, consts.FormParameterState: {"924659540232"}}, check: func(code string, state string, customParams url.Values, d int) { assert.Equal(t, "lshr755nsg39fgur", code, "case %d", d) assert.Equal(t, "924659540232", state, "case %d", d) }, }, { - parameters: url.Values{"code": {"lshr75*ns-39f+ur"}, "state": {"9a:* <&)"}}, + parameters: url.Values{consts.FormParameterAuthorizationCode: {"lshr75*ns-39f+ur"}, consts.FormParameterState: {"9a:* <&)"}}, check: func(code string, state string, customParams url.Values, d int) { assert.Equal(t, "lshr75*ns-39f+ur", code, "case %d", d) assert.Equal(t, "9a:* <&)", state, "case %d", d) }, }, { - parameters: url.Values{"code": {"1234"}, "custom": {"test2", "test3"}}, + parameters: url.Values{consts.FormParameterAuthorizationCode: {"1234"}, "custom": {"test2", "test3"}}, check: func(code string, state string, customParams url.Values, d int) { assert.Equal(t, "1234", code, "case %d", d) assert.Equal(t, []string{"test2", "test3"}, customParams["custom"], "case %d", d) }, }, { - parameters: url.Values{"code": {"1234"}, "custom": {"Bold"}}, + parameters: url.Values{consts.FormParameterAuthorizationCode: {"1234"}, "custom": {"Bold"}}, check: func(code string, state string, customParams url.Values, d int) { assert.Equal(t, "1234", code, "case %d", d) assert.Equal(t, "Bold", customParams.Get("custom"), "case %d", d) @@ -312,31 +313,6 @@ func TestIsRedirectURISecureStrict(t *testing.T) { } } -func TestURLSetFragment(t *testing.T) { - for d, c := range []struct { - u string - a string - f url.Values - }{ - {u: "http://google.com", a: "http://google.com#code=567060896", f: url.Values{"code": []string{"567060896"}}}, - {u: "http://google.com", a: "http://google.com#code=567060896&scope=read", f: url.Values{"code": []string{"567060896"}, "scope": []string{"read"}}}, - {u: "http://google.com", a: "http://google.com#code=567060896&scope=read%20mail", f: url.Values{"code": []string{"567060896j"}, "scope": []string{"read mail"}}}, - {u: "http://google.com", a: "http://google.com#code=567060896&scope=read+write", f: url.Values{"code": []string{"567060896"}, "scope": []string{"read+write"}}}, - {u: "http://google.com", a: "http://google.com#code=567060896&scope=api:*", f: url.Values{"code": []string{"567060896"}, "scope": []string{"api:*"}}}, - {u: "https://google.com?foo=bar", a: "https://google.com?foo=bar#code=567060896", f: url.Values{"code": []string{"567060896"}}}, - {u: "http://localhost?foo=bar&baz=foo", a: "http://localhost?foo=bar&baz=foo#code=567060896", f: url.Values{"code": []string{"567060896"}}}, - } { - uu, err := url.Parse(c.u) - require.NoError(t, err) - oauth2.URLSetFragment(uu, c.f) - tURL, err := url.Parse(uu.String()) - require.NoError(t, err) - r := ParseURLFragment(tURL.Fragment) - assert.Equal(t, c.f.Get("code"), r.Get("code"), "case %d", d) - assert.Equal(t, c.f.Get("scope"), r.Get("scope"), "case %d", d) - } -} - func ParseURLFragment(fragment string) url.Values { r := url.Values{} kvs := strings.Split(fragment, "&") diff --git a/authorize_request.go b/authorize_request.go index 2ad0e1e9..4dff3aaf 100644 --- a/authorize_request.go +++ b/authorize_request.go @@ -5,15 +5,17 @@ package oauth2 import ( "net/url" + + "authelia.com/provider/oauth2/internal/consts" ) type ResponseModeType string const ( ResponseModeDefault = ResponseModeType("") - ResponseModeFormPost = ResponseModeType("form_post") - ResponseModeQuery = ResponseModeType("query") - ResponseModeFragment = ResponseModeType("fragment") + ResponseModeFormPost = ResponseModeType(consts.ResponseModeFormPost) + ResponseModeQuery = ResponseModeType(consts.ResponseModeQuery) + ResponseModeFragment = ResponseModeType(consts.ResponseModeFragment) ) // AuthorizeRequest is an implementation of AuthorizeRequester diff --git a/authorize_request_handler.go b/authorize_request_handler.go index a1b91d49..60be4d9e 100644 --- a/authorize_request_handler.go +++ b/authorize_request_handler.go @@ -10,11 +10,11 @@ import ( "net/http" "strings" - "authelia.com/provider/oauth2/internal/consts" "github.com/go-jose/go-jose/v3" "github.com/pkg/errors" "authelia.com/provider/oauth2/i18n" + "authelia.com/provider/oauth2/internal/consts" "authelia.com/provider/oauth2/internal/errorsx" "authelia.com/provider/oauth2/internal/stringslice" "authelia.com/provider/oauth2/token/jwt" diff --git a/authorize_request_handler_oidc_request_test.go b/authorize_request_handler_oidc_request_test.go index 244a70f4..31982314 100644 --- a/authorize_request_handler_oidc_request_test.go +++ b/authorize_request_handler_oidc_request_test.go @@ -14,19 +14,19 @@ import ( "net/url" "testing" - "authelia.com/provider/oauth2/internal/consts" "github.com/go-jose/go-jose/v3" "github.com/pkg/errors" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "authelia.com/provider/oauth2/internal/consts" "authelia.com/provider/oauth2/token/jwt" ) func mustGenerateAssertion(t *testing.T, claims jwt.MapClaims, key *rsa.PrivateKey, kid string) string { token := jwt.NewWithClaims(jose.RS256, claims) if kid != "" { - token.Header["kid"] = kid + token.Header[consts.JSONWebTokenHeaderKeyIdentifier] = kid } tokenString, err := token.SignedString(key) require.NoError(t, err) @@ -62,9 +62,9 @@ func TestAuthorizeRequestParametersFromOpenIDConnectRequest(t *testing.T) { }, } - validRequestObject := mustGenerateAssertion(t, jwt.MapClaims{"scope": "foo", "foo": "bar", "baz": "baz", "response_type": "token", "response_mode": "post_form"}, key, "kid-foo") - validRequestObjectWithoutKid := mustGenerateAssertion(t, jwt.MapClaims{"scope": "foo", "foo": "bar", "baz": "baz"}, key, "") - validNoneRequestObject := mustGenerateNoneAssertion(t, jwt.MapClaims{"scope": "foo", "foo": "bar", "baz": "baz", "state": "some-state"}) + validRequestObject := mustGenerateAssertion(t, jwt.MapClaims{consts.FormParameterScope: "foo", "foo": "bar", "baz": "baz", consts.FormParameterResponseType: consts.ResponseTypeImplicitFlowToken, consts.FormParameterResponseMode: consts.ResponseModeFormPost}, key, "kid-foo") + validRequestObjectWithoutKid := mustGenerateAssertion(t, jwt.MapClaims{consts.FormParameterScope: "foo", "foo": "bar", "baz": "baz"}, key, "") + validNoneRequestObject := mustGenerateNoneAssertion(t, jwt.MapClaims{consts.FormParameterScope: "foo", "foo": "bar", "baz": "baz", consts.FormParameterState: "some-state"}) var reqH http.HandlerFunc = func(rw http.ResponseWriter, r *http.Request) { rw.Write([]byte(validRequestObject)) @@ -153,7 +153,7 @@ func TestAuthorizeRequestParametersFromOpenIDConnectRequest(t *testing.T) { form: url.Values{consts.FormParameterScope: {consts.ScopeOpenID}, consts.FormParameterResponseType: {consts.ResponseTypeAuthorizationCodeFlow}, consts.FormParameterResponseMode: {consts.ResponseModeNone}, consts.FormParameterRequest: {validRequestObject}}, client: &DefaultOpenIDConnectClient{JSONWebKeys: jwks, RequestObjectSigningAlgorithm: "RS256"}, // The values from form are overwritten by the request object. - expectForm: url.Values{consts.FormParameterResponseType: {consts.ResponseTypeImplicitFlowToken}, consts.FormParameterResponseMode: {"post_form"}, consts.FormParameterScope: {"foo openid"}, consts.FormParameterRequest: {validRequestObject}, "foo": {"bar"}, "baz": {"baz"}}, + expectForm: url.Values{consts.FormParameterResponseType: {consts.ResponseTypeImplicitFlowToken}, consts.FormParameterResponseMode: {consts.ResponseModeFormPost}, consts.FormParameterScope: {"foo openid"}, consts.FormParameterRequest: {validRequestObject}, "foo": {"bar"}, "baz": {"baz"}}, }, { d: "should pass even if kid is unset", @@ -172,7 +172,7 @@ func TestAuthorizeRequestParametersFromOpenIDConnectRequest(t *testing.T) { d: "should pass and set request_uri parameters properly and also fetch jwk from remote", form: url.Values{consts.FormParameterScope: {consts.ScopeOpenID}, consts.FormParameterRequestURI: {reqTS.URL}}, client: &DefaultOpenIDConnectClient{JSONWebKeysURI: reqJWK.URL, RequestObjectSigningAlgorithm: "RS256", RequestURIs: []string{reqTS.URL}}, - expectForm: url.Values{"response_type": {"token"}, "response_mode": {"post_form"}, consts.FormParameterScope: {"foo openid"}, consts.FormParameterRequestURI: {reqTS.URL}, "foo": {"bar"}, "baz": {"baz"}}, + expectForm: url.Values{consts.FormParameterResponseType: {"token"}, consts.FormParameterResponseMode: {consts.ResponseModeFormPost}, consts.FormParameterScope: {"foo openid"}, consts.FormParameterRequestURI: {reqTS.URL}, "foo": {"bar"}, "baz": {"baz"}}, }, { d: "should pass when request object uses algorithm none", diff --git a/authorize_request_handler_test.go b/authorize_request_handler_test.go index 46213855..e3df6fec 100644 --- a/authorize_request_handler_test.go +++ b/authorize_request_handler_test.go @@ -17,6 +17,7 @@ import ( . "authelia.com/provider/oauth2" . "authelia.com/provider/oauth2/internal" + "authelia.com/provider/oauth2/internal/consts" ) // Should pass @@ -53,7 +54,7 @@ func TestNewAuthorizeRequest(t *testing.T) { { desc: "invalid redirect uri fails", provider: &Fosite{Store: store, Config: &Config{ScopeStrategy: ExactScopeStrategy, AudienceMatchingStrategy: DefaultAudienceMatchingStrategy}}, - query: url.Values{"redirect_uri": []string{"invalid"}}, + query: url.Values{consts.FormParameterClientID: []string{"invalid"}}, expectedError: ErrInvalidClient, mock: func() { store.EXPECT().GetClient(gomock.Any(), gomock.Any()).Return(nil, errors.New("foo")) @@ -63,7 +64,7 @@ func TestNewAuthorizeRequest(t *testing.T) { { desc: "invalid client fails", provider: &Fosite{Store: store, Config: &Config{ScopeStrategy: ExactScopeStrategy, AudienceMatchingStrategy: DefaultAudienceMatchingStrategy}}, - query: url.Values{"redirect_uri": []string{"https://foo.bar/cb"}}, + query: url.Values{consts.FormParameterClientID: []string{"https://foo.bar/cb"}}, expectedError: ErrInvalidClient, mock: func() { store.EXPECT().GetClient(gomock.Any(), gomock.Any()).Return(nil, errors.New("foo")) @@ -74,7 +75,7 @@ func TestNewAuthorizeRequest(t *testing.T) { desc: "client and request redirects mismatch", provider: &Fosite{Store: store, Config: &Config{ScopeStrategy: ExactScopeStrategy, AudienceMatchingStrategy: DefaultAudienceMatchingStrategy}}, query: url.Values{ - "client_id": []string{"1234"}, + consts.FormParameterClientID: []string{"1234"}, }, expectedError: ErrInvalidRequest, mock: func() { @@ -86,8 +87,8 @@ func TestNewAuthorizeRequest(t *testing.T) { desc: "client and request redirects mismatch", provider: &Fosite{Store: store, Config: &Config{ScopeStrategy: ExactScopeStrategy, AudienceMatchingStrategy: DefaultAudienceMatchingStrategy}}, query: url.Values{ - "redirect_uri": []string{""}, - "client_id": []string{"1234"}, + consts.FormParameterRedirectURI: []string{""}, + consts.FormParameterClientID: []string{"1234"}, }, expectedError: ErrInvalidRequest, mock: func() { @@ -99,8 +100,8 @@ func TestNewAuthorizeRequest(t *testing.T) { desc: "client and request redirects mismatch", provider: &Fosite{Store: store, Config: &Config{ScopeStrategy: ExactScopeStrategy, AudienceMatchingStrategy: DefaultAudienceMatchingStrategy}}, query: url.Values{ - "redirect_uri": []string{"https://foo.bar/cb"}, - "client_id": []string{"1234"}, + consts.FormParameterRedirectURI: []string{"https://foo.bar/cb"}, + consts.FormParameterClientID: []string{"1234"}, }, expectedError: ErrInvalidRequest, mock: func() { @@ -112,9 +113,9 @@ func TestNewAuthorizeRequest(t *testing.T) { desc: "no state", provider: &Fosite{Store: store, Config: &Config{ScopeStrategy: ExactScopeStrategy, AudienceMatchingStrategy: DefaultAudienceMatchingStrategy}}, query: url.Values{ - "redirect_uri": []string{"https://foo.bar/cb"}, - "client_id": []string{"1234"}, - "response_type": []string{"code"}, + consts.FormParameterRedirectURI: []string{"https://foo.bar/cb"}, + consts.FormParameterClientID: []string{"1234"}, + consts.FormParameterResponseType: []string{consts.ResponseTypeAuthorizationCodeFlow}, }, expectedError: ErrInvalidState, mock: func() { @@ -126,10 +127,10 @@ func TestNewAuthorizeRequest(t *testing.T) { desc: "short state", provider: &Fosite{Store: store, Config: &Config{ScopeStrategy: ExactScopeStrategy, AudienceMatchingStrategy: DefaultAudienceMatchingStrategy}}, query: url.Values{ - "redirect_uri": {"https://foo.bar/cb"}, - "client_id": {"1234"}, - "response_type": {"code"}, - "state": {"short"}, + consts.FormParameterRedirectURI: []string{"https://foo.bar/cb"}, + consts.FormParameterClientID: []string{"1234"}, + consts.FormParameterResponseType: []string{consts.ResponseTypeAuthorizationCodeFlow}, + consts.FormParameterState: {"short"}, }, expectedError: ErrInvalidState, mock: func() { @@ -141,11 +142,11 @@ func TestNewAuthorizeRequest(t *testing.T) { desc: "should fail because client does not have scope baz", provider: &Fosite{Store: store, Config: &Config{ScopeStrategy: ExactScopeStrategy, AudienceMatchingStrategy: DefaultAudienceMatchingStrategy}}, query: url.Values{ - "redirect_uri": {"https://foo.bar/cb"}, - "client_id": {"1234"}, - "response_type": {"code token"}, - "state": {"strong-state"}, - "scope": {"foo bar baz"}, + consts.FormParameterRedirectURI: {"https://foo.bar/cb"}, + consts.FormParameterClientID: {"1234"}, + consts.FormParameterResponseType: {consts.ResponseTypeHybridFlowToken}, + consts.FormParameterState: {"strong-state"}, + consts.FormParameterScope: {"foo bar baz"}, }, mock: func() { store.EXPECT().GetClient(gomock.Any(), "1234").Return(&DefaultClient{RedirectURIs: []string{"https://foo.bar/cb"}, Scopes: []string{"foo", "bar"}}, nil) @@ -157,17 +158,17 @@ func TestNewAuthorizeRequest(t *testing.T) { desc: "should fail because client does not have scope baz", provider: &Fosite{Store: store, Config: &Config{ScopeStrategy: ExactScopeStrategy, AudienceMatchingStrategy: DefaultAudienceMatchingStrategy}}, query: url.Values{ - "redirect_uri": {"https://foo.bar/cb"}, - "client_id": {"1234"}, - "response_type": {"code token"}, - "state": {"strong-state"}, - "scope": {"foo bar"}, - "audience": {"https://cloud.ory.sh/api https://www.authelia.com/api"}, + consts.FormParameterRedirectURI: {"https://foo.bar/cb"}, + consts.FormParameterClientID: {"1234"}, + consts.FormParameterResponseType: {consts.ResponseTypeHybridFlowToken}, + consts.FormParameterState: {"strong-state"}, + consts.FormParameterScope: {"foo bar"}, + consts.FormParameterAudience: {"https://cloud.authelia.com/api https://www.authelia.com/api"}, }, mock: func() { store.EXPECT().GetClient(gomock.Any(), "1234").Return(&DefaultClient{ RedirectURIs: []string{"https://foo.bar/cb"}, Scopes: []string{"foo", "bar"}, - Audience: []string{"https://cloud.ory.sh/api"}, + Audience: []string{"https://cloud.authelia.com/api"}, }, nil) }, expectedError: ErrInvalidRequest, @@ -177,33 +178,33 @@ func TestNewAuthorizeRequest(t *testing.T) { desc: "should pass", provider: &Fosite{Store: store, Config: &Config{ScopeStrategy: ExactScopeStrategy, AudienceMatchingStrategy: DefaultAudienceMatchingStrategy}}, query: url.Values{ - "redirect_uri": {"https://foo.bar/cb"}, - "client_id": {"1234"}, - "response_type": {"code token"}, - "state": {"strong-state"}, - "scope": {"foo bar"}, - "audience": {"https://cloud.ory.sh/api https://www.authelia.com/api"}, + consts.FormParameterRedirectURI: {"https://foo.bar/cb"}, + consts.FormParameterClientID: {"1234"}, + consts.FormParameterResponseType: {consts.ResponseTypeHybridFlowToken}, + consts.FormParameterState: {"strong-state"}, + consts.FormParameterScope: {"foo bar"}, + consts.FormParameterAudience: {"https://cloud.authelia.com/api https://www.authelia.com/api"}, }, mock: func() { store.EXPECT().GetClient(gomock.Any(), "1234").Return(&DefaultClient{ - ResponseTypes: []string{"code token"}, + ResponseTypes: []string{consts.ResponseTypeHybridFlowToken}, RedirectURIs: []string{"https://foo.bar/cb"}, Scopes: []string{"foo", "bar"}, - Audience: []string{"https://cloud.ory.sh/api", "https://www.authelia.com/api"}, + Audience: []string{"https://cloud.authelia.com/api", "https://www.authelia.com/api"}, }, nil) }, expect: &AuthorizeRequest{ RedirectURI: redir, - ResponseTypes: []string{"code", "token"}, + ResponseTypes: []string{consts.ResponseTypeAuthorizationCodeFlow, consts.ResponseTypeImplicitFlowToken}, State: "strong-state", Request: Request{ Client: &DefaultClient{ - ResponseTypes: []string{"code token"}, RedirectURIs: []string{"https://foo.bar/cb"}, + ResponseTypes: []string{consts.ResponseTypeHybridFlowToken}, RedirectURIs: []string{"https://foo.bar/cb"}, Scopes: []string{"foo", "bar"}, - Audience: []string{"https://cloud.ory.sh/api", "https://www.authelia.com/api"}, + Audience: []string{"https://cloud.authelia.com/api", "https://www.authelia.com/api"}, }, RequestedScope: []string{"foo", "bar"}, - RequestedAudience: []string{"https://cloud.ory.sh/api", "https://www.authelia.com/api"}, + RequestedAudience: []string{"https://cloud.authelia.com/api", "https://www.authelia.com/api"}, }, }, }, @@ -212,33 +213,33 @@ func TestNewAuthorizeRequest(t *testing.T) { desc: "repeated audience parameter", provider: &Fosite{Store: store, Config: &Config{ScopeStrategy: ExactScopeStrategy, AudienceMatchingStrategy: DefaultAudienceMatchingStrategy}}, query: url.Values{ - "redirect_uri": {"https://foo.bar/cb"}, - "client_id": {"1234"}, - "response_type": {"code token"}, - "state": {"strong-state"}, - "scope": {"foo bar"}, - "audience": {"https://cloud.ory.sh/api", "https://www.authelia.com/api"}, + consts.FormParameterRedirectURI: {"https://foo.bar/cb"}, + consts.FormParameterClientID: {"1234"}, + consts.FormParameterResponseType: {consts.ResponseTypeHybridFlowToken}, + consts.FormParameterState: {"strong-state"}, + consts.FormParameterScope: {"foo bar"}, + consts.FormParameterAudience: {"https://cloud.authelia.com/api", "https://www.authelia.com/api"}, }, mock: func() { store.EXPECT().GetClient(gomock.Any(), "1234").Return(&DefaultClient{ - ResponseTypes: []string{"code token"}, + ResponseTypes: []string{consts.ResponseTypeHybridFlowToken}, RedirectURIs: []string{"https://foo.bar/cb"}, Scopes: []string{"foo", "bar"}, - Audience: []string{"https://cloud.ory.sh/api", "https://www.authelia.com/api"}, + Audience: []string{"https://cloud.authelia.com/api", "https://www.authelia.com/api"}, }, nil) }, expect: &AuthorizeRequest{ RedirectURI: redir, - ResponseTypes: []string{"code", "token"}, + ResponseTypes: []string{consts.ResponseTypeAuthorizationCodeFlow, consts.ResponseTypeImplicitFlowToken}, State: "strong-state", Request: Request{ Client: &DefaultClient{ - ResponseTypes: []string{"code token"}, RedirectURIs: []string{"https://foo.bar/cb"}, + ResponseTypes: []string{consts.ResponseTypeHybridFlowToken}, RedirectURIs: []string{"https://foo.bar/cb"}, Scopes: []string{"foo", "bar"}, - Audience: []string{"https://cloud.ory.sh/api", "https://www.authelia.com/api"}, + Audience: []string{"https://cloud.authelia.com/api", "https://www.authelia.com/api"}, }, RequestedScope: []string{"foo", "bar"}, - RequestedAudience: []string{"https://cloud.ory.sh/api", "https://www.authelia.com/api"}, + RequestedAudience: []string{"https://cloud.authelia.com/api", "https://www.authelia.com/api"}, }, }, }, @@ -247,16 +248,16 @@ func TestNewAuthorizeRequest(t *testing.T) { desc: "repeated audience parameter with tricky values", provider: &Fosite{Store: store, Config: &Config{ScopeStrategy: ExactScopeStrategy, AudienceMatchingStrategy: ExactAudienceMatchingStrategy}}, query: url.Values{ - "redirect_uri": {"https://foo.bar/cb"}, - "client_id": {"1234"}, - "response_type": {"code token"}, - "state": {"strong-state"}, - "scope": {"foo bar"}, - "audience": {"test value", ""}, + consts.FormParameterRedirectURI: {"https://foo.bar/cb"}, + consts.FormParameterClientID: {"1234"}, + consts.FormParameterResponseType: {consts.ResponseTypeHybridFlowToken}, + consts.FormParameterState: {"strong-state"}, + consts.FormParameterScope: {"foo bar"}, + consts.FormParameterAudience: {"test value", ""}, }, mock: func() { store.EXPECT().GetClient(gomock.Any(), "1234").Return(&DefaultClient{ - ResponseTypes: []string{"code token"}, + ResponseTypes: []string{consts.ResponseTypeHybridFlowToken}, RedirectURIs: []string{"https://foo.bar/cb"}, Scopes: []string{"foo", "bar"}, Audience: []string{"test value"}, @@ -264,11 +265,11 @@ func TestNewAuthorizeRequest(t *testing.T) { }, expect: &AuthorizeRequest{ RedirectURI: redir, - ResponseTypes: []string{"code", "token"}, + ResponseTypes: []string{consts.ResponseTypeAuthorizationCodeFlow, consts.ResponseTypeImplicitFlowToken}, State: "strong-state", Request: Request{ Client: &DefaultClient{ - ResponseTypes: []string{"code token"}, RedirectURIs: []string{"https://foo.bar/cb"}, + ResponseTypes: []string{consts.ResponseTypeHybridFlowToken}, RedirectURIs: []string{"https://foo.bar/cb"}, Scopes: []string{"foo", "bar"}, Audience: []string{"test value"}, }, @@ -282,33 +283,33 @@ func TestNewAuthorizeRequest(t *testing.T) { desc: "redirect_uri with special character", provider: &Fosite{Store: store, Config: &Config{ScopeStrategy: ExactScopeStrategy, AudienceMatchingStrategy: DefaultAudienceMatchingStrategy}}, query: url.Values{ - "redirect_uri": {"web+application://callback"}, - "client_id": {"1234"}, - "response_type": {"code token"}, - "state": {"strong-state"}, - "scope": {"foo bar"}, - "audience": {"https://cloud.ory.sh/api https://www.authelia.com/api"}, + consts.FormParameterRedirectURI: {"web+application://callback"}, + consts.FormParameterClientID: {"1234"}, + consts.FormParameterResponseType: {consts.ResponseTypeHybridFlowToken}, + consts.FormParameterState: {"strong-state"}, + consts.FormParameterScope: {"foo bar"}, + consts.FormParameterAudience: {"https://cloud.authelia.com/api https://www.authelia.com/api"}, }, mock: func() { store.EXPECT().GetClient(gomock.Any(), "1234").Return(&DefaultClient{ - ResponseTypes: []string{"code token"}, + ResponseTypes: []string{consts.ResponseTypeHybridFlowToken}, RedirectURIs: []string{"web+application://callback"}, Scopes: []string{"foo", "bar"}, - Audience: []string{"https://cloud.ory.sh/api", "https://www.authelia.com/api"}, + Audience: []string{"https://cloud.authelia.com/api", "https://www.authelia.com/api"}, }, nil) }, expect: &AuthorizeRequest{ RedirectURI: specialCharRedir, - ResponseTypes: []string{"code", "token"}, + ResponseTypes: []string{consts.ResponseTypeAuthorizationCodeFlow, consts.ResponseTypeImplicitFlowToken}, State: "strong-state", Request: Request{ Client: &DefaultClient{ - ResponseTypes: []string{"code token"}, RedirectURIs: []string{"web+application://callback"}, + ResponseTypes: []string{consts.ResponseTypeHybridFlowToken}, RedirectURIs: []string{"web+application://callback"}, Scopes: []string{"foo", "bar"}, - Audience: []string{"https://cloud.ory.sh/api", "https://www.authelia.com/api"}, + Audience: []string{"https://cloud.authelia.com/api", "https://www.authelia.com/api"}, }, RequestedScope: []string{"foo", "bar"}, - RequestedAudience: []string{"https://cloud.ory.sh/api", "https://www.authelia.com/api"}, + RequestedAudience: []string{"https://cloud.authelia.com/api", "https://www.authelia.com/api"}, }, }, }, @@ -317,33 +318,33 @@ func TestNewAuthorizeRequest(t *testing.T) { desc: "audience with double spaces between values", provider: &Fosite{Store: store, Config: &Config{ScopeStrategy: ExactScopeStrategy, AudienceMatchingStrategy: DefaultAudienceMatchingStrategy}}, query: url.Values{ - "redirect_uri": {"https://foo.bar/cb"}, - "client_id": {"1234"}, - "response_type": {"code token"}, - "state": {"strong-state"}, - "scope": {"foo bar"}, - "audience": {"https://cloud.ory.sh/api https://www.authelia.com/api"}, + consts.FormParameterRedirectURI: {"https://foo.bar/cb"}, + consts.FormParameterClientID: {"1234"}, + consts.FormParameterResponseType: {consts.ResponseTypeHybridFlowToken}, + consts.FormParameterState: {"strong-state"}, + consts.FormParameterScope: {"foo bar"}, + consts.FormParameterAudience: {"https://cloud.authelia.com/api https://www.authelia.com/api"}, }, mock: func() { store.EXPECT().GetClient(gomock.Any(), "1234").Return(&DefaultClient{ - ResponseTypes: []string{"code token"}, + ResponseTypes: []string{consts.ResponseTypeHybridFlowToken}, RedirectURIs: []string{"https://foo.bar/cb"}, Scopes: []string{"foo", "bar"}, - Audience: []string{"https://cloud.ory.sh/api", "https://www.authelia.com/api"}, + Audience: []string{"https://cloud.authelia.com/api", "https://www.authelia.com/api"}, }, nil) }, expect: &AuthorizeRequest{ RedirectURI: redir, - ResponseTypes: []string{"code", "token"}, + ResponseTypes: []string{consts.ResponseTypeAuthorizationCodeFlow, consts.ResponseTypeImplicitFlowToken}, State: "strong-state", Request: Request{ Client: &DefaultClient{ - ResponseTypes: []string{"code token"}, RedirectURIs: []string{"https://foo.bar/cb"}, + ResponseTypes: []string{consts.ResponseTypeHybridFlowToken}, RedirectURIs: []string{"https://foo.bar/cb"}, Scopes: []string{"foo", "bar"}, - Audience: []string{"https://cloud.ory.sh/api", "https://www.authelia.com/api"}, + Audience: []string{"https://cloud.authelia.com/api", "https://www.authelia.com/api"}, }, RequestedScope: []string{"foo", "bar"}, - RequestedAudience: []string{"https://cloud.ory.sh/api", "https://www.authelia.com/api"}, + RequestedAudience: []string{"https://cloud.authelia.com/api", "https://www.authelia.com/api"}, }, }, }, @@ -352,12 +353,12 @@ func TestNewAuthorizeRequest(t *testing.T) { desc: "should fail because unknown response_mode", provider: &Fosite{Store: store, Config: &Config{ScopeStrategy: ExactScopeStrategy, AudienceMatchingStrategy: DefaultAudienceMatchingStrategy}}, query: url.Values{ - "redirect_uri": {"https://foo.bar/cb"}, - "client_id": {"1234"}, - "response_type": {"code token"}, - "state": {"strong-state"}, - "scope": {"foo bar"}, - "response_mode": {"unknown"}, + consts.FormParameterRedirectURI: {"https://foo.bar/cb"}, + consts.FormParameterClientID: {"1234"}, + consts.FormParameterResponseType: {consts.ResponseTypeHybridFlowToken}, + consts.FormParameterState: {"strong-state"}, + consts.FormParameterScope: {"foo bar"}, + consts.FormParameterResponseMode: {"unknown"}, }, mock: func() { store.EXPECT().GetClient(gomock.Any(), "1234").Return(&DefaultClient{RedirectURIs: []string{"https://foo.bar/cb"}, Scopes: []string{"foo", "bar"}, ResponseTypes: []string{"code token"}}, nil) @@ -369,12 +370,12 @@ func TestNewAuthorizeRequest(t *testing.T) { desc: "should fail because response_mode is requested but the OAuth 2.0 client doesn't support response mode", provider: &Fosite{Store: store, Config: &Config{ScopeStrategy: ExactScopeStrategy, AudienceMatchingStrategy: DefaultAudienceMatchingStrategy}}, query: url.Values{ - "redirect_uri": {"https://foo.bar/cb"}, - "client_id": {"1234"}, - "response_type": {"code token"}, - "state": {"strong-state"}, - "scope": {"foo bar"}, - "response_mode": {"form_post"}, + consts.FormParameterRedirectURI: {"https://foo.bar/cb"}, + consts.FormParameterClientID: {"1234"}, + consts.FormParameterResponseType: {consts.ResponseTypeHybridFlowToken}, + consts.FormParameterState: {"strong-state"}, + consts.FormParameterScope: {"foo bar"}, + consts.FormParameterResponseMode: {consts.ResponseModeFormPost}, }, mock: func() { store.EXPECT().GetClient(gomock.Any(), "1234").Return(&DefaultClient{RedirectURIs: []string{"https://foo.bar/cb"}, Scopes: []string{"foo", "bar"}, ResponseTypes: []string{"code token"}}, nil) @@ -386,19 +387,19 @@ func TestNewAuthorizeRequest(t *testing.T) { desc: "should fail because requested response mode is not allowed", provider: &Fosite{Store: store, Config: &Config{ScopeStrategy: ExactScopeStrategy, AudienceMatchingStrategy: DefaultAudienceMatchingStrategy}}, query: url.Values{ - "redirect_uri": {"https://foo.bar/cb"}, - "client_id": {"1234"}, - "response_type": {"code token"}, - "state": {"strong-state"}, - "scope": {"foo bar"}, - "response_mode": {"form_post"}, + consts.FormParameterRedirectURI: {"https://foo.bar/cb"}, + consts.FormParameterClientID: {"1234"}, + consts.FormParameterResponseType: {consts.ResponseTypeHybridFlowToken}, + consts.FormParameterState: {"strong-state"}, + consts.FormParameterScope: {"foo bar"}, + consts.FormParameterResponseMode: {consts.ResponseModeFormPost}, }, mock: func() { store.EXPECT().GetClient(gomock.Any(), "1234").Return(&DefaultResponseModeClient{ DefaultClient: &DefaultClient{ RedirectURIs: []string{"https://foo.bar/cb"}, Scopes: []string{"foo", "bar"}, - ResponseTypes: []string{"code token"}, + ResponseTypes: []string{consts.ResponseTypeHybridFlowToken}, }, ResponseModes: []ResponseModeType{ResponseModeQuery}, }, nil) @@ -410,41 +411,41 @@ func TestNewAuthorizeRequest(t *testing.T) { desc: "success with response mode", provider: &Fosite{Store: store, Config: &Config{ScopeStrategy: ExactScopeStrategy, AudienceMatchingStrategy: DefaultAudienceMatchingStrategy}}, query: url.Values{ - "redirect_uri": {"https://foo.bar/cb"}, - "client_id": {"1234"}, - "response_type": {"code token"}, - "state": {"strong-state"}, - "scope": {"foo bar"}, - "response_mode": {"form_post"}, - "audience": {"https://cloud.ory.sh/api https://www.authelia.com/api"}, + consts.FormParameterRedirectURI: {"https://foo.bar/cb"}, + consts.FormParameterClientID: {"1234"}, + consts.FormParameterResponseType: {consts.ResponseTypeHybridFlowToken}, + consts.FormParameterState: {"strong-state"}, + consts.FormParameterScope: {"foo bar"}, + consts.FormParameterResponseMode: {consts.ResponseModeFormPost}, + consts.FormParameterAudience: {"https://cloud.authelia.com/api https://www.authelia.com/api"}, }, mock: func() { store.EXPECT().GetClient(gomock.Any(), "1234").Return(&DefaultResponseModeClient{ DefaultClient: &DefaultClient{ RedirectURIs: []string{"https://foo.bar/cb"}, Scopes: []string{"foo", "bar"}, - ResponseTypes: []string{"code token"}, - Audience: []string{"https://cloud.ory.sh/api", "https://www.authelia.com/api"}, + ResponseTypes: []string{consts.ResponseTypeHybridFlowToken}, + Audience: []string{"https://cloud.authelia.com/api", "https://www.authelia.com/api"}, }, ResponseModes: []ResponseModeType{ResponseModeFormPost}, }, nil) }, expect: &AuthorizeRequest{ RedirectURI: redir, - ResponseTypes: []string{"code", "token"}, + ResponseTypes: []string{consts.ResponseTypeAuthorizationCodeFlow, consts.ResponseTypeImplicitFlowToken}, State: "strong-state", Request: Request{ Client: &DefaultResponseModeClient{ DefaultClient: &DefaultClient{ RedirectURIs: []string{"https://foo.bar/cb"}, Scopes: []string{"foo", "bar"}, - ResponseTypes: []string{"code token"}, - Audience: []string{"https://cloud.ory.sh/api", "https://www.authelia.com/api"}, + ResponseTypes: []string{consts.ResponseTypeHybridFlowToken}, + Audience: []string{"https://cloud.authelia.com/api", "https://www.authelia.com/api"}, }, ResponseModes: []ResponseModeType{ResponseModeFormPost}, }, RequestedScope: []string{"foo", "bar"}, - RequestedAudience: []string{"https://cloud.ory.sh/api", "https://www.authelia.com/api"}, + RequestedAudience: []string{"https://cloud.authelia.com/api", "https://www.authelia.com/api"}, }, }, }, @@ -453,40 +454,40 @@ func TestNewAuthorizeRequest(t *testing.T) { desc: "success with response mode", provider: &Fosite{Store: store, Config: &Config{ScopeStrategy: ExactScopeStrategy, AudienceMatchingStrategy: DefaultAudienceMatchingStrategy}}, query: url.Values{ - "redirect_uri": {"https://foo.bar/cb"}, - "client_id": {"1234"}, - "response_type": {"code"}, - "state": {"strong-state"}, - "scope": {"foo bar"}, - "audience": {"https://cloud.ory.sh/api https://www.authelia.com/api"}, + consts.FormParameterRedirectURI: {"https://foo.bar/cb"}, + consts.FormParameterClientID: {"1234"}, + consts.FormParameterResponseType: {consts.ResponseTypeAuthorizationCodeFlow}, + consts.FormParameterState: {"strong-state"}, + consts.FormParameterScope: {"foo bar"}, + consts.FormParameterAudience: {"https://cloud.authelia.com/api https://www.authelia.com/api"}, }, mock: func() { store.EXPECT().GetClient(gomock.Any(), "1234").Return(&DefaultResponseModeClient{ DefaultClient: &DefaultClient{ RedirectURIs: []string{"https://foo.bar/cb"}, Scopes: []string{"foo", "bar"}, - ResponseTypes: []string{"code"}, - Audience: []string{"https://cloud.ory.sh/api", "https://www.authelia.com/api"}, + ResponseTypes: []string{consts.ResponseTypeAuthorizationCodeFlow}, + Audience: []string{"https://cloud.authelia.com/api", "https://www.authelia.com/api"}, }, ResponseModes: []ResponseModeType{ResponseModeQuery}, }, nil) }, expect: &AuthorizeRequest{ RedirectURI: redir, - ResponseTypes: []string{"code"}, + ResponseTypes: []string{consts.ResponseTypeAuthorizationCodeFlow}, State: "strong-state", Request: Request{ Client: &DefaultResponseModeClient{ DefaultClient: &DefaultClient{ RedirectURIs: []string{"https://foo.bar/cb"}, Scopes: []string{"foo", "bar"}, - ResponseTypes: []string{"code"}, - Audience: []string{"https://cloud.ory.sh/api", "https://www.authelia.com/api"}, + ResponseTypes: []string{consts.ResponseTypeAuthorizationCodeFlow}, + Audience: []string{"https://cloud.authelia.com/api", "https://www.authelia.com/api"}, }, ResponseModes: []ResponseModeType{ResponseModeQuery}, }, RequestedScope: []string{"foo", "bar"}, - RequestedAudience: []string{"https://cloud.ory.sh/api", "https://www.authelia.com/api"}, + RequestedAudience: []string{"https://cloud.authelia.com/api", "https://www.authelia.com/api"}, }, }, }, @@ -495,40 +496,40 @@ func TestNewAuthorizeRequest(t *testing.T) { desc: "success with response mode", provider: &Fosite{Store: store, Config: &Config{ScopeStrategy: ExactScopeStrategy, AudienceMatchingStrategy: DefaultAudienceMatchingStrategy}}, query: url.Values{ - "redirect_uri": {"https://foo.bar/cb"}, - "client_id": {"1234"}, - "response_type": {"code token"}, - "state": {"strong-state"}, - "scope": {"foo bar"}, - "audience": {"https://cloud.ory.sh/api https://www.authelia.com/api"}, + consts.FormParameterRedirectURI: {"https://foo.bar/cb"}, + consts.FormParameterClientID: {"1234"}, + consts.FormParameterResponseType: {consts.ResponseTypeHybridFlowToken}, + consts.FormParameterState: {"strong-state"}, + consts.FormParameterScope: {"foo bar"}, + consts.FormParameterAudience: {"https://cloud.authelia.com/api https://www.authelia.com/api"}, }, mock: func() { store.EXPECT().GetClient(gomock.Any(), "1234").Return(&DefaultResponseModeClient{ DefaultClient: &DefaultClient{ RedirectURIs: []string{"https://foo.bar/cb"}, Scopes: []string{"foo", "bar"}, - ResponseTypes: []string{"code token"}, - Audience: []string{"https://cloud.ory.sh/api", "https://www.authelia.com/api"}, + ResponseTypes: []string{consts.ResponseTypeHybridFlowToken}, + Audience: []string{"https://cloud.authelia.com/api", "https://www.authelia.com/api"}, }, ResponseModes: []ResponseModeType{ResponseModeFragment}, }, nil) }, expect: &AuthorizeRequest{ RedirectURI: redir, - ResponseTypes: []string{"code", "token"}, + ResponseTypes: []string{consts.ResponseTypeAuthorizationCodeFlow, consts.ResponseTypeImplicitFlowToken}, State: "strong-state", Request: Request{ Client: &DefaultResponseModeClient{ DefaultClient: &DefaultClient{ RedirectURIs: []string{"https://foo.bar/cb"}, Scopes: []string{"foo", "bar"}, - ResponseTypes: []string{"code token"}, - Audience: []string{"https://cloud.ory.sh/api", "https://www.authelia.com/api"}, + ResponseTypes: []string{consts.ResponseTypeHybridFlowToken}, + Audience: []string{"https://cloud.authelia.com/api", "https://www.authelia.com/api"}, }, ResponseModes: []ResponseModeType{ResponseModeFragment}, }, RequestedScope: []string{"foo", "bar"}, - RequestedAudience: []string{"https://cloud.ory.sh/api", "https://www.authelia.com/api"}, + RequestedAudience: []string{"https://cloud.authelia.com/api", "https://www.authelia.com/api"}, }, }, }, @@ -551,7 +552,7 @@ func TestNewAuthorizeRequest(t *testing.T) { if c.expectedError != nil { assert.EqualError(t, err, c.expectedError.Error()) // https://github.com/ory/hydra/issues/1642 - AssertObjectKeysEqual(t, &AuthorizeRequest{State: c.query.Get("state")}, ar, "State") + AssertObjectKeysEqual(t, &AuthorizeRequest{State: c.query.Get(consts.FormParameterState)}, ar, "State") } else { require.NoError(t, err) AssertObjectKeysEqual(t, c.expect, ar, "ResponseTypes", "RequestedAudience", "RequestedScope", "Client", "RedirectURI", "State") diff --git a/authorize_response_test.go b/authorize_response_test.go index 3ed75419..8b223f0e 100644 --- a/authorize_response_test.go +++ b/authorize_response_test.go @@ -7,6 +7,8 @@ import ( "testing" "github.com/stretchr/testify/assert" + + "authelia.com/provider/oauth2/internal/consts" ) func TestAuthorizeResponse(t *testing.T) { @@ -16,7 +18,7 @@ func TestAuthorizeResponse(t *testing.T) { ar.AddHeader("foo", "foo") - ar.AddParameter("code", "bar") + ar.AddParameter(consts.FormParameterAuthorizationCode, "bar") assert.Equal(t, "bar", ar.GetCode()) assert.Equal(t, "bar", ar.GetParameters().Get("foo")) diff --git a/authorize_write.go b/authorize_write.go index 467fcb14..a43ab782 100644 --- a/authorize_write.go +++ b/authorize_write.go @@ -6,6 +6,8 @@ package oauth2 import ( "context" "net/http" + + "authelia.com/provider/oauth2/internal/consts" ) func (f *Fosite) WriteAuthorizeResponse(ctx context.Context, rw http.ResponseWriter, ar AuthorizeRequester, resp AuthorizeResponder) { @@ -16,14 +18,14 @@ func (f *Fosite) WriteAuthorizeResponse(ctx context.Context, rw http.ResponseWri wh.Set(k, rh.Get(k)) } - wh.Set("Cache-Control", "no-store") - wh.Set("Pragma", "no-cache") + wh.Set(consts.HeaderCacheControl, consts.CacheControlNoStore) + wh.Set(consts.HeaderPragma, consts.PragmaNoCache) redir := ar.GetRedirectURI() switch rm := ar.GetResponseMode(); rm { case ResponseModeFormPost: //form_post - rw.Header().Add("Content-Type", "text/html;charset=UTF-8") + rw.Header().Add(consts.HeaderContentType, consts.ContentTypeTextHTML) WriteAuthorizeFormPostResponse(redir.String(), resp.GetParameters(), GetPostFormHTMLTemplate(ctx, f), rw) return case ResponseModeQuery, ResponseModeDefault: @@ -62,6 +64,6 @@ func (f *Fosite) WriteAuthorizeResponse(ctx context.Context, rw http.ResponseWri // redirection response, or by other means available to it via the // user-agent. func sendRedirect(url string, rw http.ResponseWriter) { - rw.Header().Set("Location", url) + rw.Header().Set(consts.HeaderLocation, url) rw.WriteHeader(http.StatusSeeOther) } diff --git a/authorize_write_test.go b/authorize_write_test.go index 12cdc389..22d5960c 100644 --- a/authorize_write_test.go +++ b/authorize_write_test.go @@ -14,6 +14,7 @@ import ( . "authelia.com/provider/oauth2" . "authelia.com/provider/oauth2/internal" + "authelia.com/provider/oauth2/internal/consts" ) func TestWriteAuthorizeResponse(t *testing.T) { @@ -42,9 +43,9 @@ func TestWriteAuthorizeResponse(t *testing.T) { }, expect: func() { assert.Equal(t, http.Header{ - "Location": []string{"https://foobar.com/?foo=bar"}, - "Cache-Control": []string{"no-store"}, - "Pragma": []string{"no-cache"}, + consts.HeaderLocation: []string{"https://foobar.com/?foo=bar"}, + consts.HeaderCacheControl: []string{consts.CacheControlNoStore}, + consts.HeaderPragma: []string{consts.PragmaNoCache}, }, header) }, }, @@ -61,9 +62,9 @@ func TestWriteAuthorizeResponse(t *testing.T) { }, expect: func() { assert.Equal(t, http.Header{ - "Location": []string{"https://foobar.com/?foo=bar#bar=baz"}, - "Cache-Control": []string{"no-store"}, - "Pragma": []string{"no-cache"}, + consts.HeaderLocation: []string{"https://foobar.com/?foo=bar#bar=baz"}, + consts.HeaderCacheControl: []string{consts.CacheControlNoStore}, + consts.HeaderPragma: []string{consts.PragmaNoCache}, }, header) }, }, @@ -80,11 +81,11 @@ func TestWriteAuthorizeResponse(t *testing.T) { }, expect: func() { expectedUrl, _ := url.Parse("https://foobar.com/?foo=bar&bar=baz") - actualUrl, err := url.Parse(header.Get("Location")) + actualUrl, err := url.Parse(header.Get(consts.HeaderLocation)) assert.Nil(t, err) assert.Equal(t, expectedUrl.Query(), actualUrl.Query()) - assert.Equal(t, "no-cache", header.Get("Pragma")) - assert.Equal(t, "no-store", header.Get("Cache-Control")) + assert.Equal(t, consts.PragmaNoCache, header.Get(consts.HeaderPragma)) + assert.Equal(t, consts.CacheControlNoStore, header.Get(consts.HeaderCacheControl)) }, }, { @@ -100,10 +101,10 @@ func TestWriteAuthorizeResponse(t *testing.T) { }, expect: func() { assert.Equal(t, http.Header{ - "X-Bar": {"baz"}, - "Location": {"https://foobar.com/?foo=bar#bar=b%2Baz+ab"}, - "Cache-Control": []string{"no-store"}, - "Pragma": []string{"no-cache"}, + "X-Bar": {"baz"}, + consts.HeaderLocation: {"https://foobar.com/?foo=bar#bar=b%2Baz+ab"}, + consts.HeaderCacheControl: []string{consts.CacheControlNoStore}, + consts.HeaderPragma: []string{consts.PragmaNoCache}, }, header) }, }, @@ -112,7 +113,7 @@ func TestWriteAuthorizeResponse(t *testing.T) { redir, _ := url.Parse("https://foobar.com/?foo=bar") ar.EXPECT().GetRedirectURI().Return(redir) ar.EXPECT().GetResponseMode().Return(ResponseModeQuery) - resp.EXPECT().GetParameters().Return(url.Values{"bar": {"b+az"}, "scope": {"a b"}}) + resp.EXPECT().GetParameters().Return(url.Values{"bar": {"b+az"}, consts.FormParameterScope: {"a b"}}) resp.EXPECT().GetHeader().Return(http.Header{"X-Bar": {"baz"}}) rw.EXPECT().Header().Return(header).Times(2) @@ -121,11 +122,11 @@ func TestWriteAuthorizeResponse(t *testing.T) { expect: func() { expectedUrl, err := url.Parse("https://foobar.com/?foo=bar&bar=b%2Baz&scope=a+b") assert.Nil(t, err) - actualUrl, err := url.Parse(header.Get("Location")) + actualUrl, err := url.Parse(header.Get(consts.HeaderLocation)) assert.Nil(t, err) assert.Equal(t, expectedUrl.Query(), actualUrl.Query()) - assert.Equal(t, "no-cache", header.Get("Pragma")) - assert.Equal(t, "no-store", header.Get("Cache-Control")) + assert.Equal(t, consts.PragmaNoCache, header.Get(consts.HeaderPragma)) + assert.Equal(t, consts.CacheControlNoStore, header.Get(consts.HeaderCacheControl)) assert.Equal(t, "baz", header.Get("X-Bar")) }, }, @@ -134,7 +135,7 @@ func TestWriteAuthorizeResponse(t *testing.T) { redir, _ := url.Parse("https://foobar.com/?foo=bar") ar.EXPECT().GetRedirectURI().Return(redir) ar.EXPECT().GetResponseMode().Return(ResponseModeFragment) - resp.EXPECT().GetParameters().Return(url.Values{"scope": {"api:*"}}) + resp.EXPECT().GetParameters().Return(url.Values{consts.FormParameterScope: {"api:*"}}) resp.EXPECT().GetHeader().Return(http.Header{"X-Bar": {"baz"}}) rw.EXPECT().Header().Return(header).Times(2) @@ -142,10 +143,10 @@ func TestWriteAuthorizeResponse(t *testing.T) { }, expect: func() { assert.Equal(t, http.Header{ - "X-Bar": {"baz"}, - "Location": {"https://foobar.com/?foo=bar#scope=api%3A%2A"}, - "Cache-Control": []string{"no-store"}, - "Pragma": []string{"no-cache"}, + "X-Bar": {"baz"}, + consts.HeaderLocation: {"https://foobar.com/?foo=bar#scope=api%3A%2A"}, + consts.HeaderCacheControl: []string{consts.CacheControlNoStore}, + consts.HeaderPragma: []string{consts.PragmaNoCache}, }, header) }, }, @@ -162,9 +163,9 @@ func TestWriteAuthorizeResponse(t *testing.T) { }, expect: func() { assert.Equal(t, http.Header{ - "Location": {"https://foobar.com/?foo=bar#qux=quux"}, - "Cache-Control": []string{"no-store"}, - "Pragma": []string{"no-cache"}, + consts.HeaderLocation: {"https://foobar.com/?foo=bar#qux=quux"}, + consts.HeaderCacheControl: []string{consts.CacheControlNoStore}, + consts.HeaderPragma: []string{consts.PragmaNoCache}, }, header) }, }, @@ -173,7 +174,7 @@ func TestWriteAuthorizeResponse(t *testing.T) { redir, _ := url.Parse("https://foobar.com/?foo=bar") ar.EXPECT().GetRedirectURI().Return(redir) ar.EXPECT().GetResponseMode().Return(ResponseModeFragment) - resp.EXPECT().GetParameters().Return(url.Values{"state": {"{\"a\":\"b=c&d=e\"}"}}) + resp.EXPECT().GetParameters().Return(url.Values{consts.FormParameterState: {"{\"a\":\"b=c&d=e\"}"}}) resp.EXPECT().GetHeader().Return(http.Header{}) rw.EXPECT().Header().Return(header).Times(2) @@ -181,9 +182,9 @@ func TestWriteAuthorizeResponse(t *testing.T) { }, expect: func() { assert.Equal(t, http.Header{ - "Location": {"https://foobar.com/?foo=bar#state=%7B%22a%22%3A%22b%3Dc%26d%3De%22%7D"}, - "Cache-Control": []string{"no-store"}, - "Pragma": []string{"no-cache"}, + consts.HeaderLocation: {"https://foobar.com/?foo=bar#state=%7B%22a%22%3A%22b%3Dc%26d%3De%22%7D"}, + consts.HeaderCacheControl: []string{consts.CacheControlNoStore}, + consts.HeaderPragma: []string{consts.PragmaNoCache}, }, header) }, }, @@ -193,13 +194,13 @@ func TestWriteAuthorizeResponse(t *testing.T) { ar.EXPECT().GetRedirectURI().Return(redir) ar.EXPECT().GetResponseMode().Return(ResponseModeFormPost) resp.EXPECT().GetHeader().Return(http.Header{"X-Bar": {"baz"}}) - resp.EXPECT().GetParameters().Return(url.Values{"code": {"poz65kqoneu"}, "state": {"qm6dnsrn"}}) + resp.EXPECT().GetParameters().Return(url.Values{consts.FormParameterAuthorizationCode: {"poz65kqoneu"}, consts.FormParameterState: {"qm6dnsrn"}}) rw.EXPECT().Header().Return(header).AnyTimes() rw.EXPECT().Write(gomock.Any()).AnyTimes() }, expect: func() { - assert.Equal(t, "text/html;charset=UTF-8", header.Get("Content-Type")) + assert.Equal(t, consts.ContentTypeTextHTML, header.Get(consts.HeaderContentType)) }, }, } { diff --git a/client_authentication.go b/client_authentication.go index a9606e8b..0571c63a 100644 --- a/client_authentication.go +++ b/client_authentication.go @@ -15,10 +15,10 @@ import ( "strings" "time" - "authelia.com/provider/oauth2/internal/consts" "github.com/go-jose/go-jose/v3" "github.com/pkg/errors" + "authelia.com/provider/oauth2/internal/consts" "authelia.com/provider/oauth2/internal/errorsx" "authelia.com/provider/oauth2/token/jwt" ) @@ -305,7 +305,7 @@ func clientCredentialsFromRequest(r *http.Request, form url.Values) (id, secret } func clientCredentialsFromBasicAuth(r *http.Request) (id, secret string, ok bool, err error) { - auth := r.Header.Get("Authorization") + auth := r.Header.Get(consts.HeaderAuthorization) if auth == "" { return "", "", false, nil diff --git a/client_authentication_test.go b/client_authentication_test.go index 05f6cc49..2e753047 100644 --- a/client_authentication_test.go +++ b/client_authentication_test.go @@ -23,6 +23,7 @@ import ( "github.com/stretchr/testify/require" . "authelia.com/provider/oauth2" + "authelia.com/provider/oauth2/internal/consts" "authelia.com/provider/oauth2/internal/gen" "authelia.com/provider/oauth2/storage" "authelia.com/provider/oauth2/token/jwt" @@ -62,15 +63,13 @@ func mustGenerateNoneAssertion(t *testing.T, claims jwt.MapClaims, key *rsa.Priv func clientBasicAuthHeader(clientID, clientSecret string) http.Header { creds := clientID + ":" + clientSecret return http.Header{ - "Authorization": { + consts.HeaderAuthorization: { "Basic " + base64.StdEncoding.EncodeToString([]byte(creds)), }, } } func TestAuthenticateClient(t *testing.T) { - const at = "urn:ietf:params:oauth:client-assertion-type:jwt-bearer" - hasher := &BCrypt{Config: &Config{HashCost: 6}} provider := &Fosite{ Store: storage.NewMemoryStore(), @@ -262,27 +261,27 @@ func TestAuthenticateClient(t *testing.T) { d: "should fail because client id is not valid", client: &DefaultOpenIDConnectClient{DefaultClient: &DefaultClient{ID: "foo", Secret: barSecret}, TokenEndpointAuthMethod: "client_secret_basic"}, form: url.Values{}, - r: &http.Request{Header: http.Header{"Authorization": {"Basic " + base64.StdEncoding.EncodeToString([]byte("%%%%%%:foo"))}}}, + r: &http.Request{Header: http.Header{consts.HeaderAuthorization: {"Basic " + base64.StdEncoding.EncodeToString([]byte("%%%%%%:foo"))}}}, expectErr: ErrInvalidClient, }, { d: "should fail because client secret is not valid", client: &DefaultOpenIDConnectClient{DefaultClient: &DefaultClient{ID: "foo", Secret: barSecret}, TokenEndpointAuthMethod: "client_secret_basic"}, form: url.Values{}, - r: &http.Request{Header: http.Header{"Authorization": {"Basic " + base64.StdEncoding.EncodeToString([]byte("foo:%%%%%%%"))}}}, + r: &http.Request{Header: http.Header{consts.HeaderAuthorization: {"Basic " + base64.StdEncoding.EncodeToString([]byte("foo:%%%%%%%"))}}}, expectErr: ErrInvalidClient, }, { d: "should fail because client is confidential and id does not exist in header", client: &DefaultOpenIDConnectClient{DefaultClient: &DefaultClient{ID: "bar", Secret: barSecret}, TokenEndpointAuthMethod: "client_secret_basic"}, form: url.Values{}, - r: &http.Request{Header: http.Header{"Authorization": {"Basic " + base64.StdEncoding.EncodeToString([]byte("foo:bar"))}}}, + r: &http.Request{Header: http.Header{consts.HeaderAuthorization: {"Basic " + base64.StdEncoding.EncodeToString([]byte("foo:bar"))}}}, expectErr: ErrInvalidClient, }, { d: "should fail because client_assertion but client_assertion is missing", client: &DefaultOpenIDConnectClient{DefaultClient: &DefaultClient{ID: "foo", Secret: barSecret}, TokenEndpointAuthMethod: "private_key_jwt"}, - form: url.Values{"client_id": []string{"foo"}, "client_assertion_type": []string{at}}, + form: url.Values{"client_id": []string{"foo"}, "client_assertion_type": []string{consts.ClientAssertionTypeJWTBearer}}, r: new(http.Request), expectErr: ErrInvalidRequest, }, @@ -297,36 +296,36 @@ func TestAuthenticateClient(t *testing.T) { d: "should pass with proper RSA assertion when JWKs are set within the client and client_id is not set in the request", client: &DefaultOpenIDConnectClient{DefaultClient: &DefaultClient{ID: "bar", Secret: barSecret}, JSONWebKeys: rsaJwks, TokenEndpointAuthMethod: "private_key_jwt"}, form: url.Values{"client_assertion": {mustGenerateRSAAssertion(t, jwt.MapClaims{ - "sub": "bar", - "exp": time.Now().Add(time.Hour).Unix(), - "iss": "bar", - "jti": "12345", - "aud": "token-url", - }, rsaKey, "kid-foo")}, "client_assertion_type": []string{at}}, + consts.ClaimSubject: "bar", + consts.ClaimExpirationTime: time.Now().Add(time.Hour).Unix(), + consts.ClaimIssuer: "bar", + consts.ClaimJWTID: "12345", + consts.ClaimAudience: "token-url", + }, rsaKey, "kid-foo")}, "client_assertion_type": []string{consts.ClientAssertionTypeJWTBearer}}, r: new(http.Request), }, { d: "should pass with proper ECDSA assertion when JWKs are set within the client and client_id is not set in the request", client: &DefaultOpenIDConnectClient{DefaultClient: &DefaultClient{ID: "bar", Secret: barSecret}, JSONWebKeys: ecdsaJwks, TokenEndpointAuthMethod: "private_key_jwt", TokenEndpointAuthSigningAlgorithm: "ES256"}, form: url.Values{"client_assertion": {mustGenerateECDSAAssertion(t, jwt.MapClaims{ - "sub": "bar", - "exp": time.Now().Add(time.Hour).Unix(), - "iss": "bar", - "jti": "12345", - "aud": "token-url", - }, ecdsaKey, "kid-foo")}, "client_assertion_type": []string{at}}, + consts.ClaimSubject: "bar", + consts.ClaimExpirationTime: time.Now().Add(time.Hour).Unix(), + consts.ClaimIssuer: "bar", + consts.ClaimJWTID: "12345", + consts.ClaimAudience: "token-url", + }, ecdsaKey, "kid-foo")}, "client_assertion_type": []string{consts.ClientAssertionTypeJWTBearer}}, r: new(http.Request), }, { d: "should fail because RSA assertion is used, but ECDSA assertion is required", client: &DefaultOpenIDConnectClient{DefaultClient: &DefaultClient{ID: "bar", Secret: barSecret}, JSONWebKeys: ecdsaJwks, TokenEndpointAuthMethod: "private_key_jwt", TokenEndpointAuthSigningAlgorithm: "ES256"}, form: url.Values{"client_assertion": {mustGenerateRSAAssertion(t, jwt.MapClaims{ - "sub": "bar", - "exp": time.Now().Add(time.Hour).Unix(), - "iss": "bar", - "jti": "12345", - "aud": "token-url", - }, rsaKey, "kid-foo")}, "client_assertion_type": []string{at}}, + consts.ClaimSubject: "bar", + consts.ClaimExpirationTime: time.Now().Add(time.Hour).Unix(), + consts.ClaimIssuer: "bar", + consts.ClaimJWTID: "12345", + consts.ClaimAudience: "token-url", + }, rsaKey, "kid-foo")}, "client_assertion_type": []string{consts.ClientAssertionTypeJWTBearer}}, r: new(http.Request), expectErr: ErrInvalidClient, }, @@ -334,12 +333,12 @@ func TestAuthenticateClient(t *testing.T) { d: "should fail because token auth method is not private_key_jwt, but client_secret_jwt", client: &DefaultOpenIDConnectClient{DefaultClient: &DefaultClient{ID: "bar", Secret: barSecret}, JSONWebKeys: rsaJwks, TokenEndpointAuthMethod: "client_secret_jwt"}, form: url.Values{"client_assertion": {mustGenerateRSAAssertion(t, jwt.MapClaims{ - "sub": "bar", - "exp": time.Now().Add(time.Hour).Unix(), - "iss": "bar", - "jti": "12345", - "aud": "token-url", - }, rsaKey, "kid-foo")}, "client_assertion_type": []string{at}}, + consts.ClaimSubject: "bar", + consts.ClaimExpirationTime: time.Now().Add(time.Hour).Unix(), + consts.ClaimIssuer: "bar", + consts.ClaimJWTID: "12345", + consts.ClaimAudience: "token-url", + }, rsaKey, "kid-foo")}, "client_assertion_type": []string{consts.ClientAssertionTypeJWTBearer}}, r: new(http.Request), expectErr: ErrInvalidClient, }, @@ -347,12 +346,12 @@ func TestAuthenticateClient(t *testing.T) { d: "should fail because token auth method is not private_key_jwt, but none", client: &DefaultOpenIDConnectClient{DefaultClient: &DefaultClient{ID: "bar", Secret: barSecret}, JSONWebKeys: rsaJwks, TokenEndpointAuthMethod: "none"}, form: url.Values{"client_assertion": {mustGenerateRSAAssertion(t, jwt.MapClaims{ - "sub": "bar", - "exp": time.Now().Add(time.Hour).Unix(), - "iss": "bar", - "jti": "12345", - "aud": "token-url", - }, rsaKey, "kid-foo")}, "client_assertion_type": []string{at}}, + consts.ClaimSubject: "bar", + consts.ClaimExpirationTime: time.Now().Add(time.Hour).Unix(), + consts.ClaimIssuer: "bar", + consts.ClaimJWTID: "12345", + consts.ClaimAudience: "token-url", + }, rsaKey, "kid-foo")}, "client_assertion_type": []string{consts.ClientAssertionTypeJWTBearer}}, r: new(http.Request), expectErr: ErrInvalidClient, }, @@ -360,12 +359,12 @@ func TestAuthenticateClient(t *testing.T) { d: "should fail because token auth method is not private_key_jwt, but client_secret_post", client: &DefaultOpenIDConnectClient{DefaultClient: &DefaultClient{ID: "bar", Secret: barSecret}, JSONWebKeys: rsaJwks, TokenEndpointAuthMethod: "client_secret_post"}, form: url.Values{"client_assertion": {mustGenerateRSAAssertion(t, jwt.MapClaims{ - "sub": "bar", - "exp": time.Now().Add(time.Hour).Unix(), - "iss": "bar", - "jti": "12345", - "aud": "token-url", - }, rsaKey, "kid-foo")}, "client_assertion_type": []string{at}}, + consts.ClaimSubject: "bar", + consts.ClaimExpirationTime: time.Now().Add(time.Hour).Unix(), + consts.ClaimIssuer: "bar", + consts.ClaimJWTID: "12345", + consts.ClaimAudience: "token-url", + }, rsaKey, "kid-foo")}, "client_assertion_type": []string{consts.ClientAssertionTypeJWTBearer}}, r: new(http.Request), expectErr: ErrInvalidClient, }, @@ -373,12 +372,12 @@ func TestAuthenticateClient(t *testing.T) { d: "should fail because token auth method is not private_key_jwt, but client_secret_basic", client: &DefaultOpenIDConnectClient{DefaultClient: &DefaultClient{ID: "bar", Secret: barSecret}, JSONWebKeys: rsaJwks, TokenEndpointAuthMethod: "client_secret_basic"}, form: url.Values{"client_assertion": {mustGenerateRSAAssertion(t, jwt.MapClaims{ - "sub": "bar", - "exp": time.Now().Add(time.Hour).Unix(), - "iss": "bar", - "jti": "12345", - "aud": "token-url", - }, rsaKey, "kid-foo")}, "client_assertion_type": []string{at}}, + consts.ClaimSubject: "bar", + consts.ClaimExpirationTime: time.Now().Add(time.Hour).Unix(), + consts.ClaimIssuer: "bar", + consts.ClaimJWTID: "12345", + consts.ClaimAudience: "token-url", + }, rsaKey, "kid-foo")}, "client_assertion_type": []string{consts.ClientAssertionTypeJWTBearer}}, r: new(http.Request), expectErr: ErrInvalidClient, }, @@ -386,12 +385,12 @@ func TestAuthenticateClient(t *testing.T) { d: "should fail because token auth method is not private_key_jwt, but foobar", client: &DefaultOpenIDConnectClient{DefaultClient: &DefaultClient{ID: "bar", Secret: barSecret}, JSONWebKeys: rsaJwks, TokenEndpointAuthMethod: "foobar"}, form: url.Values{"client_assertion": {mustGenerateRSAAssertion(t, jwt.MapClaims{ - "sub": "bar", - "exp": time.Now().Add(time.Hour).Unix(), - "iss": "bar", - "jti": "12345", - "aud": "token-url", - }, rsaKey, "kid-foo")}, "client_assertion_type": []string{at}}, + consts.ClaimSubject: "bar", + consts.ClaimExpirationTime: time.Now().Add(time.Hour).Unix(), + consts.ClaimIssuer: "bar", + consts.ClaimJWTID: "12345", + consts.ClaimAudience: "token-url", + }, rsaKey, "kid-foo")}, "client_assertion_type": []string{consts.ClientAssertionTypeJWTBearer}}, r: new(http.Request), expectErr: ErrInvalidClient, }, @@ -399,24 +398,24 @@ func TestAuthenticateClient(t *testing.T) { d: "should pass with proper assertion when JWKs are set within the client and client_id is not set in the request (aud is array)", client: &DefaultOpenIDConnectClient{DefaultClient: &DefaultClient{ID: "bar", Secret: barSecret}, JSONWebKeys: rsaJwks, TokenEndpointAuthMethod: "private_key_jwt"}, form: url.Values{"client_assertion": {mustGenerateRSAAssertion(t, jwt.MapClaims{ - "sub": "bar", - "exp": time.Now().Add(time.Hour).Unix(), - "iss": "bar", - "jti": "12345", - "aud": []string{"token-url-2", "token-url"}, - }, rsaKey, "kid-foo")}, "client_assertion_type": []string{at}}, + consts.ClaimSubject: "bar", + consts.ClaimExpirationTime: time.Now().Add(time.Hour).Unix(), + consts.ClaimIssuer: "bar", + consts.ClaimJWTID: "12345", + consts.ClaimAudience: []string{"token-url-2", "token-url"}, + }, rsaKey, "kid-foo")}, "client_assertion_type": []string{consts.ClientAssertionTypeJWTBearer}}, r: new(http.Request), }, { d: "should fail because audience (array) does not match token url", client: &DefaultOpenIDConnectClient{DefaultClient: &DefaultClient{ID: "bar", Secret: barSecret}, JSONWebKeys: rsaJwks, TokenEndpointAuthMethod: "private_key_jwt"}, form: url.Values{"client_assertion": {mustGenerateRSAAssertion(t, jwt.MapClaims{ - "sub": "bar", - "exp": time.Now().Add(time.Hour).Unix(), - "iss": "bar", - "jti": "12345", - "aud": []string{"token-url-1", "token-url-2"}, - }, rsaKey, "kid-foo")}, "client_assertion_type": []string{at}}, + consts.ClaimSubject: "bar", + consts.ClaimExpirationTime: time.Now().Add(time.Hour).Unix(), + consts.ClaimIssuer: "bar", + consts.ClaimJWTID: "12345", + consts.ClaimAudience: []string{"token-url-1", "token-url-2"}, + }, rsaKey, "kid-foo")}, "client_assertion_type": []string{consts.ClientAssertionTypeJWTBearer}}, r: new(http.Request), expectErr: ErrInvalidClient, }, @@ -424,24 +423,24 @@ func TestAuthenticateClient(t *testing.T) { d: "should pass with proper assertion when JWKs are set within the client", client: &DefaultOpenIDConnectClient{DefaultClient: &DefaultClient{ID: "bar", Secret: barSecret}, JSONWebKeys: rsaJwks, TokenEndpointAuthMethod: "private_key_jwt"}, form: url.Values{"client_id": []string{"bar"}, "client_assertion": {mustGenerateRSAAssertion(t, jwt.MapClaims{ - "sub": "bar", - "exp": time.Now().Add(time.Hour).Unix(), - "iss": "bar", - "jti": "12345", - "aud": "token-url", - }, rsaKey, "kid-foo")}, "client_assertion_type": []string{at}}, + consts.ClaimSubject: "bar", + consts.ClaimExpirationTime: time.Now().Add(time.Hour).Unix(), + consts.ClaimIssuer: "bar", + consts.ClaimJWTID: "12345", + consts.ClaimAudience: "token-url", + }, rsaKey, "kid-foo")}, "client_assertion_type": []string{consts.ClientAssertionTypeJWTBearer}}, r: new(http.Request), }, { d: "should fail because JWT algorithm is HS256", client: &DefaultOpenIDConnectClient{DefaultClient: &DefaultClient{ID: "bar", Secret: barSecret}, JSONWebKeys: rsaJwks, TokenEndpointAuthMethod: "private_key_jwt"}, form: url.Values{"client_id": []string{"bar"}, "client_assertion": {mustGenerateHSAssertion(t, jwt.MapClaims{ - "sub": "bar", - "exp": time.Now().Add(time.Hour).Unix(), - "iss": "bar", - "jti": "12345", - "aud": "token-url", - }, rsaKey, "kid-foo")}, "client_assertion_type": []string{at}}, + consts.ClaimSubject: "bar", + consts.ClaimExpirationTime: time.Now().Add(time.Hour).Unix(), + consts.ClaimIssuer: "bar", + consts.ClaimJWTID: "12345", + consts.ClaimAudience: "token-url", + }, rsaKey, "kid-foo")}, "client_assertion_type": []string{consts.ClientAssertionTypeJWTBearer}}, r: new(http.Request), expectErr: ErrInvalidClient, }, @@ -449,12 +448,12 @@ func TestAuthenticateClient(t *testing.T) { d: "should fail because JWT algorithm is none", client: &DefaultOpenIDConnectClient{DefaultClient: &DefaultClient{ID: "bar", Secret: barSecret}, JSONWebKeys: rsaJwks, TokenEndpointAuthMethod: "private_key_jwt"}, form: url.Values{"client_id": []string{"bar"}, "client_assertion": {mustGenerateNoneAssertion(t, jwt.MapClaims{ - "sub": "bar", - "exp": time.Now().Add(time.Hour).Unix(), - "iss": "bar", - "jti": "12345", - "aud": "token-url", - }, rsaKey, "kid-foo")}, "client_assertion_type": []string{at}}, + consts.ClaimSubject: "bar", + consts.ClaimExpirationTime: time.Now().Add(time.Hour).Unix(), + consts.ClaimIssuer: "bar", + consts.ClaimJWTID: "12345", + consts.ClaimAudience: "token-url", + }, rsaKey, "kid-foo")}, "client_assertion_type": []string{consts.ClientAssertionTypeJWTBearer}}, r: new(http.Request), expectErr: ErrInvalidClient, }, @@ -462,24 +461,24 @@ func TestAuthenticateClient(t *testing.T) { d: "should pass with proper assertion when JWKs URI is set", client: &DefaultOpenIDConnectClient{DefaultClient: &DefaultClient{ID: "bar", Secret: barSecret}, JSONWebKeysURI: ts.URL, TokenEndpointAuthMethod: "private_key_jwt"}, form: url.Values{"client_id": []string{"bar"}, "client_assertion": {mustGenerateRSAAssertion(t, jwt.MapClaims{ - "sub": "bar", - "exp": time.Now().Add(time.Hour).Unix(), - "iss": "bar", - "jti": "12345", - "aud": "token-url", - }, rsaKey, "kid-foo")}, "client_assertion_type": []string{at}}, + consts.ClaimSubject: "bar", + consts.ClaimExpirationTime: time.Now().Add(time.Hour).Unix(), + consts.ClaimIssuer: "bar", + consts.ClaimJWTID: "12345", + consts.ClaimAudience: "token-url", + }, rsaKey, "kid-foo")}, "client_assertion_type": []string{consts.ClientAssertionTypeJWTBearer}}, r: new(http.Request), }, { d: "should fail because client_assertion sub does not match client", client: &DefaultOpenIDConnectClient{DefaultClient: &DefaultClient{ID: "bar", Secret: barSecret}, JSONWebKeys: rsaJwks, TokenEndpointAuthMethod: "private_key_jwt"}, form: url.Values{"client_id": []string{"bar"}, "client_assertion": {mustGenerateRSAAssertion(t, jwt.MapClaims{ - "sub": "not-bar", - "exp": time.Now().Add(time.Hour).Unix(), - "iss": "bar", - "jti": "12345", - "aud": "token-url", - }, rsaKey, "kid-foo")}, "client_assertion_type": []string{at}}, + consts.ClaimSubject: "not-bar", + consts.ClaimExpirationTime: time.Now().Add(time.Hour).Unix(), + consts.ClaimIssuer: "bar", + consts.ClaimJWTID: "12345", + consts.ClaimAudience: "token-url", + }, rsaKey, "kid-foo")}, "client_assertion_type": []string{consts.ClientAssertionTypeJWTBearer}}, r: new(http.Request), expectErr: ErrInvalidClient, }, @@ -487,12 +486,12 @@ func TestAuthenticateClient(t *testing.T) { d: "should fail because client_assertion iss does not match client", client: &DefaultOpenIDConnectClient{DefaultClient: &DefaultClient{ID: "bar", Secret: barSecret}, JSONWebKeys: rsaJwks, TokenEndpointAuthMethod: "private_key_jwt"}, form: url.Values{"client_id": []string{"bar"}, "client_assertion": {mustGenerateRSAAssertion(t, jwt.MapClaims{ - "sub": "bar", - "exp": time.Now().Add(time.Hour).Unix(), - "iss": "not-bar", - "jti": "12345", - "aud": "token-url", - }, rsaKey, "kid-foo")}, "client_assertion_type": []string{at}}, + consts.ClaimSubject: "bar", + consts.ClaimExpirationTime: time.Now().Add(time.Hour).Unix(), + consts.ClaimIssuer: "not-bar", + consts.ClaimJWTID: "12345", + consts.ClaimAudience: "token-url", + }, rsaKey, "kid-foo")}, "client_assertion_type": []string{consts.ClientAssertionTypeJWTBearer}}, r: new(http.Request), expectErr: ErrInvalidClient, }, @@ -500,11 +499,11 @@ func TestAuthenticateClient(t *testing.T) { d: "should fail because client_assertion jti is not set", client: &DefaultOpenIDConnectClient{DefaultClient: &DefaultClient{ID: "bar", Secret: barSecret}, JSONWebKeys: rsaJwks, TokenEndpointAuthMethod: "private_key_jwt"}, form: url.Values{"client_id": []string{"bar"}, "client_assertion": {mustGenerateRSAAssertion(t, jwt.MapClaims{ - "sub": "bar", - "exp": time.Now().Add(time.Hour).Unix(), - "iss": "bar", - "aud": "token-url", - }, rsaKey, "kid-foo")}, "client_assertion_type": []string{at}}, + consts.ClaimSubject: "bar", + consts.ClaimExpirationTime: time.Now().Add(time.Hour).Unix(), + consts.ClaimIssuer: "bar", + consts.ClaimAudience: "token-url", + }, rsaKey, "kid-foo")}, "client_assertion_type": []string{consts.ClientAssertionTypeJWTBearer}}, r: new(http.Request), expectErr: ErrInvalidClient, }, @@ -512,12 +511,12 @@ func TestAuthenticateClient(t *testing.T) { d: "should fail because client_assertion aud is not set", client: &DefaultOpenIDConnectClient{DefaultClient: &DefaultClient{ID: "bar", Secret: barSecret}, JSONWebKeys: rsaJwks, TokenEndpointAuthMethod: "private_key_jwt"}, form: url.Values{"client_id": []string{"bar"}, "client_assertion": {mustGenerateRSAAssertion(t, jwt.MapClaims{ - "sub": "bar", - "exp": time.Now().Add(time.Hour).Unix(), - "iss": "bar", - "jti": "12345", - "aud": "not-token-url", - }, rsaKey, "kid-foo")}, "client_assertion_type": []string{at}}, + consts.ClaimSubject: "bar", + consts.ClaimExpirationTime: time.Now().Add(time.Hour).Unix(), + consts.ClaimIssuer: "bar", + consts.ClaimJWTID: "12345", + consts.ClaimAudience: "not-token-url", + }, rsaKey, "kid-foo")}, "client_assertion_type": []string{consts.ClientAssertionTypeJWTBearer}}, r: new(http.Request), expectErr: ErrInvalidClient, }, @@ -550,8 +549,6 @@ func TestAuthenticateClient(t *testing.T) { } func TestAuthenticateClientTwice(t *testing.T) { - const at = "urn:ietf:params:oauth:client-assertion-type:jwt-bearer" - key := gen.MustRSAKey() client := &DefaultOpenIDConnectClient{ DefaultClient: &DefaultClient{ @@ -562,12 +559,12 @@ func TestAuthenticateClientTwice(t *testing.T) { Keys: []jose.JSONWebKey{ { KeyID: "kid-foo", - Use: "sig", + Use: consts.JSONWebTokenUseSignature, Key: &key.PublicKey, }, }, }, - TokenEndpointAuthMethod: "private_key_jwt", + TokenEndpointAuthMethod: consts.ClientAuthMethodPrivateKeyJWT, } store := storage.NewMemoryStore() store.Clients[client.ID] = client @@ -583,12 +580,12 @@ func TestAuthenticateClientTwice(t *testing.T) { } formValues := url.Values{"client_id": []string{"bar"}, "client_assertion": {mustGenerateRSAAssertion(t, jwt.MapClaims{ - "sub": "bar", - "exp": time.Now().Add(time.Hour).Unix(), - "iss": "bar", - "jti": "12345", - "aud": "token-url", - }, key, "kid-foo")}, "client_assertion_type": []string{at}} + consts.ClaimSubject: "bar", + consts.ClaimExpirationTime: time.Now().Add(time.Hour).Unix(), + consts.ClaimIssuer: "bar", + consts.ClaimJWTID: "12345", + consts.ClaimAudience: "token-url", + }, key, "kid-foo")}, consts.FormParameterClientAssertionType: []string{consts.ClientAssertionTypeJWTBearer}} c, err := provider.AuthenticateClient(context.TODO(), new(http.Request), formValues) require.NoError(t, err, "%#v", err) diff --git a/config_default.go b/config_default.go index 581db6c7..b6fb18a2 100644 --- a/config_default.go +++ b/config_default.go @@ -10,14 +10,15 @@ import ( "net/url" "time" - "github.com/hashicorp/go-retryablehttp" + retryablehttp "github.com/hashicorp/go-retryablehttp" "authelia.com/provider/oauth2/i18n" + "authelia.com/provider/oauth2/internal/consts" "authelia.com/provider/oauth2/token/jwt" ) const ( - defaultPARPrefix = "urn:ietf:params:oauth:request_uri:" + defaultPARPrefix = consts.PrefixRequestURI defaultPARContextLifetime = 5 * time.Minute ) @@ -430,7 +431,7 @@ func (c *Config) GetRedirectSecureChecker(_ context.Context) func(context.Contex // GetRefreshTokenScopes returns which scopes will provide refresh tokens. func (c *Config) GetRefreshTokenScopes(_ context.Context) []string { if c.RefreshTokenScopes == nil { - return []string{"offline", "offline_access"} + return []string{consts.ScopeOffline, consts.ScopeOfflineAccess} } return c.RefreshTokenScopes } diff --git a/go.sum b/go.sum index 00cfb9a5..56b8bc28 100644 --- a/go.sum +++ b/go.sum @@ -67,8 +67,6 @@ github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peK github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= -github.com/oleiade/reflections v1.0.1 h1:D1XO3LVEYroYskEsoSiGItp9RUxG6jWnCVvrqH0HHQM= -github.com/oleiade/reflections v1.0.1/go.mod h1:rdFxbxq4QXVZWj0F+e9jqjDkc7dbp97vkRixKo2JR60= github.com/parnurzeal/gorequest v0.2.16 h1:T/5x+/4BT+nj+3eSknXmCTnEVGSzFzPGdpqmUVVZXHQ= github.com/parnurzeal/gorequest v0.2.16/go.mod h1:3Kh2QUMJoqw3icWAecsyzkpY7UzRfDhbRdTjtNwNiUE= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= diff --git a/handler/oauth2/flow_authorize_code_auth_test.go b/handler/oauth2/flow_authorize_code_auth_test.go index 12ce622a..d94e1e59 100644 --- a/handler/oauth2/flow_authorize_code_auth_test.go +++ b/handler/oauth2/flow_authorize_code_auth_test.go @@ -10,11 +10,11 @@ import ( "testing" "time" - "authelia.com/provider/oauth2/internal/consts" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "authelia.com/provider/oauth2" + "authelia.com/provider/oauth2/internal/consts" "authelia.com/provider/oauth2/storage" ) diff --git a/handler/oauth2/flow_authorize_code_token_test.go b/handler/oauth2/flow_authorize_code_token_test.go index 819b7d1f..6a6b598a 100644 --- a/handler/oauth2/flow_authorize_code_token_test.go +++ b/handler/oauth2/flow_authorize_code_token_test.go @@ -89,7 +89,7 @@ func TestAuthorizeCode_PopulateTokenEndpointResponse(t *testing.T) { Client: &oauth2.DefaultClient{ GrantTypes: oauth2.Arguments{consts.GrantTypeAuthorizationCode, consts.GrantTypeRefreshToken}, }, - GrantedScope: oauth2.Arguments{"foo", "offline"}, + GrantedScope: oauth2.Arguments{"foo", consts.ScopeOffline}, Session: &oauth2.DefaultSession{}, RequestedAt: time.Now().UTC(), }, @@ -205,7 +205,7 @@ func TestAuthorizeCode_PopulateTokenEndpointResponse(t *testing.T) { ScopeStrategy: oauth2.HierarchicScopeStrategy, AudienceMatchingStrategy: oauth2.DefaultAudienceMatchingStrategy, AccessTokenLifespan: time.Minute, - RefreshTokenScopes: []string{"offline"}, + RefreshTokenScopes: []string{consts.ScopeOffline}, } h = AuthorizeExplicitGrantHandler{ CoreStorage: store, @@ -294,7 +294,7 @@ func TestAuthorizeCode_HandleTokenEndpointRequest(t *testing.T) { setup: func(t *testing.T, areq *oauth2.AccessRequest, authreq *oauth2.AuthorizeRequest) { token, _, err := strategy.GenerateAuthorizeCode(context.TODO(), nil) require.NoError(t, err) - areq.Form = url.Values{"code": {token}} + areq.Form = url.Values{consts.FormParameterAuthorizationCode: {token}} }, expectErr: oauth2.ErrInvalidGrant, }, @@ -356,7 +356,7 @@ func TestAuthorizeCode_HandleTokenEndpointRequest(t *testing.T) { setup: func(t *testing.T, areq *oauth2.AccessRequest, authreq *oauth2.AuthorizeRequest) { token, signature, err := strategy.GenerateAuthorizeCode(context.TODO(), nil) require.NoError(t, err) - areq.Form = url.Values{"code": {token}} + areq.Form = url.Values{consts.FormParameterAuthorizationCode: {token}} require.NoError(t, store.CreateAuthorizeCodeSession(context.TODO(), signature, authreq)) }, @@ -385,7 +385,7 @@ func TestAuthorizeCode_HandleTokenEndpointRequest(t *testing.T) { token, signature, err := strategy.GenerateAuthorizeCode(context.TODO(), nil) require.NoError(t, err) - areq.Form = url.Values{"code": {token}} + areq.Form = url.Values{consts.FormParameterAuthorizationCode: {token}} require.NoError(t, store.CreateAuthorizeCodeSession(context.TODO(), signature, authreq)) }, }, @@ -397,7 +397,7 @@ func TestAuthorizeCode_HandleTokenEndpointRequest(t *testing.T) { Client: &oauth2.DefaultClient{ GrantTypes: oauth2.Arguments{"authorization_code"}, }, - GrantedScope: oauth2.Arguments{"foo", "offline"}, + GrantedScope: oauth2.Arguments{"foo", consts.ScopeOffline}, Session: &oauth2.DefaultSession{}, RequestedAt: time.Now().UTC(), }, @@ -450,14 +450,14 @@ func TestAuthorizeCodeTransactional_HandleTokenEndpointRequest(t *testing.T) { Client: &oauth2.DefaultClient{ GrantTypes: oauth2.Arguments{"authorization_code", "refresh_token"}, }, - GrantedScope: oauth2.Arguments{"offline"}, + GrantedScope: oauth2.Arguments{consts.ScopeOffline}, Session: &oauth2.DefaultSession{}, RequestedAt: time.Now().UTC(), }, } token, _, err := strategy.GenerateAuthorizeCode(context.TODO(), nil) require.NoError(t, err) - request.Form = url.Values{"code": {token}} + request.Form = url.Values{consts.FormParameterAuthorizationCode: {token}} response := oauth2.NewAccessResponse() propagatedContext := context.Background() diff --git a/handler/oauth2/flow_client_credentials_test.go b/handler/oauth2/flow_client_credentials_test.go index ec078041..b22f85b5 100644 --- a/handler/oauth2/flow_client_credentials_test.go +++ b/handler/oauth2/flow_client_credentials_test.go @@ -10,12 +10,12 @@ import ( "testing" "time" - "authelia.com/provider/oauth2/internal/consts" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" "authelia.com/provider/oauth2" "authelia.com/provider/oauth2/internal" + "authelia.com/provider/oauth2/internal/consts" ) func TestClientCredentials_HandleTokenEndpointRequest(t *testing.T) { diff --git a/handler/oauth2/flow_refresh_test.go b/handler/oauth2/flow_refresh_test.go index ba31f8aa..5f14a758 100644 --- a/handler/oauth2/flow_refresh_test.go +++ b/handler/oauth2/flow_refresh_test.go @@ -86,7 +86,7 @@ func TestRefreshFlow_HandleTokenEndpointRequest(t *testing.T) { areq.Form.Add(consts.FormParameterRefreshToken, token) err = store.CreateRefreshTokenSession(context.TODO(), sig, &oauth2.Request{ Client: &oauth2.DefaultClient{ID: ""}, - GrantedScope: []string{"offline"}, + GrantedScope: []string{consts.ScopeOffline}, Session: sess, }) require.NoError(t, err) @@ -100,7 +100,7 @@ func TestRefreshFlow_HandleTokenEndpointRequest(t *testing.T) { areq.Client = &oauth2.DefaultClient{ ID: "foo", GrantTypes: oauth2.Arguments{consts.GrantTypeRefreshToken}, - Scopes: []string{"foo", "bar", "offline"}, + Scopes: []string{"foo", "bar", consts.ScopeOffline}, } token, sig, err := strategy.GenerateRefreshToken(context.TODO(), nil) @@ -109,8 +109,8 @@ func TestRefreshFlow_HandleTokenEndpointRequest(t *testing.T) { areq.Form.Add(consts.FormParameterRefreshToken, token) err = store.CreateRefreshTokenSession(context.TODO(), sig, &oauth2.Request{ Client: areq.Client, - GrantedScope: oauth2.Arguments{"foo", "offline"}, - RequestedScope: oauth2.Arguments{"foo", "bar", "offline"}, + GrantedScope: oauth2.Arguments{"foo", consts.ScopeOffline}, + RequestedScope: oauth2.Arguments{"foo", "bar", consts.ScopeOffline}, Session: expiredSess, Form: url.Values{"foo": []string{"bar"}}, RequestedAt: time.Now().UTC().Add(-time.Hour).Round(time.Hour), @@ -134,8 +134,8 @@ func TestRefreshFlow_HandleTokenEndpointRequest(t *testing.T) { areq.Form.Add(consts.FormParameterRefreshToken, token) err = store.CreateRefreshTokenSession(context.TODO(), sig, &oauth2.Request{ Client: areq.Client, - GrantedScope: oauth2.Arguments{"foo", "offline"}, - RequestedScope: oauth2.Arguments{"foo", "offline"}, + GrantedScope: oauth2.Arguments{"foo", consts.ScopeOffline}, + RequestedScope: oauth2.Arguments{"foo", consts.ScopeOffline}, Session: sess, Form: url.Values{"foo": []string{"bar"}}, RequestedAt: time.Now().UTC().Add(-time.Hour).Round(time.Hour), @@ -151,7 +151,7 @@ func TestRefreshFlow_HandleTokenEndpointRequest(t *testing.T) { areq.Client = &oauth2.DefaultClient{ ID: "foo", GrantTypes: oauth2.Arguments{consts.GrantTypeRefreshToken}, - Scopes: []string{"foo", "bar", "offline"}, + Scopes: []string{"foo", "bar", consts.ScopeOffline}, } token, sig, err := strategy.GenerateRefreshToken(context.TODO(), nil) @@ -160,8 +160,8 @@ func TestRefreshFlow_HandleTokenEndpointRequest(t *testing.T) { areq.Form.Add(consts.FormParameterRefreshToken, token) err = store.CreateRefreshTokenSession(context.TODO(), sig, &oauth2.Request{ Client: areq.Client, - GrantedScope: oauth2.Arguments{"foo", "offline"}, - RequestedScope: oauth2.Arguments{"foo", "bar", "offline"}, + GrantedScope: oauth2.Arguments{"foo", consts.ScopeOffline}, + RequestedScope: oauth2.Arguments{"foo", "bar", consts.ScopeOffline}, Session: sess, Form: url.Values{"foo": []string{"bar"}}, RequestedAt: time.Now().UTC().Add(-time.Hour).Round(time.Hour), @@ -171,8 +171,8 @@ func TestRefreshFlow_HandleTokenEndpointRequest(t *testing.T) { expect: func(t *testing.T) { assert.NotEqual(t, sess, areq.Session) assert.NotEqual(t, time.Now().UTC().Add(-time.Hour).Round(time.Hour), areq.RequestedAt) - assert.Equal(t, oauth2.Arguments{"foo", "offline"}, areq.GrantedScope) - assert.Equal(t, oauth2.Arguments{"foo", "offline"}, areq.RequestedScope) + assert.Equal(t, oauth2.Arguments{"foo", consts.ScopeOffline}, areq.GrantedScope) + assert.Equal(t, oauth2.Arguments{"foo", consts.ScopeOffline}, areq.RequestedScope) assert.NotEqual(t, url.Values{"foo": []string{"bar"}}, areq.Form) assert.Equal(t, time.Now().Add(time.Hour).UTC().Round(time.Second), areq.GetSession().GetExpiresAt(oauth2.AccessToken)) assert.Equal(t, time.Now().Add(time.Hour).UTC().Round(time.Second), areq.GetSession().GetExpiresAt(oauth2.RefreshToken)) @@ -185,7 +185,7 @@ func TestRefreshFlow_HandleTokenEndpointRequest(t *testing.T) { areq.Client = &oauth2.DefaultClient{ ID: "foo", GrantTypes: oauth2.Arguments{"refresh_token"}, - Scopes: []string{"foo", "bar", "baz", "offline"}, + Scopes: []string{"foo", "bar", "baz", consts.ScopeOffline}, } token, sig, err := strategy.GenerateRefreshToken(nil, nil) @@ -195,8 +195,8 @@ func TestRefreshFlow_HandleTokenEndpointRequest(t *testing.T) { areq.Form.Add("scope", "foo bar baz offline") err = store.CreateRefreshTokenSession(nil, sig, &oauth2.Request{ Client: areq.Client, - GrantedScope: oauth2.Arguments{"foo", "bar", "baz", "offline"}, - RequestedScope: oauth2.Arguments{"foo", "bar", "baz", "offline"}, + GrantedScope: oauth2.Arguments{"foo", "bar", "baz", consts.ScopeOffline}, + RequestedScope: oauth2.Arguments{"foo", "bar", "baz", consts.ScopeOffline}, Session: sess, Form: url.Values{"foo": []string{"bar"}}, RequestedAt: time.Now().UTC().Add(-time.Hour).Round(time.Hour), @@ -204,8 +204,8 @@ func TestRefreshFlow_HandleTokenEndpointRequest(t *testing.T) { require.NoError(t, err) }, expect: func(t *testing.T) { - assert.Equal(t, oauth2.Arguments{"foo", "bar", "baz", "offline"}, areq.GrantedScope) - assert.Equal(t, oauth2.Arguments{"foo", "bar", "baz", "offline"}, areq.RequestedScope) + assert.Equal(t, oauth2.Arguments{"foo", "bar", "baz", consts.ScopeOffline}, areq.GrantedScope) + assert.Equal(t, oauth2.Arguments{"foo", "bar", "baz", consts.ScopeOffline}, areq.RequestedScope) }, }, { @@ -215,7 +215,7 @@ func TestRefreshFlow_HandleTokenEndpointRequest(t *testing.T) { areq.Client = &oauth2.DefaultClient{ ID: "foo", GrantTypes: oauth2.Arguments{"refresh_token"}, - Scopes: []string{"foo", "bar", "baz", "offline"}, + Scopes: []string{"foo", "bar", "baz", consts.ScopeOffline}, } token, sig, err := strategy.GenerateRefreshToken(nil, nil) @@ -223,12 +223,12 @@ func TestRefreshFlow_HandleTokenEndpointRequest(t *testing.T) { areq.Form.Add("refresh_token", token) areq.Form.Add("scope", "foo bar offline") - areq.SetRequestedScopes(oauth2.Arguments{"foo", "bar", "offline"}) + areq.SetRequestedScopes(oauth2.Arguments{"foo", "bar", consts.ScopeOffline}) err = store.CreateRefreshTokenSession(nil, sig, &oauth2.Request{ Client: areq.Client, - GrantedScope: oauth2.Arguments{"foo", "bar", "baz", "offline"}, - RequestedScope: oauth2.Arguments{"foo", "bar", "baz", "offline"}, + GrantedScope: oauth2.Arguments{"foo", "bar", "baz", consts.ScopeOffline}, + RequestedScope: oauth2.Arguments{"foo", "bar", "baz", consts.ScopeOffline}, Session: sess, Form: url.Values{"foo": []string{"bar"}}, RequestedAt: time.Now().UTC().Add(-time.Hour).Round(time.Hour), @@ -236,8 +236,8 @@ func TestRefreshFlow_HandleTokenEndpointRequest(t *testing.T) { require.NoError(t, err) }, expect: func(t *testing.T) { - assert.Equal(t, oauth2.Arguments{"foo", "bar", "offline"}, areq.GrantedScope) - assert.Equal(t, oauth2.Arguments{"foo", "bar", "offline"}, areq.RequestedScope) + assert.Equal(t, oauth2.Arguments{"foo", "bar", consts.ScopeOffline}, areq.GrantedScope) + assert.Equal(t, oauth2.Arguments{"foo", "bar", consts.ScopeOffline}, areq.RequestedScope) }, }, { @@ -247,7 +247,7 @@ func TestRefreshFlow_HandleTokenEndpointRequest(t *testing.T) { areq.Client = &oauth2.DefaultClient{ ID: "foo", GrantTypes: oauth2.Arguments{"refresh_token"}, - Scopes: []string{"foo", "bar", "baz", "offline"}, + Scopes: []string{"foo", "bar", "baz", consts.ScopeOffline}, } token, sig, err := strategy.GenerateRefreshToken(nil, nil) @@ -255,12 +255,12 @@ func TestRefreshFlow_HandleTokenEndpointRequest(t *testing.T) { areq.Form.Add("refresh_token", token) areq.Form.Add("scope", "foo bar offline") - areq.SetRequestedScopes(oauth2.Arguments{"foo", "bar", "offline"}) + areq.SetRequestedScopes(oauth2.Arguments{"foo", "bar", consts.ScopeOffline}) err = store.CreateRefreshTokenSession(nil, sig, &oauth2.Request{ Client: areq.Client, - GrantedScope: oauth2.Arguments{"foo", "baz", "offline"}, - RequestedScope: oauth2.Arguments{"foo", "baz", "offline"}, + GrantedScope: oauth2.Arguments{"foo", "baz", consts.ScopeOffline}, + RequestedScope: oauth2.Arguments{"foo", "baz", consts.ScopeOffline}, Session: sess, Form: url.Values{"foo": []string{"bar"}}, RequestedAt: time.Now().UTC().Add(-time.Hour).Round(time.Hour), @@ -277,7 +277,7 @@ func TestRefreshFlow_HandleTokenEndpointRequest(t *testing.T) { DefaultClient: &oauth2.DefaultClient{ ID: "foo", GrantTypes: oauth2.Arguments{consts.GrantTypeRefreshToken}, - Scopes: []string{"foo", "bar", "offline"}, + Scopes: []string{"foo", "bar", consts.ScopeOffline}, }, } @@ -289,8 +289,8 @@ func TestRefreshFlow_HandleTokenEndpointRequest(t *testing.T) { areq.Form.Add(consts.FormParameterRefreshToken, token) err = store.CreateRefreshTokenSession(context.TODO(), sig, &oauth2.Request{ Client: areq.Client, - GrantedScope: oauth2.Arguments{"foo", "offline"}, - RequestedScope: oauth2.Arguments{"foo", "bar", "offline"}, + GrantedScope: oauth2.Arguments{"foo", consts.ScopeOffline}, + RequestedScope: oauth2.Arguments{"foo", "bar", consts.ScopeOffline}, Session: sess, Form: url.Values{"foo": []string{"bar"}}, RequestedAt: time.Now().UTC().Add(-time.Hour).Round(time.Hour), @@ -300,8 +300,8 @@ func TestRefreshFlow_HandleTokenEndpointRequest(t *testing.T) { expect: func(t *testing.T) { assert.NotEqual(t, sess, areq.Session) assert.NotEqual(t, time.Now().UTC().Add(-time.Hour).Round(time.Hour), areq.RequestedAt) - assert.Equal(t, oauth2.Arguments{"foo", "offline"}, areq.GrantedScope) - assert.Equal(t, oauth2.Arguments{"foo", "offline"}, areq.RequestedScope) + assert.Equal(t, oauth2.Arguments{"foo", consts.ScopeOffline}, areq.GrantedScope) + assert.Equal(t, oauth2.Arguments{"foo", consts.ScopeOffline}, areq.RequestedScope) assert.NotEqual(t, url.Values{"foo": []string{"bar"}}, areq.Form) internal.RequireEqualTime(t, time.Now().Add(*internal.TestLifespans.RefreshTokenGrantAccessTokenLifespan).UTC(), areq.GetSession().GetExpiresAt(oauth2.AccessToken), time.Minute) internal.RequireEqualTime(t, time.Now().Add(*internal.TestLifespans.RefreshTokenGrantRefreshTokenLifespan).UTC(), areq.GetSession().GetExpiresAt(oauth2.RefreshToken), time.Minute) diff --git a/handler/oauth2/introspector_test.go b/handler/oauth2/introspector_test.go index 89a0dd33..2d082f2d 100644 --- a/handler/oauth2/introspector_test.go +++ b/handler/oauth2/introspector_test.go @@ -16,6 +16,7 @@ import ( "authelia.com/provider/oauth2" "authelia.com/provider/oauth2/internal" + "authelia.com/provider/oauth2/internal/consts" "authelia.com/provider/oauth2/internal/errorsx" ) @@ -44,7 +45,7 @@ func TestIntrospectToken(t *testing.T) { { description: "should fail because no bearer token set", setup: func() { - httpreq.Header.Set("Authorization", "bearer") + httpreq.Header.Set(consts.HeaderAuthorization, "bearer") chgen.EXPECT().AccessTokenSignature(gomock.Any(), "").Return("") store.EXPECT().GetAccessTokenSession(context.TODO(), "", nil).Return(nil, errors.New("")) chgen.EXPECT().RefreshTokenSignature(gomock.Any(), "").Return("") @@ -55,7 +56,7 @@ func TestIntrospectToken(t *testing.T) { { description: "should fail because retrieval fails", setup: func() { - httpreq.Header.Set("Authorization", "bearer 1234") + httpreq.Header.Set(consts.HeaderAuthorization, "bearer 1234") chgen.EXPECT().AccessTokenSignature(gomock.Any(), "1234").AnyTimes().Return("asdf") store.EXPECT().GetAccessTokenSession(context.TODO(), "asdf", nil).Return(nil, errors.New("")) chgen.EXPECT().RefreshTokenSignature(gomock.Any(), "1234").Return("asdf") diff --git a/handler/oauth2/strategy_jwt_test.go b/handler/oauth2/strategy_jwt_test.go index 806c9a42..d0e777e6 100644 --- a/handler/oauth2/strategy_jwt_test.go +++ b/handler/oauth2/strategy_jwt_test.go @@ -12,11 +12,11 @@ import ( "testing" "time" - "authelia.com/provider/oauth2/internal/consts" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "authelia.com/provider/oauth2" + "authelia.com/provider/oauth2/internal/consts" "authelia.com/provider/oauth2/internal/gen" "authelia.com/provider/oauth2/token/jwt" ) @@ -205,7 +205,7 @@ func TestAccessToken(t *testing.T) { if scopeField == jwt.JWTScopeFieldList || scopeField == jwt.JWTScopeFieldBoth { scope, ok := payload[consts.ClaimScopeNonStandard] require.True(t, ok) - assert.Equal(t, []any{"email", "offline"}, scope) + assert.Equal(t, []any{consts.ScopeEmail, consts.ScopeOffline}, scope) } if scopeField == jwt.JWTScopeFieldString || scopeField == jwt.JWTScopeFieldBoth { scope, ok := payload[consts.ClaimScope] diff --git a/handler/openid/flow_explicit_auth_test.go b/handler/openid/flow_explicit_auth_test.go index f18b1efc..14661544 100644 --- a/handler/openid/flow_explicit_auth_test.go +++ b/handler/openid/flow_explicit_auth_test.go @@ -8,13 +8,13 @@ import ( "fmt" "testing" - "authelia.com/provider/oauth2/internal/consts" "github.com/pkg/errors" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" "authelia.com/provider/oauth2" "authelia.com/provider/oauth2/internal" + "authelia.com/provider/oauth2/internal/consts" "authelia.com/provider/oauth2/internal/gen" "authelia.com/provider/oauth2/token/jwt" ) diff --git a/handler/openid/flow_explicit_token.go b/handler/openid/flow_explicit_token.go index 4e50fe1a..e245f9c2 100644 --- a/handler/openid/flow_explicit_token.go +++ b/handler/openid/flow_explicit_token.go @@ -6,10 +6,10 @@ package openid import ( "context" - "authelia.com/provider/oauth2/internal/consts" "github.com/pkg/errors" "authelia.com/provider/oauth2" + "authelia.com/provider/oauth2/internal/consts" "authelia.com/provider/oauth2/internal/errorsx" ) diff --git a/handler/openid/flow_explicit_token_test.go b/handler/openid/flow_explicit_token_test.go index 102ad478..5edbde08 100644 --- a/handler/openid/flow_explicit_token_test.go +++ b/handler/openid/flow_explicit_token_test.go @@ -9,7 +9,6 @@ import ( "testing" "time" - "authelia.com/provider/oauth2/internal/consts" "github.com/pkg/errors" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -17,6 +16,7 @@ import ( "authelia.com/provider/oauth2" "authelia.com/provider/oauth2/internal" + "authelia.com/provider/oauth2/internal/consts" "authelia.com/provider/oauth2/token/jwt" ) @@ -130,7 +130,7 @@ func TestExplicit_PopulateTokenEndpointResponse(t *testing.T) { } storedReq := oauth2.NewAuthorizeRequest() storedReq.Session = storedSession - storedReq.GrantedScope = oauth2.Arguments{"openid"} + storedReq.GrantedScope = oauth2.Arguments{consts.ScopeOpenID} storedReq.Form.Set("nonce", "1111111111111111") store.EXPECT().GetOpenIDConnectSession(context.TODO(), "foobar", req).Return(storedReq, nil) }, @@ -157,7 +157,7 @@ func TestExplicit_PopulateTokenEndpointResponse(t *testing.T) { } storedReq := oauth2.NewAuthorizeRequest() storedReq.Session = storedSession - storedReq.GrantedScope = oauth2.Arguments{"openid"} + storedReq.GrantedScope = oauth2.Arguments{consts.ScopeOpenID} store.EXPECT().GetOpenIDConnectSession(context.TODO(), "foobar", req).Return(storedReq, nil) }, expectErr: oauth2.ErrServerError, @@ -169,7 +169,7 @@ func TestExplicit_PopulateTokenEndpointResponse(t *testing.T) { req.Form.Set(consts.FormParameterAuthorizationCode, "foobar") storedReq := oauth2.NewAuthorizeRequest() storedReq.Session = nil - storedReq.GrantScope("openid") + storedReq.GrantScope(consts.ScopeOpenID) store.EXPECT().GetOpenIDConnectSession(context.TODO(), "foobar", req).Return(storedReq, nil) }, expectErr: oauth2.ErrServerError, diff --git a/handler/openid/flow_hybrid_test.go b/handler/openid/flow_hybrid_test.go index ec749674..73b2588c 100644 --- a/handler/openid/flow_hybrid_test.go +++ b/handler/openid/flow_hybrid_test.go @@ -140,9 +140,9 @@ func TestHybrid_HandleAuthorizeEndpointRequest(t *testing.T) { areq.Client = &oauth2.DefaultClient{ GrantTypes: oauth2.Arguments{consts.GrantTypeAuthorizationCode, consts.GrantTypeImplicit}, ResponseTypes: oauth2.Arguments{consts.ResponseTypeImplicitFlowToken, consts.ResponseTypeAuthorizationCodeFlow, consts.ResponseTypeImplicitFlowIDToken}, - Scopes: []string{"openid"}, + Scopes: []string{consts.ScopeOpenID}, } - areq.GrantedScope = oauth2.Arguments{"openid"} + areq.GrantedScope = oauth2.Arguments{consts.ScopeOpenID} return makeOpenIDConnectHybridHandler(oauth2.MinParameterEntropy) }, expectErr: oauth2.ErrInsufficientEntropy, @@ -155,9 +155,9 @@ func TestHybrid_HandleAuthorizeEndpointRequest(t *testing.T) { areq.Client = &oauth2.DefaultClient{ GrantTypes: oauth2.Arguments{consts.GrantTypeAuthorizationCode, consts.GrantTypeImplicit}, ResponseTypes: oauth2.Arguments{consts.ResponseTypeImplicitFlowToken, consts.ResponseTypeAuthorizationCodeFlow, consts.ResponseTypeImplicitFlowIDToken}, - Scopes: []string{"openid"}, + Scopes: []string{consts.ScopeOpenID}, } - areq.GrantedScope = oauth2.Arguments{"openid"} + areq.GrantedScope = oauth2.Arguments{consts.ScopeOpenID} return makeOpenIDConnectHybridHandler(42) }, expectErr: oauth2.ErrInsufficientEntropy, @@ -170,9 +170,9 @@ func TestHybrid_HandleAuthorizeEndpointRequest(t *testing.T) { areq.Client = &oauth2.DefaultClient{ GrantTypes: oauth2.Arguments{consts.GrantTypeAuthorizationCode, consts.GrantTypeImplicit}, ResponseTypes: oauth2.Arguments{consts.ResponseTypeImplicitFlowToken, consts.ResponseTypeAuthorizationCodeFlow, consts.ResponseTypeImplicitFlowIDToken}, - Scopes: []string{"openid"}, + Scopes: []string{consts.ScopeOpenID}, } - areq.GrantedScope = oauth2.Arguments{"openid"} + areq.GrantedScope = oauth2.Arguments{consts.ScopeOpenID} return makeOpenIDConnectHybridHandler(oauth2.MinParameterEntropy) }, expectErr: ErrInvalidSession, @@ -184,7 +184,7 @@ func TestHybrid_HandleAuthorizeEndpointRequest(t *testing.T) { areq.Client = &oauth2.DefaultClient{ GrantTypes: oauth2.Arguments{"implicit"}, ResponseTypes: oauth2.Arguments{consts.ResponseTypeImplicitFlowToken, consts.ResponseTypeAuthorizationCodeFlow, consts.ResponseTypeImplicitFlowIDToken}, - Scopes: []string{"openid"}, + Scopes: []string{consts.ScopeOpenID}, } areq.Session = &DefaultSession{ Claims: &jwt.IDTokenClaims{ @@ -204,7 +204,7 @@ func TestHybrid_HandleAuthorizeEndpointRequest(t *testing.T) { areq.Client = &oauth2.DefaultClient{ GrantTypes: oauth2.Arguments{consts.GrantTypeAuthorizationCode, consts.GrantTypeImplicit}, ResponseTypes: oauth2.Arguments{consts.ResponseTypeImplicitFlowToken, consts.ResponseTypeAuthorizationCodeFlow, consts.ResponseTypeImplicitFlowIDToken}, - Scopes: []string{"openid"}, + Scopes: []string{consts.ScopeOpenID}, } return makeOpenIDConnectHybridHandler(oauth2.MinParameterEntropy) }, @@ -227,7 +227,7 @@ func TestHybrid_HandleAuthorizeEndpointRequest(t *testing.T) { areq.Client = &oauth2.DefaultClient{ GrantTypes: oauth2.Arguments{consts.GrantTypeAuthorizationCode, consts.GrantTypeImplicit}, ResponseTypes: oauth2.Arguments{consts.ResponseTypeImplicitFlowToken, consts.ResponseTypeAuthorizationCodeFlow, consts.ResponseTypeImplicitFlowIDToken}, - Scopes: []string{"openid"}, + Scopes: []string{consts.ScopeOpenID}, } return makeOpenIDConnectHybridHandler(oauth2.MinParameterEntropy) }, @@ -238,7 +238,7 @@ func TestHybrid_HandleAuthorizeEndpointRequest(t *testing.T) { areq.Client = &oauth2.DefaultClient{ GrantTypes: oauth2.Arguments{consts.GrantTypeAuthorizationCode, consts.GrantTypeImplicit}, ResponseTypes: oauth2.Arguments{consts.ResponseTypeImplicitFlowToken, consts.ResponseTypeAuthorizationCodeFlow, consts.ResponseTypeImplicitFlowIDToken}, - Scopes: []string{"openid"}, + Scopes: []string{consts.ScopeOpenID}, } return makeOpenIDConnectHybridHandler(oauth2.MinParameterEntropy) }, @@ -250,7 +250,7 @@ func TestHybrid_HandleAuthorizeEndpointRequest(t *testing.T) { areq.Client = &oauth2.DefaultClient{ GrantTypes: oauth2.Arguments{consts.GrantTypeAuthorizationCode, consts.GrantTypeImplicit}, ResponseTypes: oauth2.Arguments{consts.ResponseTypeImplicitFlowToken, consts.ResponseTypeAuthorizationCodeFlow, consts.ResponseTypeImplicitFlowIDToken}, - Scopes: []string{"openid"}, + Scopes: []string{consts.ScopeOpenID}, } return makeOpenIDConnectHybridHandler(4) }, @@ -288,10 +288,10 @@ func TestHybrid_HandleAuthorizeEndpointRequest(t *testing.T) { DefaultClient: &oauth2.DefaultClient{ GrantTypes: oauth2.Arguments{consts.GrantTypeAuthorizationCode, consts.GrantTypeImplicit}, ResponseTypes: oauth2.Arguments{consts.ResponseTypeImplicitFlowToken, consts.ResponseTypeAuthorizationCodeFlow, consts.ResponseTypeImplicitFlowIDToken}, - Scopes: []string{"openid"}, + Scopes: []string{consts.ScopeOpenID}, }, } - areq.GrantedScope = oauth2.Arguments{"openid"} + areq.GrantedScope = oauth2.Arguments{consts.ScopeOpenID} areq.Session = &DefaultSession{ Claims: &jwt.IDTokenClaims{ Subject: "peter", diff --git a/handler/openid/flow_implicit_test.go b/handler/openid/flow_implicit_test.go index 1728d119..76872c7c 100644 --- a/handler/openid/flow_implicit_test.go +++ b/handler/openid/flow_implicit_test.go @@ -16,6 +16,7 @@ import ( "authelia.com/provider/oauth2" hoauth2 "authelia.com/provider/oauth2/handler/oauth2" "authelia.com/provider/oauth2/internal" + "authelia.com/provider/oauth2/internal/consts" "authelia.com/provider/oauth2/internal/gen" "authelia.com/provider/oauth2/storage" "authelia.com/provider/oauth2/token/jwt" @@ -83,7 +84,7 @@ func TestImplicit_HandleAuthorizeEndpointRequest(t *testing.T) { { description: "should not do anything because request requirements are not met", setup: func() OpenIDConnectImplicitHandler { - areq.ResponseTypes = oauth2.Arguments{"id_token"} + areq.ResponseTypes = oauth2.Arguments{consts.ResponseTypeImplicitFlowIDToken} areq.State = "foostate" return makeOpenIDConnectImplicitHandler(oauth2.MinParameterEntropy) }, @@ -91,7 +92,7 @@ func TestImplicit_HandleAuthorizeEndpointRequest(t *testing.T) { { description: "should not do anything because request requirements are not met", setup: func() OpenIDConnectImplicitHandler { - areq.ResponseTypes = oauth2.Arguments{"token", "id_token"} + areq.ResponseTypes = oauth2.Arguments{consts.ResponseTypeImplicitFlowToken, consts.ResponseTypeImplicitFlowIDToken} return makeOpenIDConnectImplicitHandler(oauth2.MinParameterEntropy) }, }, @@ -99,19 +100,19 @@ func TestImplicit_HandleAuthorizeEndpointRequest(t *testing.T) { description: "should not do anything because request requirements are not met", setup: func() OpenIDConnectImplicitHandler { areq.ResponseTypes = oauth2.Arguments{} - areq.GrantedScope = oauth2.Arguments{"openid"} + areq.GrantedScope = oauth2.Arguments{consts.ScopeOpenID} return makeOpenIDConnectImplicitHandler(oauth2.MinParameterEntropy) }, }, { description: "should not do anything because request requirements are not met", setup: func() OpenIDConnectImplicitHandler { - areq.ResponseTypes = oauth2.Arguments{"token", "id_token"} - areq.RequestedScope = oauth2.Arguments{"openid"} + areq.ResponseTypes = oauth2.Arguments{consts.ResponseTypeImplicitFlowToken, consts.ResponseTypeImplicitFlowIDToken} + areq.RequestedScope = oauth2.Arguments{consts.ScopeOpenID} areq.Client = &oauth2.DefaultClient{ GrantTypes: oauth2.Arguments{}, ResponseTypes: oauth2.Arguments{}, - Scopes: []string{"openid", "oauth2"}, + Scopes: []string{consts.ScopeOpenID, "oauth2"}, } return makeOpenIDConnectImplicitHandler(oauth2.MinParameterEntropy) }, @@ -121,12 +122,12 @@ func TestImplicit_HandleAuthorizeEndpointRequest(t *testing.T) { //{ // description: "should not do anything because request requirements are not met", // setup: func() OpenIDConnectImplicitHandler { - // areq.ResponseTypes = oauth2.Arguments{"token", "id_token"} - // areq.RequestedScope = oauth2.Arguments{"openid"} + // areq.ResponseTypes = oauth2.Arguments{consts.ResponseTypeImplicitFlowToken, consts.ResponseTypeImplicitFlowIDToken} + // areq.RequestedScope = oauth2.Arguments{consts.ScopeOpenID} // areq.Client = &oauth2.DefaultClient{ - // GrantTypes: oauth2.Arguments{"implicit"}, + // GrantTypes: oauth2.Arguments{consts.GrantTypeImplicit}, // ResponseTypes: oauth2.Arguments{}, - // RequestedScope: []string{"openid", "oauth2"}, + // RequestedScope: []string{consts.ScopeOpenID, "oauth2"}, // } // return makeOpenIDConnectImplicitHandler(oauth2.MinParameterEntropy) // }, @@ -135,12 +136,12 @@ func TestImplicit_HandleAuthorizeEndpointRequest(t *testing.T) { { description: "should not do anything because request requirements are not met", setup: func() OpenIDConnectImplicitHandler { - areq.ResponseTypes = oauth2.Arguments{"id_token"} - areq.RequestedScope = oauth2.Arguments{"openid"} + areq.ResponseTypes = oauth2.Arguments{consts.ResponseTypeImplicitFlowIDToken} + areq.RequestedScope = oauth2.Arguments{consts.ScopeOpenID} areq.Client = &oauth2.DefaultClient{ - GrantTypes: oauth2.Arguments{"implicit"}, - //ResponseTypes: oauth2.Arguments{"token", "id_token"}, - Scopes: []string{"openid", "oauth2"}, + GrantTypes: oauth2.Arguments{consts.GrantTypeImplicit}, + //ResponseTypes: oauth2.Arguments{consts.ResponseTypeImplicitFlowToken, consts.ResponseTypeImplicitFlowIDToken}, + Scopes: []string{consts.ScopeOpenID, "oauth2"}, } return makeOpenIDConnectImplicitHandler(oauth2.MinParameterEntropy) }, @@ -149,13 +150,13 @@ func TestImplicit_HandleAuthorizeEndpointRequest(t *testing.T) { { description: "should not do anything because request requirements are not met", setup: func() OpenIDConnectImplicitHandler { - areq.Form = url.Values{"nonce": {"short"}} - areq.ResponseTypes = oauth2.Arguments{"id_token"} - areq.RequestedScope = oauth2.Arguments{"openid"} + areq.Form = url.Values{consts.FormParameterNonce: {"short"}} + areq.ResponseTypes = oauth2.Arguments{consts.ResponseTypeImplicitFlowIDToken} + areq.RequestedScope = oauth2.Arguments{consts.ScopeOpenID} areq.Client = &oauth2.DefaultClient{ - GrantTypes: oauth2.Arguments{"implicit"}, - ResponseTypes: oauth2.Arguments{"token", "id_token"}, - Scopes: []string{"openid", "oauth2"}, + GrantTypes: oauth2.Arguments{consts.GrantTypeImplicit}, + ResponseTypes: oauth2.Arguments{consts.ResponseTypeImplicitFlowToken, consts.ResponseTypeImplicitFlowIDToken}, + Scopes: []string{consts.ScopeOpenID, "oauth2"}, } return makeOpenIDConnectImplicitHandler(oauth2.MinParameterEntropy) }, @@ -164,13 +165,13 @@ func TestImplicit_HandleAuthorizeEndpointRequest(t *testing.T) { { description: "should fail because session not set", setup: func() OpenIDConnectImplicitHandler { - areq.Form = url.Values{"nonce": {"long-enough"}} - areq.ResponseTypes = oauth2.Arguments{"id_token"} - areq.RequestedScope = oauth2.Arguments{"openid"} + areq.Form = url.Values{consts.FormParameterNonce: {"long-enough"}} + areq.ResponseTypes = oauth2.Arguments{consts.ResponseTypeImplicitFlowIDToken} + areq.RequestedScope = oauth2.Arguments{consts.ScopeOpenID} areq.Client = &oauth2.DefaultClient{ - GrantTypes: oauth2.Arguments{"implicit"}, - ResponseTypes: oauth2.Arguments{"token", "id_token"}, - Scopes: []string{"openid", "oauth2"}, + GrantTypes: oauth2.Arguments{consts.GrantTypeImplicit}, + ResponseTypes: oauth2.Arguments{consts.ResponseTypeImplicitFlowToken, consts.ResponseTypeImplicitFlowIDToken}, + Scopes: []string{consts.ScopeOpenID, "oauth2"}, } return makeOpenIDConnectImplicitHandler(oauth2.MinParameterEntropy) }, @@ -186,21 +187,21 @@ func TestImplicit_HandleAuthorizeEndpointRequest(t *testing.T) { Headers: &jwt.Headers{}, Subject: "peter", } - areq.Form.Add("nonce", "some-random-foo-nonce-wow") + areq.Form.Add(consts.FormParameterNonce, "some-random-foo-nonce-wow") return makeOpenIDConnectImplicitHandler(oauth2.MinParameterEntropy) }, }, { description: "should pass", setup: func() OpenIDConnectImplicitHandler { - areq.ResponseTypes = oauth2.Arguments{"id_token"} + areq.ResponseTypes = oauth2.Arguments{consts.ResponseTypeImplicitFlowIDToken} return makeOpenIDConnectImplicitHandler(oauth2.MinParameterEntropy) }, check: func() { - assert.NotEmpty(t, aresp.GetParameters().Get("state")) - assert.Empty(t, aresp.GetParameters().Get("access_token")) + assert.NotEmpty(t, aresp.GetParameters().Get(consts.FormParameterState)) + assert.Empty(t, aresp.GetParameters().Get(consts.AccessResponseAccessToken)) - idToken := aresp.GetParameters().Get("id_token") + idToken := aresp.GetParameters().Get(consts.AccessResponseIDToken) assert.NotEmpty(t, idToken) idTokenExp := internal.ExtractJwtExpClaim(t, idToken) internal.RequireEqualTime(t, time.Now().Add(time.Hour), *idTokenExp, time.Minute) @@ -217,22 +218,22 @@ func TestImplicit_HandleAuthorizeEndpointRequest(t *testing.T) { Headers: &jwt.Headers{}, Subject: "peter", } - areq.ResponseTypes = oauth2.Arguments{"id_token"} + areq.ResponseTypes = oauth2.Arguments{consts.ResponseTypeImplicitFlowIDToken} areq.Client = &oauth2.DefaultClientWithCustomTokenLifespans{ DefaultClient: &oauth2.DefaultClient{ - GrantTypes: oauth2.Arguments{"implicit"}, - ResponseTypes: oauth2.Arguments{"token", "id_token"}, - Scopes: []string{"openid", "oauth2"}, + GrantTypes: oauth2.Arguments{consts.GrantTypeImplicit}, + ResponseTypes: oauth2.Arguments{consts.ResponseTypeImplicitFlowToken, consts.ResponseTypeImplicitFlowIDToken}, + Scopes: []string{consts.ScopeOpenID, "oauth2"}, }, } areq.Client.(*oauth2.DefaultClientWithCustomTokenLifespans).SetTokenLifespans(&internal.TestLifespans) return makeOpenIDConnectImplicitHandler(oauth2.MinParameterEntropy) }, check: func() { - idToken := aresp.GetParameters().Get("id_token") + idToken := aresp.GetParameters().Get(consts.AccessResponseIDToken) assert.NotEmpty(t, idToken) - assert.NotEmpty(t, aresp.GetParameters().Get("state")) - assert.Empty(t, aresp.GetParameters().Get("access_token")) + assert.NotEmpty(t, aresp.GetParameters().Get(consts.FormParameterState)) + assert.Empty(t, aresp.GetParameters().Get(consts.AccessResponseAccessToken)) idTokenExp := internal.ExtractJwtExpClaim(t, idToken) internal.RequireEqualTime(t, time.Now().Add(*internal.TestLifespans.ImplicitGrantIDTokenLifespan), *idTokenExp, time.Minute) }, @@ -241,44 +242,44 @@ func TestImplicit_HandleAuthorizeEndpointRequest(t *testing.T) { description: "should pass", setup: func() OpenIDConnectImplicitHandler { aresp = oauth2.NewAuthorizeResponse() - areq.ResponseTypes = oauth2.Arguments{"token", "id_token"} + areq.ResponseTypes = oauth2.Arguments{consts.ResponseTypeImplicitFlowToken, consts.ResponseTypeImplicitFlowIDToken} return makeOpenIDConnectImplicitHandler(oauth2.MinParameterEntropy) }, check: func() { - assert.NotEmpty(t, aresp.GetParameters().Get("state")) + assert.NotEmpty(t, aresp.GetParameters().Get(consts.FormParameterState)) - idToken := aresp.GetParameters().Get("id_token") + idToken := aresp.GetParameters().Get(consts.AccessResponseIDToken) assert.NotEmpty(t, idToken) internal.RequireEqualTime(t, time.Now().Add(*internal.TestLifespans.ImplicitGrantIDTokenLifespan).UTC(), *internal.ExtractJwtExpClaim(t, idToken), time.Minute) - assert.NotEmpty(t, aresp.GetParameters().Get("access_token")) + assert.NotEmpty(t, aresp.GetParameters().Get(consts.AccessResponseAccessToken)) internal.RequireEqualTime(t, time.Now().Add(*internal.TestLifespans.ImplicitGrantAccessTokenLifespan).UTC(), areq.Session.GetExpiresAt(oauth2.AccessToken), time.Minute) }, }, { description: "should pass", setup: func() OpenIDConnectImplicitHandler { - areq.ResponseTypes = oauth2.Arguments{"id_token", "token"} - areq.RequestedScope = oauth2.Arguments{"oauth2", "openid"} + areq.ResponseTypes = oauth2.Arguments{consts.ResponseTypeImplicitFlowIDToken, consts.ResponseTypeImplicitFlowToken} + areq.RequestedScope = oauth2.Arguments{"oauth2", consts.ScopeOpenID} return makeOpenIDConnectImplicitHandler(oauth2.MinParameterEntropy) }, check: func() { - assert.NotEmpty(t, aresp.GetParameters().Get("id_token")) - assert.NotEmpty(t, aresp.GetParameters().Get("state")) - assert.NotEmpty(t, aresp.GetParameters().Get("access_token")) + assert.NotEmpty(t, aresp.GetParameters().Get(consts.AccessResponseIDToken)) + assert.NotEmpty(t, aresp.GetParameters().Get(consts.FormParameterState)) + assert.NotEmpty(t, aresp.GetParameters().Get(consts.AccessResponseAccessToken)) assert.Equal(t, oauth2.ResponseModeFragment, areq.GetResponseMode()) }, }, { description: "should pass with low min entropy", setup: func() OpenIDConnectImplicitHandler { - areq.Form.Set("nonce", "short") + areq.Form.Set(consts.FormParameterNonce, "short") return makeOpenIDConnectImplicitHandler(4) }, check: func() { - assert.NotEmpty(t, aresp.GetParameters().Get("id_token")) - assert.NotEmpty(t, aresp.GetParameters().Get("state")) - assert.NotEmpty(t, aresp.GetParameters().Get("access_token")) + assert.NotEmpty(t, aresp.GetParameters().Get(consts.AccessResponseIDToken)) + assert.NotEmpty(t, aresp.GetParameters().Get(consts.FormParameterState)) + assert.NotEmpty(t, aresp.GetParameters().Get(consts.AccessResponseAccessToken)) }, }, } { diff --git a/handler/openid/flow_refresh_token.go b/handler/openid/flow_refresh_token.go index bebfee61..ee448dca 100644 --- a/handler/openid/flow_refresh_token.go +++ b/handler/openid/flow_refresh_token.go @@ -7,11 +7,11 @@ import ( "context" "time" - "authelia.com/provider/oauth2/internal/consts" "github.com/google/uuid" "github.com/pkg/errors" "authelia.com/provider/oauth2" + "authelia.com/provider/oauth2/internal/consts" "authelia.com/provider/oauth2/internal/errorsx" ) diff --git a/handler/openid/flow_refresh_token_test.go b/handler/openid/flow_refresh_token_test.go index a6439e60..a94feabd 100644 --- a/handler/openid/flow_refresh_token_test.go +++ b/handler/openid/flow_refresh_token_test.go @@ -8,12 +8,12 @@ import ( "testing" "time" - "authelia.com/provider/oauth2/internal/consts" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "authelia.com/provider/oauth2" "authelia.com/provider/oauth2/internal" + "authelia.com/provider/oauth2/internal/consts" "authelia.com/provider/oauth2/token/jwt" ) diff --git a/handler/openid/strategy_jwt.go b/handler/openid/strategy_jwt.go index b7096724..4c8e168c 100644 --- a/handler/openid/strategy_jwt.go +++ b/handler/openid/strategy_jwt.go @@ -8,11 +8,11 @@ import ( "strconv" "time" - "authelia.com/provider/oauth2/internal/consts" "github.com/mohae/deepcopy" "github.com/pkg/errors" "authelia.com/provider/oauth2" + "authelia.com/provider/oauth2/internal/consts" "authelia.com/provider/oauth2/internal/errorsx" "authelia.com/provider/oauth2/internal/stringslice" "authelia.com/provider/oauth2/token/jwt" diff --git a/handler/openid/strategy_jwt_test.go b/handler/openid/strategy_jwt_test.go index 797104e7..fe6d2ae4 100644 --- a/handler/openid/strategy_jwt_test.go +++ b/handler/openid/strategy_jwt_test.go @@ -9,10 +9,10 @@ import ( "testing" "time" - "authelia.com/provider/oauth2/internal/consts" "github.com/stretchr/testify/assert" "authelia.com/provider/oauth2" + "authelia.com/provider/oauth2/internal/consts" "authelia.com/provider/oauth2/token/jwt" ) diff --git a/handler/openid/validator.go b/handler/openid/validator.go index 6138e8fd..32e4e14f 100644 --- a/handler/openid/validator.go +++ b/handler/openid/validator.go @@ -9,10 +9,10 @@ import ( "strings" "time" - "authelia.com/provider/oauth2/internal/consts" "github.com/pkg/errors" "authelia.com/provider/oauth2" + "authelia.com/provider/oauth2/internal/consts" "authelia.com/provider/oauth2/internal/errorsx" "authelia.com/provider/oauth2/internal/stringslice" "authelia.com/provider/oauth2/token/jwt" diff --git a/handler/pkce/handler.go b/handler/pkce/handler.go index a759a01b..bd72a7c3 100644 --- a/handler/pkce/handler.go +++ b/handler/pkce/handler.go @@ -10,11 +10,11 @@ import ( "encoding/base64" "regexp" - "authelia.com/provider/oauth2/internal/consts" "github.com/pkg/errors" "authelia.com/provider/oauth2" hoauth2 "authelia.com/provider/oauth2/handler/oauth2" + "authelia.com/provider/oauth2/internal/consts" "authelia.com/provider/oauth2/internal/errorsx" ) diff --git a/handler/rfc7523/handler_test.go b/handler/rfc7523/handler_test.go index 8d765c49..691a5ffb 100644 --- a/handler/rfc7523/handler_test.go +++ b/handler/rfc7523/handler_test.go @@ -15,7 +15,7 @@ import ( "testing" "time" - "github.com/go-jose/go-jose/v3" + jose "github.com/go-jose/go-jose/v3" "github.com/go-jose/go-jose/v3/jwt" "github.com/stretchr/testify/suite" "go.uber.org/mock/gomock" @@ -144,7 +144,7 @@ func (s *AuthorizeJWTGrantRequestHandlerTestSuite) TestRequestWithoutAssertion() func (s *AuthorizeJWTGrantRequestHandlerTestSuite) TestRequestWithMalformedAssertion() { // arrange s.accessRequest.GrantTypes = []string{consts.GrantTypeOAuthJWTBearer} - s.accessRequest.Form.Add("assertion", "fjigjgfkjgkf") + s.accessRequest.Form.Add(consts.FormParameterAssertion, "fjigjgfkjgkf") // act err := s.handler.HandleTokenEndpointRequest(context.Background(), s.accessRequest) @@ -164,7 +164,7 @@ func (s *AuthorizeJWTGrantRequestHandlerTestSuite) TestRequestAssertionWithoutIs keyID := "my_key" cl := s.createStandardClaim() cl.Issuer = "" - s.accessRequest.Form.Add("assertion", s.createTestAssertion(cl, keyID)) + s.accessRequest.Form.Add(consts.FormParameterAssertion, s.createTestAssertion(cl, keyID)) // act err := s.handler.HandleTokenEndpointRequest(context.Background(), s.accessRequest) @@ -184,7 +184,7 @@ func (s *AuthorizeJWTGrantRequestHandlerTestSuite) TestRequestAssertionWithoutSu keyID := "my_key" cl := s.createStandardClaim() cl.Subject = "" - s.accessRequest.Form.Add("assertion", s.createTestAssertion(cl, keyID)) + s.accessRequest.Form.Add(consts.FormParameterAssertion, s.createTestAssertion(cl, keyID)) // act err := s.handler.HandleTokenEndpointRequest(context.Background(), s.accessRequest) @@ -204,7 +204,7 @@ func (s *AuthorizeJWTGrantRequestHandlerTestSuite) TestNoMatchingPublicKeyToChec s.accessRequest.GrantTypes = []string{consts.GrantTypeOAuthJWTBearer} cl := s.createStandardClaim() keyID := "my_key" - s.accessRequest.Form.Add("assertion", s.createTestAssertion(cl, keyID)) + s.accessRequest.Form.Add(consts.FormParameterAssertion, s.createTestAssertion(cl, keyID)) s.mockStore.EXPECT().GetPublicKey(ctx, cl.Issuer, cl.Subject, keyID).Return(nil, oauth2.ErrNotFound) // act @@ -228,7 +228,7 @@ func (s *AuthorizeJWTGrantRequestHandlerTestSuite) TestNoMatchingPublicKeysToChe s.accessRequest.GrantTypes = []string{consts.GrantTypeOAuthJWTBearer} keyID := "" // provide no hint of what key was used to sign assertion cl := s.createStandardClaim() - s.accessRequest.Form.Add("assertion", s.createTestAssertion(cl, keyID)) + s.accessRequest.Form.Add(consts.FormParameterAssertion, s.createTestAssertion(cl, keyID)) s.mockStore.EXPECT().GetPublicKeys(ctx, cl.Issuer, cl.Subject).Return(nil, oauth2.ErrNotFound) // act @@ -252,7 +252,7 @@ func (s *AuthorizeJWTGrantRequestHandlerTestSuite) TestWrongPublicKeyToCheckAsse s.accessRequest.GrantTypes = []string{consts.GrantTypeOAuthJWTBearer} keyID := "wrong_key" cl := s.createStandardClaim() - s.accessRequest.Form.Add("assertion", s.createTestAssertion(cl, keyID)) + s.accessRequest.Form.Add(consts.FormParameterAssertion, s.createTestAssertion(cl, keyID)) jwk := s.createRandomTestJWK() s.mockStore.EXPECT().GetPublicKey(ctx, cl.Issuer, cl.Subject, keyID).Return(&jwk, nil) @@ -271,7 +271,7 @@ func (s *AuthorizeJWTGrantRequestHandlerTestSuite) TestWrongPublicKeysToCheckAss s.accessRequest.GrantTypes = []string{consts.GrantTypeOAuthJWTBearer} keyID := "" // provide no hint of what key was used to sign assertion cl := s.createStandardClaim() - s.accessRequest.Form.Add("assertion", s.createTestAssertion(cl, keyID)) + s.accessRequest.Form.Add(consts.FormParameterAssertion, s.createTestAssertion(cl, keyID)) s.mockStore.EXPECT().GetPublicKeys(ctx, cl.Issuer, cl.Subject).Return(s.createJWS(s.createRandomTestJWK(), s.createRandomTestJWK()), nil) // act @@ -297,7 +297,7 @@ func (s *AuthorizeJWTGrantRequestHandlerTestSuite) TestNoAudienceInAssertion() { pubKey := s.createJWK(s.privateKey.Public(), keyID) cl := s.createStandardClaim() cl.Audience = []string{} - s.accessRequest.Form.Add("assertion", s.createTestAssertion(cl, keyID)) + s.accessRequest.Form.Add(consts.FormParameterAssertion, s.createTestAssertion(cl, keyID)) s.mockStore.EXPECT().GetPublicKey(ctx, cl.Issuer, cl.Subject, keyID).Return(&pubKey, nil) // act @@ -320,7 +320,7 @@ func (s *AuthorizeJWTGrantRequestHandlerTestSuite) TestNotValidAudienceInAsserti pubKey := s.createJWK(s.privateKey.Public(), keyID) cl := s.createStandardClaim() cl.Audience = jwt.Audience{"leela", "fry"} - s.accessRequest.Form.Add("assertion", s.createTestAssertion(cl, keyID)) + s.accessRequest.Form.Add(consts.FormParameterAssertion, s.createTestAssertion(cl, keyID)) s.mockStore.EXPECT().GetPublicKey(ctx, cl.Issuer, cl.Subject, keyID).Return(&pubKey, nil) // act @@ -346,7 +346,7 @@ func (s *AuthorizeJWTGrantRequestHandlerTestSuite) TestNoExpirationInAssertion() pubKey := s.createJWK(s.privateKey.Public(), keyID) cl := s.createStandardClaim() cl.Expiry = nil - s.accessRequest.Form.Add("assertion", s.createTestAssertion(cl, keyID)) + s.accessRequest.Form.Add(consts.FormParameterAssertion, s.createTestAssertion(cl, keyID)) s.mockStore.EXPECT().GetPublicKey(ctx, cl.Issuer, cl.Subject, keyID).Return(&pubKey, nil) // act @@ -369,7 +369,7 @@ func (s *AuthorizeJWTGrantRequestHandlerTestSuite) TestExpiredAssertion() { pubKey := s.createJWK(s.privateKey.Public(), keyID) cl := s.createStandardClaim() cl.Expiry = jwt.NewNumericDate(time.Now().AddDate(0, -1, 0)) - s.accessRequest.Form.Add("assertion", s.createTestAssertion(cl, keyID)) + s.accessRequest.Form.Add(consts.FormParameterAssertion, s.createTestAssertion(cl, keyID)) s.mockStore.EXPECT().GetPublicKey(ctx, cl.Issuer, cl.Subject, keyID).Return(&pubKey, nil) // act @@ -393,7 +393,7 @@ func (s *AuthorizeJWTGrantRequestHandlerTestSuite) TestAssertionNotAcceptedBefor nbf := time.Now().AddDate(0, 1, 0) cl := s.createStandardClaim() cl.NotBefore = jwt.NewNumericDate(nbf) - s.accessRequest.Form.Add("assertion", s.createTestAssertion(cl, keyID)) + s.accessRequest.Form.Add(consts.FormParameterAssertion, s.createTestAssertion(cl, keyID)) s.mockStore.EXPECT().GetPublicKey(ctx, cl.Issuer, cl.Subject, keyID).Return(&pubKey, nil) // act @@ -420,7 +420,7 @@ func (s *AuthorizeJWTGrantRequestHandlerTestSuite) TestAssertionWithoutRequiredI cl := s.createStandardClaim() cl.IssuedAt = nil s.handler.Config.(*oauth2.Config).GrantTypeJWTBearerIssuedDateOptional = false - s.accessRequest.Form.Add("assertion", s.createTestAssertion(cl, keyID)) + s.accessRequest.Form.Add(consts.FormParameterAssertion, s.createTestAssertion(cl, keyID)) s.mockStore.EXPECT().GetPublicKey(ctx, cl.Issuer, cl.Subject, keyID).Return(&pubKey, nil) // act @@ -446,7 +446,7 @@ func (s *AuthorizeJWTGrantRequestHandlerTestSuite) TestAssertionWithIssueDateFar cl.IssuedAt = jwt.NewNumericDate(issuedAt) s.handler.Config.(*oauth2.Config).GrantTypeJWTBearerIssuedDateOptional = false s.handler.Config.(*oauth2.Config).GrantTypeJWTBearerMaxDuration = time.Hour * 24 * 30 - s.accessRequest.Form.Add("assertion", s.createTestAssertion(cl, keyID)) + s.accessRequest.Form.Add(consts.FormParameterAssertion, s.createTestAssertion(cl, keyID)) s.mockStore.EXPECT().GetPublicKey(ctx, cl.Issuer, cl.Subject, keyID).Return(&pubKey, nil) // act @@ -476,7 +476,7 @@ func (s *AuthorizeJWTGrantRequestHandlerTestSuite) TestAssertionWithExpirationDa cl.Expiry = jwt.NewNumericDate(time.Now().AddDate(0, 0, 20)) s.handler.Config.(*oauth2.Config).GrantTypeJWTBearerIssuedDateOptional = false s.handler.Config.(*oauth2.Config).GrantTypeJWTBearerMaxDuration = time.Hour * 24 * 30 - s.accessRequest.Form.Add("assertion", s.createTestAssertion(cl, keyID)) + s.accessRequest.Form.Add(consts.FormParameterAssertion, s.createTestAssertion(cl, keyID)) s.mockStore.EXPECT().GetPublicKey(ctx, cl.Issuer, cl.Subject, keyID).Return(&pubKey, nil) // act @@ -506,7 +506,7 @@ func (s *AuthorizeJWTGrantRequestHandlerTestSuite) TestAssertionWithExpirationDa cl.Expiry = jwt.NewNumericDate(time.Now().AddDate(0, 0, 31)) s.handler.Config.(*oauth2.Config).GrantTypeJWTBearerIssuedDateOptional = true s.handler.Config.(*oauth2.Config).GrantTypeJWTBearerMaxDuration = time.Hour * 24 * 30 - s.accessRequest.Form.Add("assertion", s.createTestAssertion(cl, keyID)) + s.accessRequest.Form.Add(consts.FormParameterAssertion, s.createTestAssertion(cl, keyID)) s.mockStore.EXPECT().GetPublicKey(ctx, cl.Issuer, cl.Subject, keyID).Return(&pubKey, nil) // act @@ -525,7 +525,7 @@ func (s *AuthorizeJWTGrantRequestHandlerTestSuite) TestAssertionWithoutRequiredT pubKey := s.createJWK(s.privateKey.Public(), keyID) cl := s.createStandardClaim() cl.ID = "" - s.accessRequest.Form.Add("assertion", s.createTestAssertion(cl, keyID)) + s.accessRequest.Form.Add(consts.FormParameterAssertion, s.createTestAssertion(cl, keyID)) s.mockStore.EXPECT().GetPublicKey(ctx, cl.Issuer, cl.Subject, keyID).Return(&pubKey, nil) // act @@ -547,7 +547,7 @@ func (s *AuthorizeJWTGrantRequestHandlerTestSuite) TestAssertionAlreadyUsed() { keyID := "my_key" pubKey := s.createJWK(s.privateKey.Public(), keyID) cl := s.createStandardClaim() - s.accessRequest.Form.Add("assertion", s.createTestAssertion(cl, keyID)) + s.accessRequest.Form.Add(consts.FormParameterAssertion, s.createTestAssertion(cl, keyID)) s.mockStore.EXPECT().GetPublicKey(ctx, cl.Issuer, cl.Subject, keyID).Return(&pubKey, nil) s.mockStore.EXPECT().IsJWTUsed(ctx, cl.ID).Return(true, nil) @@ -566,7 +566,7 @@ func (s *AuthorizeJWTGrantRequestHandlerTestSuite) TestErrWhenCheckingIfJWTWasUs keyID := "my_key" pubKey := s.createJWK(s.privateKey.Public(), keyID) cl := s.createStandardClaim() - s.accessRequest.Form.Add("assertion", s.createTestAssertion(cl, keyID)) + s.accessRequest.Form.Add(consts.FormParameterAssertion, s.createTestAssertion(cl, keyID)) s.mockStore.EXPECT().GetPublicKey(ctx, cl.Issuer, cl.Subject, keyID).Return(&pubKey, nil) s.mockStore.EXPECT().IsJWTUsed(ctx, cl.ID).Return(false, oauth2.ErrServerError) @@ -585,7 +585,7 @@ func (s *AuthorizeJWTGrantRequestHandlerTestSuite) TestErrWhenMarkingJWTAsUsed() keyID := "my_key" pubKey := s.createJWK(s.privateKey.Public(), keyID) cl := s.createStandardClaim() - s.accessRequest.Form.Add("assertion", s.createTestAssertion(cl, keyID)) + s.accessRequest.Form.Add(consts.FormParameterAssertion, s.createTestAssertion(cl, keyID)) s.mockStore.EXPECT().GetPublicKey(ctx, cl.Issuer, cl.Subject, keyID).Return(&pubKey, nil) s.mockStore.EXPECT().GetPublicKeyScopes(ctx, cl.Issuer, cl.Subject, keyID).Return([]string{"valid_scope"}, nil) s.mockStore.EXPECT().IsJWTUsed(ctx, cl.ID).Return(false, nil) @@ -607,7 +607,7 @@ func (s *AuthorizeJWTGrantRequestHandlerTestSuite) TestErrWhileFetchingPublicKey pubKey := s.createJWK(s.privateKey.Public(), keyID) cl := s.createStandardClaim() - s.accessRequest.Form.Add("assertion", s.createTestAssertion(cl, keyID)) + s.accessRequest.Form.Add(consts.FormParameterAssertion, s.createTestAssertion(cl, keyID)) s.mockStore.EXPECT().GetPublicKey(ctx, cl.Issuer, cl.Subject, keyID).Return(&pubKey, nil) s.mockStore.EXPECT().GetPublicKeyScopes(ctx, cl.Issuer, cl.Subject, keyID).Return([]string{}, oauth2.ErrServerError) s.mockStore.EXPECT().IsJWTUsed(ctx, cl.ID).Return(false, nil) @@ -628,7 +628,7 @@ func (s *AuthorizeJWTGrantRequestHandlerTestSuite) TestAssertionWithInvalidScope pubKey := s.createJWK(s.privateKey.Public(), keyID) cl := s.createStandardClaim() - s.accessRequest.Form.Add("assertion", s.createTestAssertion(cl, keyID)) + s.accessRequest.Form.Add(consts.FormParameterAssertion, s.createTestAssertion(cl, keyID)) s.accessRequest.RequestedScope = []string{"some_scope"} s.mockStore.EXPECT().GetPublicKey(ctx, cl.Issuer, cl.Subject, keyID).Return(&pubKey, nil) s.mockStore.EXPECT().GetPublicKeyScopes(ctx, cl.Issuer, cl.Subject, keyID).Return([]string{"valid_scope"}, nil) @@ -654,10 +654,10 @@ func (s *AuthorizeJWTGrantRequestHandlerTestSuite) TestValidAssertion() { pubKey := s.createJWK(s.privateKey.Public(), keyID) cl := s.createStandardClaim() - s.accessRequest.Form.Add("assertion", s.createTestAssertion(cl, keyID)) + s.accessRequest.Form.Add(consts.FormParameterAssertion, s.createTestAssertion(cl, keyID)) s.accessRequest.RequestedScope = []string{"valid_scope"} s.mockStore.EXPECT().GetPublicKey(ctx, cl.Issuer, cl.Subject, keyID).Return(&pubKey, nil) - s.mockStore.EXPECT().GetPublicKeyScopes(ctx, cl.Issuer, cl.Subject, keyID).Return([]string{"valid_scope", "openid"}, nil) + s.mockStore.EXPECT().GetPublicKeyScopes(ctx, cl.Issuer, cl.Subject, keyID).Return([]string{"valid_scope", consts.ScopeOpenID}, nil) s.mockStore.EXPECT().IsJWTUsed(ctx, cl.ID).Return(false, nil) s.mockStore.EXPECT().MarkJWTUsedForTime(ctx, cl.ID, cl.Expiry.Time()).Return(nil) @@ -675,7 +675,7 @@ func (s *AuthorizeJWTGrantRequestHandlerTestSuite) TestAssertionIsValidWhenNoSco keyID := "my_key" pubKey := s.createJWK(s.privateKey.Public(), keyID) cl := s.createStandardClaim() - s.accessRequest.Form.Add("assertion", s.createTestAssertion(cl, keyID)) + s.accessRequest.Form.Add(consts.FormParameterAssertion, s.createTestAssertion(cl, keyID)) s.mockStore.EXPECT().GetPublicKey(ctx, cl.Issuer, cl.Subject, keyID).Return(&pubKey, nil) s.mockStore.EXPECT().GetPublicKeyScopes(ctx, cl.Issuer, cl.Subject, keyID).Return([]string{"valid_scope"}, nil) s.mockStore.EXPECT().IsJWTUsed(ctx, cl.ID).Return(false, nil) @@ -697,7 +697,7 @@ func (s *AuthorizeJWTGrantRequestHandlerTestSuite) TestAssertionIsValidWhenJWTID cl := s.createStandardClaim() s.handler.Config.(*oauth2.Config).GrantTypeJWTBearerIDOptional = true cl.ID = "" - s.accessRequest.Form.Add("assertion", s.createTestAssertion(cl, keyID)) + s.accessRequest.Form.Add(consts.FormParameterAssertion, s.createTestAssertion(cl, keyID)) s.mockStore.EXPECT().GetPublicKey(ctx, cl.Issuer, cl.Subject, keyID).Return(&pubKey, nil) s.mockStore.EXPECT().GetPublicKeyScopes(ctx, cl.Issuer, cl.Subject, keyID).Return([]string{"valid_scope"}, nil) @@ -717,7 +717,7 @@ func (s *AuthorizeJWTGrantRequestHandlerTestSuite) TestAssertionIsValidWhenJWTIs cl := s.createStandardClaim() cl.IssuedAt = nil s.handler.Config.(*oauth2.Config).GrantTypeJWTBearerIssuedDateOptional = true - s.accessRequest.Form.Add("assertion", s.createTestAssertion(cl, keyID)) + s.accessRequest.Form.Add(consts.FormParameterAssertion, s.createTestAssertion(cl, keyID)) s.mockStore.EXPECT().GetPublicKey(ctx, cl.Issuer, cl.Subject, keyID).Return(&pubKey, nil) s.mockStore.EXPECT().GetPublicKeyScopes(ctx, cl.Issuer, cl.Subject, keyID).Return([]string{"valid_scope"}, nil) s.mockStore.EXPECT().IsJWTUsed(ctx, cl.ID).Return(false, nil) @@ -739,7 +739,7 @@ func (s *AuthorizeJWTGrantRequestHandlerTestSuite) TestRequestIsValidWhenClientA cl := s.createStandardClaim() s.accessRequest.Client = &oauth2.DefaultClient{} s.handler.Config.(*oauth2.Config).GrantTypeJWTBearerCanSkipClientAuth = true - s.accessRequest.Form.Add("assertion", s.createTestAssertion(cl, keyID)) + s.accessRequest.Form.Add(consts.FormParameterAssertion, s.createTestAssertion(cl, keyID)) s.mockStore.EXPECT().GetPublicKey(ctx, cl.Issuer, cl.Subject, keyID).Return(&pubKey, nil) s.mockStore.EXPECT().GetPublicKeyScopes(ctx, cl.Issuer, cl.Subject, keyID).Return([]string{"valid_scope"}, nil) s.mockStore.EXPECT().IsJWTUsed(ctx, cl.ID).Return(false, nil) @@ -793,7 +793,7 @@ func (s *AuthorizeJWTGrantRequestHandlerTestSuite) createJWK(key any, keyID stri Key: key, KeyID: keyID, Algorithm: string(jose.RS256), - Use: "sig", + Use: consts.JSONWebTokenUseSignature, } } @@ -917,13 +917,13 @@ func (s *AuthorizeJWTGrantPopulateTokenEndpointTestSuite) TestAccessTokenIssuedS // assert s.NoError(err, "no error expected") s.Equal(s.accessResponse.AccessToken, token, "access token expected in response") - s.Equal(s.accessResponse.TokenType, "bearer", "token type expected to be \"bearer\"") + s.Equal(s.accessResponse.TokenType, oauth2.BearerAccessToken, "token type expected to be \"bearer\"") s.Equal( - s.accessResponse.GetExtra("expires_in"), int64(s.handler.HandleHelper.Config.GetAccessTokenLifespan(context.TODO()).Seconds()), + s.accessResponse.GetExtra(consts.AccessResponseExpiresIn), int64(s.handler.HandleHelper.Config.GetAccessTokenLifespan(context.TODO()).Seconds()), "token expiration time expected in response to be equal to AccessTokenLifespan setting in handler", ) - s.Equal(s.accessResponse.GetExtra("scope"), "", "no scopes expected in response") - s.Nil(s.accessResponse.GetExtra("refresh_token"), "refresh token not expected in response") + s.Equal(s.accessResponse.GetExtra(consts.AccessResponseScope), "", "no scopes expected in response") + s.Nil(s.accessResponse.GetExtra(consts.AccessResponseRefreshToken), "refresh token not expected in response") } func (s *AuthorizeJWTGrantPopulateTokenEndpointTestSuite) TestAccessTokenIssuedSuccessfullyWithCustomLifespan() { @@ -947,11 +947,11 @@ func (s *AuthorizeJWTGrantPopulateTokenEndpointTestSuite) TestAccessTokenIssuedS // assert s.NoError(err, "no error expected") s.Equal(s.accessResponse.AccessToken, token, "access token expected in response") - s.Equal(s.accessResponse.TokenType, "bearer", "token type expected to be \"bearer\"") + s.Equal(s.accessResponse.TokenType, oauth2.BearerAccessToken, "token type expected to be \"bearer\"") s.Equal( - s.accessResponse.GetExtra("expires_in"), int64(internal.TestLifespans.JwtBearerGrantAccessTokenLifespan.Seconds()), + s.accessResponse.GetExtra(consts.AccessResponseExpiresIn), int64(internal.TestLifespans.JwtBearerGrantAccessTokenLifespan.Seconds()), "token expiration time expected in response to be equal to the pertinent AccessTokenLifespan setting in client", ) - s.Equal(s.accessResponse.GetExtra("scope"), "", "no scopes expected in response") - s.Nil(s.accessResponse.GetExtra("refresh_token"), "refresh token not expected in response") + s.Equal(s.accessResponse.GetExtra(consts.AccessResponseScope), "", "no scopes expected in response") + s.Nil(s.accessResponse.GetExtra(consts.AccessResponseRefreshToken), "refresh token not expected in response") } diff --git a/handler/verifiable/handler_test.go b/handler/verifiable/handler_test.go index 0c114fe1..8047ec9a 100644 --- a/handler/verifiable/handler_test.go +++ b/handler/verifiable/handler_test.go @@ -8,12 +8,12 @@ import ( "testing" "time" - "authelia.com/provider/oauth2/internal/consts" "github.com/stretchr/testify/assert" "go.uber.org/mock/gomock" "authelia.com/provider/oauth2" "authelia.com/provider/oauth2/internal" + "authelia.com/provider/oauth2/internal/consts" ) type mockNonceManager struct{ t *testing.T } @@ -57,7 +57,7 @@ func TestHandler(t *testing.T) { defer ctrl.Finish() req := internal.NewMockAccessRequester(ctrl) - req.EXPECT().GetGrantedScopes().Return(oauth2.Arguments{"openid"}).AnyTimes() + req.EXPECT().GetGrantedScopes().Return(oauth2.Arguments{consts.ScopeOpenID}).AnyTimes() resp := internal.NewMockAccessResponder(ctrl) diff --git a/integration/authorize_code_grant_public_client_pkce_test.go b/integration/authorize_code_grant_public_client_pkce_test.go index 2845be75..761d55d7 100644 --- a/integration/authorize_code_grant_public_client_pkce_test.go +++ b/integration/authorize_code_grant_public_client_pkce_test.go @@ -19,6 +19,7 @@ import ( "authelia.com/provider/oauth2" "authelia.com/provider/oauth2/compose" hoauth2 "authelia.com/provider/oauth2/handler/oauth2" + "authelia.com/provider/oauth2/internal/consts" ) func TestAuthorizeCodeFlowWithPublicClientAndPKCE(t *testing.T) { @@ -92,11 +93,11 @@ func runAuthorizeCodeGrantWithPublicClientAndPKCETest(t *testing.T, strategy any t.Logf("Got redirect url: %s", resp.Request.URL) resp, err := http.PostForm(ts.URL+"/token", url.Values{ - "code": {resp.Request.URL.Query().Get("code")}, - "grant_type": {"authorization_code"}, - "client_id": {"public-client"}, - "redirect_uri": {ts.URL + "/callback"}, - "code_verifier": {verifier}, + consts.FormParameterAuthorizationCode: {resp.Request.URL.Query().Get(consts.FormParameterAuthorizationCode)}, + consts.FormParameterGrantType: {consts.GrantTypeAuthorizationCode}, + consts.FormParameterClientID: {"public-client"}, + consts.FormParameterRedirectURI: {ts.URL + "/callback"}, + consts.FormParameterCodeVerifier: {verifier}, }) require.NoError(t, err) defer resp.Body.Close() diff --git a/integration/authorize_code_grant_test.go b/integration/authorize_code_grant_test.go index 45affdeb..06b55326 100644 --- a/integration/authorize_code_grant_test.go +++ b/integration/authorize_code_grant_test.go @@ -20,6 +20,7 @@ import ( hoauth2 "authelia.com/provider/oauth2/handler/oauth2" "authelia.com/provider/oauth2/handler/openid" "authelia.com/provider/oauth2/internal" + "authelia.com/provider/oauth2/internal/consts" ) func TestAuthorizeCodeFlow(t *testing.T) { @@ -105,7 +106,7 @@ func runAuthorizeCodeGrantTest(t *testing.T, strategy any) { setup: func() { oauthClient = newOAuth2Client(ts) oauthClient.ClientID = "custom-lifespan-client" - oauthClient.Scopes = []string{"oauth2", "offline"} + oauthClient.Scopes = []string{"oauth2", consts.ScopeOffline} state = "12345678901234567890" }, check: func(t *testing.T, r *http.Response, token *xoauth2.Token) { @@ -115,7 +116,7 @@ func runAuthorizeCodeGrantTest(t *testing.T, strategy any) { require.NoError(t, json.NewDecoder(r.Body).Decode(&b)) atExp := b.Session.GetExpiresAt(oauth2.AccessToken) internal.RequireEqualTime(t, time.Now().UTC().Add(*internal.TestLifespans.AuthorizationCodeGrantAccessTokenLifespan), atExp, time.Minute) - atExpIn := time.Duration(token.Extra("expires_in").(float64)) * time.Second + atExpIn := time.Duration(token.Extra(consts.AccessResponseExpiresIn).(float64)) * time.Second internal.RequireEqualDuration(t, *internal.TestLifespans.AuthorizationCodeGrantAccessTokenLifespan, atExpIn, time.Minute) rtExp := b.Session.GetExpiresAt(oauth2.RefreshToken) internal.RequireEqualTime(t, time.Now().UTC().Add(*internal.TestLifespans.AuthorizationCodeGrantRefreshTokenLifespan), rtExp, time.Minute) @@ -169,7 +170,7 @@ func runAuthorizeCodeGrantDupeCodeTest(t *testing.T, strategy any) { req, err := http.NewRequest("GET", ts.URL+"/info", nil) require.NoError(t, err) - req.Header.Set("Authorization", "Bearer "+token.AccessToken) + req.Header.Set(consts.HeaderAuthorization, "Bearer "+token.AccessToken) resp, err = http.DefaultClient.Do(req) require.NoError(t, err) diff --git a/integration/authorize_form_post_test.go b/integration/authorize_form_post_test.go index cb4b14d6..31db5d72 100644 --- a/integration/authorize_form_post_test.go +++ b/integration/authorize_form_post_test.go @@ -20,6 +20,7 @@ import ( "authelia.com/provider/oauth2/compose" "authelia.com/provider/oauth2/handler/openid" "authelia.com/provider/oauth2/internal" + "authelia.com/provider/oauth2/internal/consts" "authelia.com/provider/oauth2/internal/gen" "authelia.com/provider/oauth2/token/jwt" ) @@ -64,7 +65,7 @@ func TestAuthorizeFormPostResponseMode(t *testing.T) { responseType: "id_token%20token", setup: func() { state = "12345678901234567890" - oauthClient.Scopes = []string{"openid"} + oauthClient.Scopes = []string{consts.ScopeOpenID} }, check: func(t *testing.T, stateFromServer string, code string, token xoauth2.Token, iDToken string, cparam url.Values, err map[string]string) { assert.EqualValues(t, state, stateFromServer) @@ -76,10 +77,10 @@ func TestAuthorizeFormPostResponseMode(t *testing.T) { }, { description: "implicit grant #2 test with form_post", - responseType: "id_token", + responseType: consts.ResponseTypeImplicitFlowIDToken, setup: func() { state = "12345678901234567890" - oauthClient.Scopes = []string{"openid"} + oauthClient.Scopes = []string{consts.ScopeOpenID} }, check: func(t *testing.T, stateFromServer string, code string, token xoauth2.Token, iDToken string, cparam url.Values, err map[string]string) { assert.EqualValues(t, state, stateFromServer) @@ -88,7 +89,7 @@ func TestAuthorizeFormPostResponseMode(t *testing.T) { }, { description: "Authorization code grant test with form_post", - responseType: "code", + responseType: consts.ResponseTypeAuthorizationCodeFlow, setup: func() { state = "12345678901234567890" }, @@ -102,7 +103,7 @@ func TestAuthorizeFormPostResponseMode(t *testing.T) { responseType: "token%20code", setup: func() { state = "12345678901234567890" - oauthClient.Scopes = []string{"openid"} + oauthClient.Scopes = []string{consts.ScopeOpenID} }, check: func(t *testing.T, stateFromServer string, code string, token xoauth2.Token, iDToken string, cparam url.Values, err map[string]string) { assert.EqualValues(t, state, stateFromServer) @@ -117,7 +118,7 @@ func TestAuthorizeFormPostResponseMode(t *testing.T) { responseType: "token%20id_token%20code", setup: func() { state = "12345678901234567890" - oauthClient.Scopes = []string{"openid"} + oauthClient.Scopes = []string{consts.ScopeOpenID} }, check: func(t *testing.T, stateFromServer string, code string, token xoauth2.Token, iDToken string, cparam url.Values, err map[string]string) { assert.EqualValues(t, state, stateFromServer) @@ -133,7 +134,7 @@ func TestAuthorizeFormPostResponseMode(t *testing.T) { responseType: "id_token%20code", setup: func() { state = "12345678901234567890" - oauthClient.Scopes = []string{"openid"} + oauthClient.Scopes = []string{consts.ScopeOpenID} }, check: func(t *testing.T, stateFromServer string, code string, token xoauth2.Token, iDToken string, cparam url.Values, err map[string]string) { assert.EqualValues(t, state, stateFromServer) @@ -155,7 +156,7 @@ func TestAuthorizeFormPostResponseMode(t *testing.T) { }, } { // Test canonical form_post - t.Run(fmt.Sprintf("case=%d/description=%s", k, c.description), testFormPost(&state, false, c, oauthClient, "form_post")) + t.Run(fmt.Sprintf("case=%d/description=%s", k, c.description), testFormPost(&state, false, c, oauthClient, consts.ResponseModeFormPost)) // Test decorated form_post response c.check = decorateCheck(c.check) @@ -204,7 +205,7 @@ func (m *decoratedFormPostResponse) ResponseModes() oauth2.ResponseModeTypes { } func (m *decoratedFormPostResponse) WriteAuthorizeResponse(ctx context.Context, rw http.ResponseWriter, ar oauth2.AuthorizeRequester, resp oauth2.AuthorizeResponder) { - rw.Header().Add("Content-Type", "text/html;charset=UTF-8") + rw.Header().Add(consts.HeaderContentType, consts.ContentTypeTextHTML) resp.AddParameter("custom_param", "foo") oauth2.WriteAuthorizeFormPostResponse(ar.GetRedirectURI().String(), resp.GetParameters(), oauth2.GetPostFormHTMLTemplate(ctx, oauth2.New(nil, new(oauth2.Config))), rw) diff --git a/integration/authorize_response_mode_test.go b/integration/authorize_response_mode_test.go index 566b273f..2bf943b7 100644 --- a/integration/authorize_response_mode_test.go +++ b/integration/authorize_response_mode_test.go @@ -63,10 +63,10 @@ func TestAuthorizeResponseModes(t *testing.T) { { description: "Should give err because implicit grant with response mode query", responseType: "id_token%20token", - responseMode: "query", + responseMode: consts.ResponseModeQuery, setup: func() { state = "12345678901234567890" - oauthClient.Scopes = []string{"openid"} + oauthClient.Scopes = []string{consts.ScopeOpenID} responseModeClient.ResponseModes = []oauth2.ResponseModeType{oauth2.ResponseModeQuery} }, check: func(t *testing.T, stateFromServer string, code string, token xoauth2.Token, iDToken string, err map[string]string) { @@ -78,10 +78,10 @@ func TestAuthorizeResponseModes(t *testing.T) { { description: "Should pass implicit grant with response mode form_post", responseType: "id_token%20token", - responseMode: "form_post", + responseMode: consts.ResponseModeFormPost, setup: func() { state = "12345678901234567890" - oauthClient.Scopes = []string{"openid"} + oauthClient.Scopes = []string{consts.ScopeOpenID} responseModeClient.ResponseModes = []oauth2.ResponseModeType{oauth2.ResponseModeFormPost} }, check: func(t *testing.T, stateFromServer string, code string, token xoauth2.Token, iDToken string, err map[string]string) { @@ -95,10 +95,10 @@ func TestAuthorizeResponseModes(t *testing.T) { { description: "Should fail because response mode form_post is not allowed by the client", responseType: "id_token%20token", - responseMode: "form_post", + responseMode: consts.ResponseModeFormPost, setup: func() { state = "12345678901234567890" - oauthClient.Scopes = []string{"openid"} + oauthClient.Scopes = []string{consts.ScopeOpenID} responseModeClient.ResponseModes = []oauth2.ResponseModeType{oauth2.ResponseModeQuery} }, check: func(t *testing.T, stateFromServer string, code string, token xoauth2.Token, iDToken string, err map[string]string) { @@ -110,10 +110,10 @@ func TestAuthorizeResponseModes(t *testing.T) { { description: "Should fail because response mode form_post is not allowed by the client without legacy format", responseType: "id_token%20token", - responseMode: "form_post", + responseMode: consts.ResponseModeFormPost, setup: func() { state = "12345678901234567890" - oauthClient.Scopes = []string{"openid"} + oauthClient.Scopes = []string{consts.ScopeOpenID} responseModeClient.ResponseModes = []oauth2.ResponseModeType{oauth2.ResponseModeQuery} provider.(*oauth2.Fosite).Config.(*oauth2.Config).UseLegacyErrorFormat = false }, @@ -126,8 +126,8 @@ func TestAuthorizeResponseModes(t *testing.T) { }, { description: "Should pass Authorization code grant test with response mode fragment", - responseType: "code", - responseMode: "fragment", + responseType: consts.ResponseTypeAuthorizationCodeFlow, + responseMode: consts.ResponseModeFragment, setup: func() { state = "12345678901234567890" responseModeClient.ResponseModes = []oauth2.ResponseModeType{oauth2.ResponseModeFragment} @@ -140,7 +140,7 @@ func TestAuthorizeResponseModes(t *testing.T) { { description: "Should pass Authorization code grant test with response mode form_post", responseType: "code", - responseMode: "form_post", + responseMode: consts.ResponseModeFormPost, setup: func() { state = "12345678901234567890" responseModeClient.ResponseModes = []oauth2.ResponseModeType{oauth2.ResponseModeFormPost} @@ -153,10 +153,10 @@ func TestAuthorizeResponseModes(t *testing.T) { { description: "Should fail Hybrid grant test with query", responseType: "token%20code", - responseMode: "query", + responseMode: consts.ResponseModeQuery, setup: func() { state = "12345678901234567890" - oauthClient.Scopes = []string{"openid"} + oauthClient.Scopes = []string{consts.ScopeOpenID} responseModeClient.ResponseModes = []oauth2.ResponseModeType{oauth2.ResponseModeQuery} }, check: func(t *testing.T, stateFromServer string, code string, token xoauth2.Token, iDToken string, err map[string]string) { @@ -168,10 +168,10 @@ func TestAuthorizeResponseModes(t *testing.T) { { description: "Should fail Hybrid grant test with query without legacy fields", responseType: "token%20code", - responseMode: "query", + responseMode: consts.ResponseModeQuery, setup: func() { state = "12345678901234567890" - oauthClient.Scopes = []string{"openid"} + oauthClient.Scopes = []string{consts.ScopeOpenID} responseModeClient.ResponseModes = []oauth2.ResponseModeType{oauth2.ResponseModeQuery} provider.(*oauth2.Fosite).Config.(*oauth2.Config).UseLegacyErrorFormat = false }, @@ -187,10 +187,10 @@ func TestAuthorizeResponseModes(t *testing.T) { { description: "Should pass Hybrid grant test with form_post", responseType: "token%20code", - responseMode: "form_post", + responseMode: consts.ResponseModeFormPost, setup: func() { state = "12345678901234567890" - oauthClient.Scopes = []string{"openid"} + oauthClient.Scopes = []string{consts.ScopeOpenID} responseModeClient.ResponseModes = []oauth2.ResponseModeType{oauth2.ResponseModeFormPost} }, check: func(t *testing.T, stateFromServer string, code string, token xoauth2.Token, iDToken string, err map[string]string) { diff --git a/integration/client_credentials_grant_test.go b/integration/client_credentials_grant_test.go index dfd83900..261eb8fc 100644 --- a/integration/client_credentials_grant_test.go +++ b/integration/client_credentials_grant_test.go @@ -24,6 +24,7 @@ import ( "authelia.com/provider/oauth2/compose" hoauth2 "authelia.com/provider/oauth2/handler/oauth2" "authelia.com/provider/oauth2/internal" + "authelia.com/provider/oauth2/internal/consts" ) func TestClientCredentialsFlow(t *testing.T) { @@ -38,7 +39,7 @@ func introspect(t *testing.T, ts *httptest.Server, token string, p any, username req, err := http.NewRequest("POST", ts.URL+"/introspect", strings.NewReader(url.Values{"token": {token}}.Encode())) require.NoError(t, err) req.SetBasicAuth(username, password) - req.Header.Set("Content-Type", "application/x-www-form-urlencoded") + req.Header.Set(consts.HeaderContentType, consts.ContentTypeApplicationURLEncodedForm) r, err := http.DefaultClient.Do(req) require.NoError(t, err) defer r.Body.Close() @@ -86,8 +87,8 @@ func runClientCredentialsGrantTest(t *testing.T, strategy hoauth2.AccessTokenStr check: func(t *testing.T, token *xoauth2.Token) { var j json.RawMessage introspect(t, ts, token.AccessToken, &j, oauthClient.ClientID, oauthClient.ClientSecret) - assert.Equal(t, oauthClient.ClientID, gjson.GetBytes(j, "client_id").String()) - assert.Equal(t, "oauth2", gjson.GetBytes(j, "scope").String()) + assert.Equal(t, oauthClient.ClientID, gjson.GetBytes(j, consts.ClaimClientIdentifier).String()) + assert.Equal(t, "oauth2", gjson.GetBytes(j, consts.ClaimScope).String()) }, }, { @@ -98,13 +99,13 @@ func runClientCredentialsGrantTest(t *testing.T, strategy hoauth2.AccessTokenStr var j json.RawMessage introspect(t, ts, token.AccessToken, &j, oauthClient.ClientID, oauthClient.ClientSecret) introspect(t, ts, token.AccessToken, &j, oauthClient.ClientID, oauthClient.ClientSecret) - assert.Equal(t, oauthClient.ClientID, gjson.GetBytes(j, "client_id").String()) - assert.Equal(t, "oauth2", gjson.GetBytes(j, "scope").String()) + assert.Equal(t, oauthClient.ClientID, gjson.GetBytes(j, consts.ClaimClientIdentifier).String()) + assert.Equal(t, "oauth2", gjson.GetBytes(j, consts.ClaimScope).String()) atReq, ok := store.AccessTokens[strings.Split(token.AccessToken, ".")[1]] require.True(t, ok) atExp := atReq.GetSession().GetExpiresAt(oauth2.AccessToken) internal.RequireEqualTime(t, time.Now().UTC().Add(time.Hour), atExp, time.Minute) - atExpIn := time.Duration(token.Extra("expires_in").(float64)) * time.Second + atExpIn := time.Duration(token.Extra(consts.AccessResponseExpiresIn).(float64)) * time.Second internal.RequireEqualDuration(t, time.Hour, atExpIn, time.Minute) }, }, @@ -117,14 +118,14 @@ func runClientCredentialsGrantTest(t *testing.T, strategy hoauth2.AccessTokenStr var j json.RawMessage introspect(t, ts, token.AccessToken, &j, oauthClient.ClientID, oauthClient.ClientSecret) introspect(t, ts, token.AccessToken, &j, oauthClient.ClientID, oauthClient.ClientSecret) - assert.Equal(t, oauthClient.ClientID, gjson.GetBytes(j, "client_id").String()) - assert.Equal(t, "oauth2", gjson.GetBytes(j, "scope").String()) + assert.Equal(t, oauthClient.ClientID, gjson.GetBytes(j, consts.ClaimClientIdentifier).String()) + assert.Equal(t, "oauth2", gjson.GetBytes(j, consts.ClaimScope).String()) atReq, ok := store.AccessTokens[strings.Split(token.AccessToken, ".")[1]] require.True(t, ok) atExp := atReq.GetSession().GetExpiresAt(oauth2.AccessToken) internal.RequireEqualTime(t, time.Now().UTC().Add(*internal.TestLifespans.ClientCredentialsGrantAccessTokenLifespan), atExp, time.Minute) - atExpIn := time.Duration(token.Extra("expires_in").(float64)) * time.Second + atExpIn := time.Duration(token.Extra(consts.AccessResponseExpiresIn).(float64)) * time.Second internal.RequireEqualDuration(t, *internal.TestLifespans.ClientCredentialsGrantAccessTokenLifespan, atExpIn, time.Minute) rtExp := atReq.GetSession().GetExpiresAt(oauth2.RefreshToken) internal.RequireEqualTime(t, time.Time{}, rtExp, time.Minute) diff --git a/integration/clients/introspect.go b/integration/clients/introspect.go index 7db35be1..f6c7b079 100644 --- a/integration/clients/introspect.go +++ b/integration/clients/introspect.go @@ -87,7 +87,7 @@ func (c *Introspect) getRequest( return nil, err } - request.Header.Set("Content-Type", "application/x-www-form-urlencoded") + request.Header.Set(consts.HeaderContentType, consts.ContentTypeApplicationURLEncodedForm) for header, value := range header { request.Header.Set(header, value) diff --git a/integration/clients/jwt_bearer.go b/integration/clients/jwt_bearer.go index 4289aa7c..a47e23e0 100644 --- a/integration/clients/jwt_bearer.go +++ b/integration/clients/jwt_bearer.go @@ -84,7 +84,7 @@ func (c *JWTBearer) GetToken(ctx context.Context, payloadData *JWTBearerPayload, return nil, err } - request.Header.Set("Content-Type", "application/x-www-form-urlencoded") + request.Header.Set(consts.HeaderContentType, consts.ContentTypeApplicationURLEncodedForm) response, err := c.client.Do(request) if err != nil { diff --git a/integration/helper_endpoints_test.go b/integration/helper_endpoints_test.go index 6e4ab1a2..5ea11987 100644 --- a/integration/helper_endpoints_test.go +++ b/integration/helper_endpoints_test.go @@ -15,6 +15,7 @@ import ( "authelia.com/provider/oauth2" hoauth2 "authelia.com/provider/oauth2/handler/oauth2" + "authelia.com/provider/oauth2/internal/consts" ) func tokenRevocationHandler(t *testing.T, oauth2 oauth2.Provider, session oauth2.Session) func(rw http.ResponseWriter, req *http.Request) { @@ -78,12 +79,12 @@ func authEndpointHandler(t *testing.T, provider oauth2.Provider, session oauth2. ar.GrantScope("oauth2") } - if ar.GetRequestedScopes().Has("offline") { - ar.GrantScope("offline") + if ar.GetRequestedScopes().Has(consts.ScopeOffline) { + ar.GrantScope(consts.ScopeOffline) } - if ar.GetRequestedScopes().Has("openid") { - ar.GrantScope("openid") + if ar.GetRequestedScopes().Has(consts.ScopeOpenID) { + ar.GrantScope(consts.ScopeOpenID) } for _, a := range ar.GetRequestedAudience() { diff --git a/integration/helper_setup_test.go b/integration/helper_setup_test.go index 3c9aa93f..58e88093 100644 --- a/integration/helper_setup_test.go +++ b/integration/helper_setup_test.go @@ -22,6 +22,7 @@ import ( "authelia.com/provider/oauth2/handler/openid" "authelia.com/provider/oauth2/integration/clients" "authelia.com/provider/oauth2/internal" + "authelia.com/provider/oauth2/internal/consts" "authelia.com/provider/oauth2/internal/gen" "authelia.com/provider/oauth2/storage" "authelia.com/provider/oauth2/token/hmac" @@ -53,9 +54,9 @@ var store = &storage.MemoryStore{ ID: "my-client", Secret: []byte(`$2a$10$IxMdI6d.LIRZPpSfEwNoeu4rY3FhDREsxFJXikcgdRRAStxUlsuEO`), // = "foobar" RedirectURIs: []string{"http://localhost:3846/callback"}, - ResponseTypes: []string{"id_token", "code", "token", "token code", "id_token code", "token id_token", "token code id_token"}, - GrantTypes: []string{"implicit", "refresh_token", "authorization_code", "password", "client_credentials"}, - Scopes: []string{"oauth2", "offline", "openid"}, + ResponseTypes: []string{consts.ResponseTypeImplicitFlowIDToken, consts.ResponseTypeAuthorizationCodeFlow, consts.ResponseTypeImplicitFlowToken, consts.ResponseTypeImplicitFlowBoth, consts.ResponseTypeHybridFlowIDToken, consts.ResponseTypeHybridFlowToken, consts.ResponseTypeHybridFlowBoth}, + GrantTypes: []string{consts.GrantTypeImplicit, consts.GrantTypeRefreshToken, consts.GrantTypeAuthorizationCode, consts.GrantTypeResourceOwnerPasswordCredentials, consts.GrantTypeClientCredentials}, + Scopes: []string{"oauth2", consts.ScopeOffline, consts.ScopeOpenID}, Audience: []string{tokenURL}, }, "custom-lifespan-client": &oauth2.DefaultClientWithCustomTokenLifespans{ @@ -64,9 +65,9 @@ var store = &storage.MemoryStore{ Secret: []byte(`$2a$10$IxMdI6d.LIRZPpSfEwNoeu4rY3FhDREsxFJXikcgdRRAStxUlsuEO`), // = "foobar" RotatedSecrets: [][]byte{[]byte(`$2y$10$X51gLxUQJ.hGw1epgHTE5u0bt64xM0COU7K9iAp.OFg8p2pUd.1zC `)}, // = "foobaz", RedirectURIs: []string{"http://localhost:3846/callback"}, - ResponseTypes: []string{"id_token", "code", "token", "id_token token", "code id_token", "code token", "code id_token token"}, - GrantTypes: []string{"implicit", "refresh_token", "authorization_code", "password", "client_credentials"}, - Scopes: []string{"oauth2", "openid", "photos", "offline"}, + ResponseTypes: []string{consts.ResponseTypeImplicitFlowIDToken, consts.ResponseTypeAuthorizationCodeFlow, consts.ResponseTypeImplicitFlowToken, consts.ResponseTypeImplicitFlowBoth, consts.ResponseTypeHybridFlowIDToken, consts.ResponseTypeHybridFlowToken, consts.ResponseTypeHybridFlowBoth}, + GrantTypes: []string{consts.GrantTypeImplicit, consts.GrantTypeRefreshToken, consts.GrantTypeAuthorizationCode, consts.GrantTypeResourceOwnerPasswordCredentials, consts.GrantTypeClientCredentials}, + Scopes: []string{"oauth2", consts.ScopeOpenID, "photos", consts.ScopeOffline}, }, TokenLifespans: &internal.TestLifespans, }, @@ -75,9 +76,9 @@ var store = &storage.MemoryStore{ Secret: []byte{}, Public: true, RedirectURIs: []string{"http://localhost:3846/callback"}, - ResponseTypes: []string{"id_token", "code", "code id_token"}, - GrantTypes: []string{"refresh_token", "authorization_code"}, - Scopes: []string{"oauth2", "offline", "openid"}, + ResponseTypes: []string{consts.ResponseTypeImplicitFlowIDToken, consts.ResponseTypeAuthorizationCodeFlow, consts.ResponseTypeHybridFlowIDToken}, + GrantTypes: []string{consts.GrantTypeRefreshToken, consts.GrantTypeAuthorizationCode}, + Scopes: []string{"oauth2", consts.ScopeOffline, consts.ScopeOpenID}, Audience: []string{tokenURL}, }, }, diff --git a/integration/introspect_jwt_bearer_token_test.go b/integration/introspect_jwt_bearer_token_test.go index 52a5c33c..75e235f6 100644 --- a/integration/introspect_jwt_bearer_token_test.go +++ b/integration/introspect_jwt_bearer_token_test.go @@ -18,6 +18,7 @@ import ( "authelia.com/provider/oauth2" "authelia.com/provider/oauth2/compose" "authelia.com/provider/oauth2/integration/clients" + "authelia.com/provider/oauth2/internal/consts" ) type introspectJWTBearerTokenSuite struct { @@ -69,7 +70,7 @@ func (s *introspectJWTBearerTokenSuite) TestSuccessResponseWithMultipleScopesTok Token: token.AccessToken, Scopes: nil, }, - map[string]string{"Authorization": s.authorizationHeader}, + map[string]string{consts.HeaderAuthorization: s.authorizationHeader}, ) s.assertSuccessResponse(s.T(), response, err, firstJWTBearerSubject) @@ -88,7 +89,7 @@ func (s *introspectJWTBearerTokenSuite) TestUnActiveResponseWithInvalidScopes() Token: token.AccessToken, Scopes: []string{"invalid"}, }, - map[string]string{"Authorization": s.authorizationHeader}, + map[string]string{consts.HeaderAuthorization: s.authorizationHeader}, ) require.NoError(s.T(), err) @@ -108,7 +109,7 @@ func (s *introspectJWTBearerTokenSuite) TestSuccessResponseWithoutScopesForIntro Token: token.AccessToken, Scopes: nil, }, - map[string]string{"Authorization": s.authorizationHeader}, + map[string]string{consts.HeaderAuthorization: s.authorizationHeader}, ) s.assertSuccessResponse(s.T(), response, err, firstJWTBearerSubject) @@ -126,7 +127,7 @@ func (s *introspectJWTBearerTokenSuite) TestSuccessResponseWithoutScopes() { Token: token.AccessToken, Scopes: nil, }, - map[string]string{"Authorization": s.authorizationHeader}, + map[string]string{consts.HeaderAuthorization: s.authorizationHeader}, ) s.assertSuccessResponse(s.T(), response, err, firstJWTBearerSubject) @@ -144,7 +145,7 @@ func (s *introspectJWTBearerTokenSuite) TestSubjectHasAccessToScopeButNotInited( Token: token.AccessToken, Scopes: s.scopes, }, - map[string]string{"Authorization": s.authorizationHeader}, + map[string]string{consts.HeaderAuthorization: s.authorizationHeader}, ) require.NoError(s.T(), err) @@ -163,7 +164,7 @@ func (s *introspectJWTBearerTokenSuite) TestTheSameTokenInRequestAndHeader() { Token: token.AccessToken, Scopes: nil, }, - map[string]string{"Authorization": "bearer " + token.AccessToken}, + map[string]string{consts.HeaderAuthorization: "bearer " + token.AccessToken}, ) s.assertUnauthorizedResponse(s.T(), response, err) diff --git a/integration/introspect_token_test.go b/integration/introspect_token_test.go index 36db357e..58bee488 100644 --- a/integration/introspect_token_test.go +++ b/integration/introspect_token_test.go @@ -16,6 +16,7 @@ import ( "authelia.com/provider/oauth2" "authelia.com/provider/oauth2/compose" hoauth2 "authelia.com/provider/oauth2/handler/oauth2" + "authelia.com/provider/oauth2/internal/consts" ) func TestIntrospectToken(t *testing.T) { @@ -70,28 +71,28 @@ func runIntrospectTokenTest(t *testing.T, strategy hoauth2.AccessTokenStrategy, }, { prepare: func(s *gorequest.SuperAgent) *gorequest.SuperAgent { - return s.Set("Authorization", "bearer "+a.AccessToken) + return s.Set(consts.HeaderAuthorization, "bearer "+a.AccessToken) }, isActive: true, scopes: "oauth2", }, { prepare: func(s *gorequest.SuperAgent) *gorequest.SuperAgent { - return s.Set("Authorization", "bearer "+a.AccessToken) + return s.Set(consts.HeaderAuthorization, "bearer "+a.AccessToken) }, isActive: true, scopes: "", }, { prepare: func(s *gorequest.SuperAgent) *gorequest.SuperAgent { - return s.Set("Authorization", "bearer "+a.AccessToken) + return s.Set(consts.HeaderAuthorization, "bearer "+a.AccessToken) }, isActive: false, scopes: "foo", }, { prepare: func(s *gorequest.SuperAgent) *gorequest.SuperAgent { - return s.Set("Authorization", "bearer "+b.AccessToken) + return s.Set(consts.HeaderAuthorization, "bearer "+b.AccessToken) }, isActive: false, scopes: "", diff --git a/integration/oidc_explicit_test.go b/integration/oidc_explicit_test.go index 4efca19b..aa5f5033 100644 --- a/integration/oidc_explicit_test.go +++ b/integration/oidc_explicit_test.go @@ -19,6 +19,7 @@ import ( "authelia.com/provider/oauth2" "authelia.com/provider/oauth2/compose" "authelia.com/provider/oauth2/handler/openid" + "authelia.com/provider/oauth2/internal/consts" "authelia.com/provider/oauth2/internal/gen" "authelia.com/provider/oauth2/token/jwt" ) @@ -50,7 +51,7 @@ func TestOpenIDConnectExplicitFlow(t *testing.T) { session: newIDSession(&jwt.IDTokenClaims{Subject: "peter"}), description: "should pass", setup: func(oauthClient *xoauth2.Config) string { - oauthClient.Scopes = []string{"openid"} + oauthClient.Scopes = []string{consts.ScopeOpenID} return oauthClient.AuthCodeURL("12345678901234567890") + "&nonce=11234123" }, authStatusCode: http.StatusOK, @@ -59,7 +60,7 @@ func TestOpenIDConnectExplicitFlow(t *testing.T) { session: newIDSession(&jwt.IDTokenClaims{Subject: "peter"}), description: "should fail registered single redirect uri but no redirect uri in request", setup: func(oauthClient *xoauth2.Config) string { - oauthClient.Scopes = []string{"openid"} + oauthClient.Scopes = []string{consts.ScopeOpenID} oauthClient.RedirectURL = "" return oauthClient.AuthCodeURL("12345678901234567890") + "&nonce=11234123" @@ -71,7 +72,7 @@ func TestOpenIDConnectExplicitFlow(t *testing.T) { session: newIDSession(&jwt.IDTokenClaims{Subject: "peter"}), description: "should fail because nonce is not long enough", setup: func(oauthClient *xoauth2.Config) string { - oauthClient.Scopes = []string{"openid"} + oauthClient.Scopes = []string{consts.ScopeOpenID} return oauthClient.AuthCodeURL("12345678901234567890") + "&nonce=1" }, authStatusCode: http.StatusOK, @@ -81,7 +82,7 @@ func TestOpenIDConnectExplicitFlow(t *testing.T) { session: newIDSession(&jwt.IDTokenClaims{Subject: "peter"}), description: "should fail because state is not long enough", setup: func(oauthClient *xoauth2.Config) string { - oauthClient.Scopes = []string{"openid"} + oauthClient.Scopes = []string{consts.ScopeOpenID} return oauthClient.AuthCodeURL("123") + "&nonce=1234567890" }, expectAuthErr: "invalid_state", @@ -95,7 +96,7 @@ func TestOpenIDConnectExplicitFlow(t *testing.T) { }), description: "should pass", setup: func(oauthClient *xoauth2.Config) string { - oauthClient.Scopes = []string{"openid"} + oauthClient.Scopes = []string{consts.ScopeOpenID} return oauthClient.AuthCodeURL("12345678901234567890") + "&nonce=1234567890&prompt=login" }, authStatusCode: http.StatusOK, @@ -109,7 +110,7 @@ func TestOpenIDConnectExplicitFlow(t *testing.T) { description: "should not pass missing redirect uri", setup: func(oauthClient *xoauth2.Config) string { oauthClient.RedirectURL = "" - oauthClient.Scopes = []string{"openid"} + oauthClient.Scopes = []string{consts.ScopeOpenID} return oauthClient.AuthCodeURL("12345678901234567890") + "&nonce=1234567890&prompt=login" }, expectAuthErr: `{"error":"invalid_request","error_description":"The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. The 'redirect_uri' parameter is required when using OpenID Connect 1.0."}`, @@ -123,7 +124,7 @@ func TestOpenIDConnectExplicitFlow(t *testing.T) { }), description: "should fail because authentication was in the past", setup: func(oauthClient *xoauth2.Config) string { - oauthClient.Scopes = []string{"openid"} + oauthClient.Scopes = []string{consts.ScopeOpenID} return oauthClient.AuthCodeURL("12345678901234567890") + "&nonce=1234567890&prompt=login" }, authStatusCode: http.StatusNotAcceptable, // code from internal test callback handler when error occurs @@ -137,7 +138,7 @@ func TestOpenIDConnectExplicitFlow(t *testing.T) { }), description: "should pass because authorization was in the past and no login was required", setup: func(oauthClient *xoauth2.Config) string { - oauthClient.Scopes = []string{"openid"} + oauthClient.Scopes = []string{consts.ScopeOpenID} return oauthClient.AuthCodeURL("12345678901234567890") + "&nonce=1234567890&prompt=none" }, authStatusCode: http.StatusOK, diff --git a/integration/oidc_implicit_hybrid_public_client_pkce_test.go b/integration/oidc_implicit_hybrid_public_client_pkce_test.go index 07ed9928..1c4055c8 100644 --- a/integration/oidc_implicit_hybrid_public_client_pkce_test.go +++ b/integration/oidc_implicit_hybrid_public_client_pkce_test.go @@ -20,6 +20,7 @@ import ( "authelia.com/provider/oauth2" "authelia.com/provider/oauth2/compose" "authelia.com/provider/oauth2/handler/openid" + "authelia.com/provider/oauth2/internal/consts" "authelia.com/provider/oauth2/internal/gen" "authelia.com/provider/oauth2/token/jwt" ) @@ -43,7 +44,7 @@ func TestOIDCImplicitFlowPublicClientPKCE(t *testing.T) { oauthClient.ClientSecret = "" oauthClient.ClientID = "public-client" - oauthClient.Scopes = []string{"openid"} + oauthClient.Scopes = []string{consts.ScopeOpenID} store.Clients["public-client"].(*oauth2.DefaultClient).RedirectURIs[0] = ts.URL + "/callback" @@ -86,17 +87,17 @@ func TestOIDCImplicitFlowPublicClientPKCE(t *testing.T) { fragment, err := url.ParseQuery(callbackURL.Fragment) require.NoError(t, err) - code := fragment.Get("code") + code := fragment.Get(consts.FormParameterAuthorizationCode) assert.NotEmpty(t, code) - assert.NotEmpty(t, fragment.Get("id_token")) + assert.NotEmpty(t, fragment.Get(consts.AccessResponseIDToken)) resp, err = http.PostForm(oauthClient.Endpoint.TokenURL, url.Values{ - "code": {code}, - "grant_type": {"authorization_code"}, - "client_id": {"public-client"}, - "redirect_uri": {ts.URL + "/callback"}, - "code_verifier": {c.codeVerifier}, + consts.FormParameterAuthorizationCode: {code}, + consts.FormParameterGrantType: {consts.GrantTypeAuthorizationCode}, + consts.FormParameterClientID: {"public-client"}, + consts.FormParameterRedirectURI: {ts.URL + "/callback"}, + consts.FormParameterCodeVerifier: {c.codeVerifier}, }) require.NoError(t, err) defer resp.Body.Close() diff --git a/integration/oidc_implicit_hybrid_test.go b/integration/oidc_implicit_hybrid_test.go index 79d17644..fbb0d1e9 100644 --- a/integration/oidc_implicit_hybrid_test.go +++ b/integration/oidc_implicit_hybrid_test.go @@ -68,7 +68,7 @@ func TestOIDCImplicitFlow(t *testing.T) { nonce: "1111111111111111", description: "should pass id token (id_token token)", setup: func() { - oauthClient.Scopes = []string{"oauth2", "openid"} + oauthClient.Scopes = []string{"oauth2", consts.ScopeOpenID} }, hasToken: true, hasIdToken: true, diff --git a/integration/pushed_authorize_code_grant_test.go b/integration/pushed_authorize_code_grant_test.go index 503e152f..4f9ebfda 100644 --- a/integration/pushed_authorize_code_grant_test.go +++ b/integration/pushed_authorize_code_grant_test.go @@ -19,6 +19,7 @@ import ( "authelia.com/provider/oauth2" "authelia.com/provider/oauth2/compose" hoauth2 "authelia.com/provider/oauth2/handler/oauth2" + "authelia.com/provider/oauth2/internal/consts" ) func TestPushedAuthorizeCodeFlow(t *testing.T) { @@ -50,7 +51,7 @@ func runPushedAuthorizeCodeGrantTest(t *testing.T, strategy any) { }{ { description: "should fail because of audience", - params: map[string]string{"audience": "https://www.authelia.com/not-api"}, + params: map[string]string{consts.FormParameterAudience: "https://www.authelia.com/not-api"}, setup: func() { oauthClient = newOAuth2Client(ts) state = "12345678901234567890" @@ -71,7 +72,7 @@ func runPushedAuthorizeCodeGrantTest(t *testing.T, strategy any) { }, { description: "should pass with proper audience", - params: map[string]string{"audience": "https://www.authelia.com/api"}, + params: map[string]string{consts.FormParameterAudience: "https://www.authelia.com/api"}, setup: func() { oauthClient = newOAuth2Client(ts) state = "12345678901234567890" @@ -103,12 +104,12 @@ func runPushedAuthorizeCodeGrantTest(t *testing.T, strategy any) { // build request from the OAuth client data := url.Values{} - data.Set("client_id", oauthClient.ClientID) - data.Set("client_secret", oauthClient.ClientSecret) - data.Set("response_type", "code") - data.Set("state", state) - data.Set("scope", strings.Join(oauthClient.Scopes, " ")) - data.Set("redirect_uri", oauthClient.RedirectURL) + data.Set(consts.FormParameterClientID, oauthClient.ClientID) + data.Set(consts.FormParameterClientSecret, oauthClient.ClientSecret) + data.Set(consts.FormParameterResponseType, consts.ResponseTypeAuthorizationCodeFlow) + data.Set(consts.FormParameterState, state) + data.Set(consts.FormParameterScope, strings.Join(oauthClient.Scopes, " ")) + data.Set(consts.FormParameterRedirectURI, oauthClient.RedirectURL) for k, v := range c.params { data.Set(k, v) } @@ -116,7 +117,7 @@ func runPushedAuthorizeCodeGrantTest(t *testing.T, strategy any) { req, err := http.NewRequest("POST", ts.URL+"/par", strings.NewReader(data.Encode())) require.NoError(t, err) - req.Header.Add("Content-Type", "application/x-www-form-urlencoded") + req.Header.Add(consts.HeaderContentType, consts.ContentTypeApplicationURLEncodedForm) resp, err := http.DefaultClient.Do(req) require.NoError(t, err) @@ -134,23 +135,23 @@ func runPushedAuthorizeCodeGrantTest(t *testing.T, strategy any) { assert.NoError(t, err, "Error occurred when unamrshaling the body: %v", err) // validate request_uri - requestURI, _ := m["request_uri"].(string) + requestURI, _ := m[consts.FormParameterRequestURI].(string) assert.NotEmpty(t, requestURI, "request_uri is empty") assert.Condition(t, func() bool { - return strings.HasPrefix(requestURI, "urn:ietf:params:oauth:request_uri:") + return strings.HasPrefix(requestURI, consts.PrefixRequestURI) }, "PAR Prefix is incorrect: %s", requestURI) // validate expires_in - assert.EqualValues(t, 300, int(m["expires_in"].(float64)), "Invalid expires_in value=%v", m["expires_in"]) + assert.EqualValues(t, 300, int(m[consts.AccessResponseExpiresIn].(float64)), "Invalid expires_in value=%v", m[consts.AccessResponseExpiresIn]) // call authorize data = url.Values{} - data.Set("client_id", oauthClient.ClientID) - data.Set("request_uri", m["request_uri"].(string)) + data.Set(consts.FormParameterClientID, oauthClient.ClientID) + data.Set(consts.FormParameterRequestURI, m[consts.FormParameterRequestURI].(string)) req, err = http.NewRequest("POST", ts.URL+"/auth", strings.NewReader(data.Encode())) require.NoError(t, err) - req.Header.Add("Content-Type", "application/x-www-form-urlencoded") + req.Header.Add(consts.HeaderContentType, consts.ContentTypeApplicationURLEncodedForm) resp, err = http.DefaultClient.Do(req) require.NoError(t, err) diff --git a/integration/refresh_token_grant_test.go b/integration/refresh_token_grant_test.go index e5f444aa..30213ee1 100644 --- a/integration/refresh_token_grant_test.go +++ b/integration/refresh_token_grant_test.go @@ -20,6 +20,7 @@ import ( "authelia.com/provider/oauth2" "authelia.com/provider/oauth2/compose" "authelia.com/provider/oauth2/handler/openid" + "authelia.com/provider/oauth2/internal/consts" "authelia.com/provider/oauth2/internal/gen" "authelia.com/provider/oauth2/token/jwt" ) @@ -64,7 +65,7 @@ func TestRefreshTokenFlow(t *testing.T) { RedirectURIs: []string{ts.URL + "/callback"}, ResponseTypes: []string{"id_token", "code", "token", "token code", "id_token code", "token id_token", "token code id_token"}, GrantTypes: []string{"implicit", "refresh_token", "authorization_code", "password", "client_credentials"}, - Scopes: []string{"oauth2", "offline", "openid"}, + Scopes: []string{"oauth2", consts.ScopeOffline, consts.ScopeOpenID}, Audience: []string{"https://www.authelia.com/api"}, } @@ -90,7 +91,7 @@ func TestRefreshTokenFlow(t *testing.T) { { description: "should pass but not yield id token", setup: func(t *testing.T) { - oauthClient.Scopes = []string{"offline"} + oauthClient.Scopes = []string{consts.ScopeOffline} }, pass: true, check: func(t *testing.T, original, refreshed *xoauth2.Token, or, rr *introspectionResponse) { @@ -103,7 +104,7 @@ func TestRefreshTokenFlow(t *testing.T) { description: "should pass and yield id token", params: []xoauth2.AuthCodeOption{xoauth2.SetAuthURLParam("audience", "https://www.authelia.com/api")}, setup: func(t *testing.T) { - oauthClient.Scopes = []string{"oauth2", "offline", "openid"} + oauthClient.Scopes = []string{"oauth2", consts.ScopeOffline, consts.ScopeOpenID} }, pass: true, check: func(t *testing.T, original, refreshed *xoauth2.Token, or, rr *introspectionResponse) { @@ -137,10 +138,10 @@ func TestRefreshTokenFlow(t *testing.T) { description: "should fail because scope is no longer allowed", setup: func(t *testing.T) { oauthClient.ClientID = refreshCheckClient.ID - oauthClient.Scopes = []string{"oauth2", "offline", "openid"} + oauthClient.Scopes = []string{"oauth2", consts.ScopeOffline, consts.ScopeOpenID} }, beforeRefresh: func(t *testing.T) { - refreshCheckClient.Scopes = []string{"offline", "openid"} + refreshCheckClient.Scopes = []string{consts.ScopeOffline, consts.ScopeOpenID} }, pass: false, }, @@ -149,8 +150,8 @@ func TestRefreshTokenFlow(t *testing.T) { params: []xoauth2.AuthCodeOption{xoauth2.SetAuthURLParam("audience", "https://www.authelia.com/api")}, setup: func(t *testing.T) { oauthClient.ClientID = refreshCheckClient.ID - oauthClient.Scopes = []string{"oauth2", "offline", "openid"} - refreshCheckClient.Scopes = []string{"oauth2", "offline", "openid"} + oauthClient.Scopes = []string{"oauth2", consts.ScopeOffline, consts.ScopeOpenID} + refreshCheckClient.Scopes = []string{"oauth2", consts.ScopeOffline, consts.ScopeOpenID} }, beforeRefresh: func(t *testing.T) { refreshCheckClient.Audience = []string{"https://https://www.not-authelia.com//api"} @@ -167,7 +168,7 @@ func TestRefreshTokenFlow(t *testing.T) { ts = mockServer(t, f, session) oauthClient = newOAuth2Client(ts) - oauthClient.Scopes = []string{"oauth2", "offline", "openid"} + oauthClient.Scopes = []string{"oauth2", consts.ScopeOffline, consts.ScopeOpenID} store.Clients["my-client"].(*oauth2.DefaultClient).RedirectURIs[0] = ts.URL + "/callback" }, pass: false, @@ -182,7 +183,7 @@ func TestRefreshTokenFlow(t *testing.T) { ts = mockServer(t, f, session) oauthClient = newOAuth2Client(ts) - oauthClient.Scopes = []string{"oauth2", "offline", "openid"} + oauthClient.Scopes = []string{"oauth2", consts.ScopeOffline, consts.ScopeOpenID} store.Clients["my-client"].(*oauth2.DefaultClient).RedirectURIs[0] = ts.URL + "/callback" }, beforeRefresh: func(t *testing.T) { @@ -194,7 +195,7 @@ func TestRefreshTokenFlow(t *testing.T) { { description: "should deny access if original token was reused", setup: func(t *testing.T) { - oauthClient.Scopes = []string{"offline"} + oauthClient.Scopes = []string{consts.ScopeOffline} }, pass: true, check: func(t *testing.T, original, refreshed *xoauth2.Token, or, rr *introspectionResponse) { @@ -218,7 +219,7 @@ func TestRefreshTokenFlow(t *testing.T) { req, err := http.NewRequest("POST", ts.URL+"/introspect", strings.NewReader(url.Values{"token": {token}}.Encode())) require.NoError(t, err) req.SetBasicAuth("refresh-client", "foobar") - req.Header.Set("Content-Type", "application/x-www-form-urlencoded") + req.Header.Set(consts.HeaderContentType, consts.ContentTypeApplicationURLEncodedForm) r, err := http.DefaultClient.Do(req) require.NoError(t, err) assert.Equal(t, http.StatusOK, r.StatusCode) diff --git a/integration/resource_owner_password_credentials_grant_test.go b/integration/resource_owner_password_credentials_grant_test.go index 34ec8f9e..ccdcfa5b 100644 --- a/integration/resource_owner_password_credentials_grant_test.go +++ b/integration/resource_owner_password_credentials_grant_test.go @@ -17,6 +17,7 @@ import ( "authelia.com/provider/oauth2/compose" hoauth2 "authelia.com/provider/oauth2/handler/oauth2" "authelia.com/provider/oauth2/internal" + "authelia.com/provider/oauth2/internal/consts" ) func TestResourceOwnerPasswordCredentialsFlow(t *testing.T) { @@ -68,7 +69,7 @@ func runResourceOwnerPasswordCredentialsGrantTest(t *testing.T, strategy hoauth2 require.NoError(t, err) atExp := s.GetSession().GetExpiresAt(oauth2.AccessToken) internal.RequireEqualTime(t, time.Now().UTC().Add(*internal.TestLifespans.PasswordGrantAccessTokenLifespan), atExp, time.Minute) - atExpIn := time.Duration(token.Extra("expires_in").(float64)) * time.Second + atExpIn := time.Duration(token.Extra(consts.AccessResponseExpiresIn).(float64)) * time.Second internal.RequireEqualDuration(t, *internal.TestLifespans.PasswordGrantAccessTokenLifespan, atExpIn, time.Minute) rtExp := s.GetSession().GetExpiresAt(oauth2.RefreshToken) internal.RequireEqualTime(t, time.Now().UTC().Add(*internal.TestLifespans.PasswordGrantRefreshTokenLifespan), rtExp, time.Minute) diff --git a/integration/revoke_token_test.go b/integration/revoke_token_test.go index 70db2ea2..847a3bb6 100644 --- a/integration/revoke_token_test.go +++ b/integration/revoke_token_test.go @@ -15,6 +15,7 @@ import ( "authelia.com/provider/oauth2" "authelia.com/provider/oauth2/compose" hoauth2 "authelia.com/provider/oauth2/handler/oauth2" + "authelia.com/provider/oauth2/internal/consts" ) func TestRevokeToken(t *testing.T) { @@ -50,7 +51,7 @@ func runRevokeTokenTest(t *testing.T, strategy hoauth2.AccessTokenStrategy) { assert.Equal(t, 200, resp.StatusCode) hres, _, errs := gorequest.New().Get(ts.URL+"/info"). - Set("Authorization", "bearer "+token.AccessToken). + Set(consts.HeaderAuthorization, "bearer "+token.AccessToken). End() require.Len(t, errs, 0) assert.Equal(t, http.StatusUnauthorized, hres.StatusCode) diff --git a/internal/consts/http.go b/internal/consts/http.go new file mode 100644 index 00000000..69a60ee7 --- /dev/null +++ b/internal/consts/http.go @@ -0,0 +1,25 @@ +package consts + +const ( + HeaderContentType = "Content-Type" + HeaderCacheControl = "Cache-Control" + HeaderPragma = "Pragma" + HeaderAuthorization = "Authorization" + HeaderLocation = "Location" +) + +const ( + ContentTypeApplicationURLEncodedForm = "application/x-www-form-urlencoded" + ContentTypeApplicationJSON = "application/json; charset=utf-8" + ContentTypeTextHTML = "text/html; charset=utf-8" +) + +const ( + PragmaNoCache = "no-cache" + CacheControlNoStore = "no-store" +) + +const ( + SchemeHTTP = "http" + SchemeHTTPS = "https" +) diff --git a/internal/consts/spec.go b/internal/consts/spec.go index 4d2f37eb..bbf3c2cb 100644 --- a/internal/consts/spec.go +++ b/internal/consts/spec.go @@ -16,3 +16,12 @@ const ( const ( ClientAssertionTypeJWTBearer = "urn:ietf:params:oauth:client-assertion-type:jwt-bearer" ) + +const ( + PrefixRequestURI = "urn:ietf:params:oauth:request_uri:" +) + +const ( + TokenTypeAccessToken = "access_token" + TokenTypeRefreshToken = "refresh_token" +) diff --git a/introspect.go b/introspect.go index 1661cca6..1fcbd00b 100644 --- a/introspect.go +++ b/introspect.go @@ -23,7 +23,7 @@ func AccessTokenFromRequest(req *http.Request) string { // - Form-Encoded Body Parameter. Recommended, more likely to appear. e.g.: Authorization: Bearer mytoken123 // - URI Query Parameter e.g. access_token=mytoken123 - auth := req.Header.Get("Authorization") + auth := req.Header.Get(consts.HeaderAuthorization) split := strings.SplitN(auth, " ", 2) if len(split) != 2 || !strings.EqualFold(split[0], BearerAccessToken) { // Nothing in Authorization header, try access_token diff --git a/introspect_test.go b/introspect_test.go index 8f3d5ffa..11015f9b 100644 --- a/introspect_test.go +++ b/introspect_test.go @@ -16,6 +16,7 @@ import ( . "authelia.com/provider/oauth2" "authelia.com/provider/oauth2/compose" "authelia.com/provider/oauth2/internal" + "authelia.com/provider/oauth2/internal/consts" "authelia.com/provider/oauth2/storage" ) @@ -29,7 +30,7 @@ func TestAccessTokenFromRequestHeader(t *testing.T) { token := "TokenFromHeader" req, _ := http.NewRequest("GET", "http://example.com/test", nil) - req.Header.Add("Authorization", "Bearer "+token) + req.Header.Add(consts.HeaderAuthorization, "Bearer "+token) assert.Equal(t, AccessTokenFromRequest(req), token, "Token should be obtainable from header") } @@ -51,7 +52,7 @@ func TestIntrospect(t *testing.T) { provider := compose.ComposeAllEnabled(config, storage.NewMemoryStore(), nil).(*Fosite) req, _ := http.NewRequest("GET", "http://example.com/test", nil) - req.Header.Add("Authorization", "bearer some-token") + req.Header.Add(consts.HeaderAuthorization, "bearer some-token") for k, c := range []struct { description string diff --git a/introspection_request_handler.go b/introspection_request_handler.go index e6d7c361..5e0fbf7d 100644 --- a/introspection_request_handler.go +++ b/introspection_request_handler.go @@ -9,9 +9,9 @@ import ( "net/url" "strings" - "authelia.com/provider/oauth2/internal/consts" "golang.org/x/text/language" + "authelia.com/provider/oauth2/internal/consts" "authelia.com/provider/oauth2/internal/errorsx" ) diff --git a/introspection_request_handler_test.go b/introspection_request_handler_test.go index fe4d3fcb..054739e2 100644 --- a/introspection_request_handler_test.go +++ b/introspection_request_handler_test.go @@ -19,6 +19,7 @@ import ( . "authelia.com/provider/oauth2" "authelia.com/provider/oauth2/compose" "authelia.com/provider/oauth2/internal" + "authelia.com/provider/oauth2/internal/consts" "authelia.com/provider/oauth2/storage" ) @@ -34,7 +35,7 @@ func TestIntrospectionResponseTokenUse(t *testing.T) { httpreq := &http.Request{ Method: "POST", Header: http.Header{ - "Authorization": []string{"bearer some-token"}, + consts.HeaderAuthorization: []string{"bearer some-token"}, }, PostForm: url.Values{ "token": []string{"introspect-token"}, @@ -122,7 +123,7 @@ func TestNewIntrospectionRequest(t *testing.T) { httpreq = &http.Request{ Method: "POST", Header: http.Header{ - "Authorization": []string{"bearer some-token"}, + consts.HeaderAuthorization: []string{"bearer some-token"}, }, PostForm: url.Values{ "token": []string{"introspect-token"}, @@ -141,7 +142,7 @@ func TestNewIntrospectionRequest(t *testing.T) { httpreq = &http.Request{ Method: "POST", Header: http.Header{ - "Authorization": []string{"bearer some-token"}, + consts.HeaderAuthorization: []string{"bearer some-token"}, }, PostForm: url.Values{ "token": []string{"introspect-token"}, @@ -160,7 +161,7 @@ func TestNewIntrospectionRequest(t *testing.T) { Method: "POST", Header: http.Header{ //Basic Authorization with username=encoded:client and password=encoded&password - "Authorization": []string{"Basic ZW5jb2RlZCUzQWNsaWVudDplbmNvZGVkJTI2cGFzc3dvcmQ="}, + consts.HeaderAuthorization: []string{"Basic ZW5jb2RlZCUzQWNsaWVudDplbmNvZGVkJTI2cGFzc3dvcmQ="}, }, PostForm: url.Values{ "token": []string{"introspect-token"}, @@ -178,7 +179,7 @@ func TestNewIntrospectionRequest(t *testing.T) { Method: "POST", Header: http.Header{ //Basic Authorization with username=my-client and password=foobar - "Authorization": []string{"Basic bXktY2xpZW50OmZvb2Jhcg=="}, + consts.HeaderAuthorization: []string{"Basic bXktY2xpZW50OmZvb2Jhcg=="}, }, PostForm: url.Values{ "token": []string{"introspect-token"}, @@ -196,7 +197,7 @@ func TestNewIntrospectionRequest(t *testing.T) { Method: "POST", Header: http.Header{ //Basic Authorization with username=my-client and password=foobaz - "Authorization": []string{"Basic bXktY2xpZW50OmZvb2Jheg=="}, + consts.HeaderAuthorization: []string{"Basic bXktY2xpZW50OmZvb2Jheg=="}, }, PostForm: url.Values{ "token": []string{"introspect-token"}, diff --git a/introspection_response_writer.go b/introspection_response_writer.go index e3f1abf0..8b27bac1 100644 --- a/introspection_response_writer.go +++ b/introspection_response_writer.go @@ -9,8 +9,9 @@ import ( "net/http" "strings" - "authelia.com/provider/oauth2/internal/consts" "github.com/pkg/errors" + + "authelia.com/provider/oauth2/internal/consts" ) // WriteIntrospectionError responds with token metadata discovered by token introspection as defined in @@ -45,9 +46,9 @@ func (f *Fosite) WriteIntrospectionError(ctx context.Context, rw http.ResponseWr return } - rw.Header().Set("Content-Type", "application/json;charset=UTF-8") - rw.Header().Set("Cache-Control", "no-store") - rw.Header().Set("Pragma", "no-cache") + rw.Header().Set(consts.HeaderContentType, consts.ContentTypeApplicationJSON) + rw.Header().Set(consts.HeaderCacheControl, consts.CacheControlNoStore) + rw.Header().Set(consts.HeaderPragma, consts.PragmaNoCache) _ = json.NewEncoder(rw).Encode(struct { Active bool `json:"active"` }{Active: false}) @@ -227,8 +228,8 @@ func (f *Fosite) WriteIntrospectionResponse(ctx context.Context, rw http.Respons response[consts.ClaimUsername] = r.GetAccessRequester().GetSession().GetUsername() } - rw.Header().Set("Content-Type", "application/json;charset=UTF-8") - rw.Header().Set("Cache-Control", "no-store") - rw.Header().Set("Pragma", "no-cache") + rw.Header().Set(consts.HeaderContentType, consts.ContentTypeApplicationJSON) + rw.Header().Set(consts.HeaderCacheControl, consts.CacheControlNoStore) + rw.Header().Set(consts.HeaderPragma, consts.PragmaNoCache) _ = json.NewEncoder(rw).Encode(response) } diff --git a/introspection_response_writer_test.go b/introspection_response_writer_test.go index d2ebc3c6..5394e5bd 100644 --- a/introspection_response_writer_test.go +++ b/introspection_response_writer_test.go @@ -18,6 +18,7 @@ import ( . "authelia.com/provider/oauth2" "authelia.com/provider/oauth2/internal" + "authelia.com/provider/oauth2/internal/consts" "authelia.com/provider/oauth2/internal/errorsx" ) @@ -116,7 +117,7 @@ func TestWriteIntrospectionResponseBody(t *testing.T) { sess := &DefaultSession{} sess.GetExtraClaims()["extra"] = "foobar" // We try to set these, but they should be ignored. - for _, field := range []string{"exp", "client_id", "scope", "iat", "sub", "aud", "username"} { + for _, field := range []string{consts.ClaimExpirationTime, consts.ClaimClientIdentifier, consts.ClaimScope, consts.ClaimIssuedAt, consts.ClaimSubject, consts.ClaimAudience, consts.ClaimUsername} { sess.GetExtraClaims()[field] = "invalid" } sess.SetExpiresAt(ires.TokenUse, time.Time{}) diff --git a/oauth2.go b/oauth2.go index 0033af66..419b3112 100644 --- a/oauth2.go +++ b/oauth2.go @@ -21,8 +21,8 @@ type TokenType string type GrantType string const ( - AccessToken TokenType = "access_token" - RefreshToken TokenType = "refresh_token" + AccessToken TokenType = consts.TokenTypeAccessToken + RefreshToken TokenType = consts.TokenTypeRefreshToken AuthorizeCode TokenType = "authorize_code" IDToken TokenType = "id_token" // PushedAuthorizeRequestContext represents the PAR context object diff --git a/pushed_authorize_request_handler_test.go b/pushed_authorize_request_handler_test.go index 00427649..1c9d6c11 100644 --- a/pushed_authorize_request_handler_test.go +++ b/pushed_authorize_request_handler_test.go @@ -16,6 +16,7 @@ import ( . "authelia.com/provider/oauth2" "authelia.com/provider/oauth2/internal" + "authelia.com/provider/oauth2/internal/consts" ) // Should pass @@ -76,7 +77,7 @@ func TestNewPushedAuthorizeRequest(t *testing.T) { { desc: "invalid client fails", provider: provider, - query: url.Values{"redirect_uri": []string{"https://foo.bar/cb"}}, + query: url.Values{consts.FormParameterRedirectURI: []string{"https://foo.bar/cb"}}, expectedError: ErrInvalidClient, mock: func() {}, }, @@ -85,8 +86,8 @@ func TestNewPushedAuthorizeRequest(t *testing.T) { desc: "client and request redirects mismatch", provider: provider, query: url.Values{ - "client_id": []string{"1234"}, - "client_secret": []string{"1234"}, + consts.FormParameterClientID: []string{"1234"}, + consts.FormParameterClientSecret: []string{"1234"}, }, expectedError: ErrInvalidRequest, mock: func() { @@ -99,9 +100,9 @@ func TestNewPushedAuthorizeRequest(t *testing.T) { desc: "client and request redirects mismatch", provider: provider, query: url.Values{ - "redirect_uri": []string{""}, - "client_id": []string{"1234"}, - "client_secret": []string{"1234"}, + consts.FormParameterRedirectURI: []string{""}, + consts.FormParameterClientID: []string{"1234"}, + consts.FormParameterClientSecret: []string{"1234"}, }, expectedError: ErrInvalidRequest, mock: func() { @@ -114,9 +115,9 @@ func TestNewPushedAuthorizeRequest(t *testing.T) { desc: "client and request redirects mismatch", provider: provider, query: url.Values{ - "redirect_uri": []string{"https://foo.bar/cb"}, - "client_id": []string{"1234"}, - "client_secret": []string{"1234"}, + consts.FormParameterRedirectURI: []string{"https://foo.bar/cb"}, + consts.FormParameterClientID: []string{"1234"}, + consts.FormParameterClientSecret: []string{"1234"}, }, expectedError: ErrInvalidRequest, mock: func() { @@ -129,10 +130,10 @@ func TestNewPushedAuthorizeRequest(t *testing.T) { desc: "no state", provider: provider, query: url.Values{ - "redirect_uri": []string{"https://foo.bar/cb"}, - "client_id": []string{"1234"}, - "client_secret": []string{"1234"}, - "response_type": []string{"code"}, + consts.FormParameterRedirectURI: []string{"https://foo.bar/cb"}, + consts.FormParameterClientID: []string{"1234"}, + consts.FormParameterClientSecret: []string{"1234"}, + consts.FormParameterResponseType: []string{consts.ResponseTypeAuthorizationCodeFlow}, }, expectedError: ErrInvalidState, mock: func() { @@ -145,11 +146,11 @@ func TestNewPushedAuthorizeRequest(t *testing.T) { desc: "short state", provider: provider, query: url.Values{ - "redirect_uri": {"https://foo.bar/cb"}, - "client_id": {"1234"}, - "client_secret": []string{"1234"}, - "response_type": {"code"}, - "state": {"short"}, + consts.FormParameterRedirectURI: {"https://foo.bar/cb"}, + consts.FormParameterClientID: {"1234"}, + consts.FormParameterClientSecret: []string{"1234"}, + consts.FormParameterResponseType: {"code"}, + consts.FormParameterState: {"short"}, }, expectedError: ErrInvalidState, mock: func() { @@ -162,12 +163,12 @@ func TestNewPushedAuthorizeRequest(t *testing.T) { desc: "should fail because client does not have scope baz", provider: provider, query: url.Values{ - "redirect_uri": {"https://foo.bar/cb"}, - "client_id": {"1234"}, - "client_secret": []string{"1234"}, - "response_type": {"code token"}, - "state": {"strong-state"}, - "scope": {"foo bar baz"}, + consts.FormParameterRedirectURI: {"https://foo.bar/cb"}, + consts.FormParameterClientID: {"1234"}, + consts.FormParameterClientSecret: []string{"1234"}, + consts.FormParameterResponseType: []string{consts.ResponseTypeHybridFlowToken}, + consts.FormParameterState: {"strong-state"}, + consts.FormParameterScope: {"foo bar baz"}, }, mock: func() { store.EXPECT().GetClient(gomock.Any(), "1234").Return(&DefaultClient{RedirectURIs: []string{"https://foo.bar/cb"}, Scopes: []string{"foo", "bar"}, Secret: []byte("1234")}, nil).MaxTimes(2) @@ -180,18 +181,18 @@ func TestNewPushedAuthorizeRequest(t *testing.T) { desc: "should fail because client does not have scope baz", provider: provider, query: url.Values{ - "redirect_uri": {"https://foo.bar/cb"}, - "client_id": {"1234"}, - "client_secret": []string{"1234"}, - "response_type": {"code token"}, - "state": {"strong-state"}, - "scope": {"foo bar"}, - "audience": {"https://cloud.ory.sh/api https://www.authelia.com/api"}, + consts.FormParameterRedirectURI: {"https://foo.bar/cb"}, + consts.FormParameterClientID: {"1234"}, + consts.FormParameterClientSecret: []string{"1234"}, + consts.FormParameterResponseType: []string{consts.ResponseTypeHybridFlowToken}, + consts.FormParameterState: {"strong-state"}, + consts.FormParameterScope: {"foo bar"}, + consts.FormParameterAudience: {"https://cloud.authelia.com/api https://www.authelia.com/api"}, }, mock: func() { store.EXPECT().GetClient(gomock.Any(), "1234").Return(&DefaultClient{ RedirectURIs: []string{"https://foo.bar/cb"}, Scopes: []string{"foo", "bar"}, - Audience: []string{"https://cloud.ory.sh/api"}, + Audience: []string{"https://cloud.authelia.com/api"}, Secret: []byte("1234"), }, nil).MaxTimes(2) hasher.EXPECT().Compare(ctx, gomock.Eq([]byte("1234")), gomock.Eq([]byte("1234"))).Return(nil) @@ -203,20 +204,20 @@ func TestNewPushedAuthorizeRequest(t *testing.T) { desc: "should pass", provider: provider, query: url.Values{ - "redirect_uri": {"https://foo.bar/cb"}, - "client_id": {"1234"}, - "client_secret": []string{"1234"}, - "response_type": {"code token"}, - "state": {"strong-state"}, - "scope": {"foo bar"}, - "audience": {"https://cloud.ory.sh/api https://www.authelia.com/api"}, + consts.FormParameterRedirectURI: {"https://foo.bar/cb"}, + consts.FormParameterClientID: {"1234"}, + consts.FormParameterClientSecret: []string{"1234"}, + consts.FormParameterResponseType: []string{consts.ResponseTypeHybridFlowToken}, + consts.FormParameterState: {"strong-state"}, + consts.FormParameterScope: {"foo bar"}, + consts.FormParameterAudience: {"https://cloud.authelia.com/api https://www.authelia.com/api"}, }, mock: func() { store.EXPECT().GetClient(gomock.Any(), "1234").Return(&DefaultClient{ - ResponseTypes: []string{"code token"}, + ResponseTypes: []string{consts.ResponseTypeHybridFlowToken}, RedirectURIs: []string{"https://foo.bar/cb"}, Scopes: []string{"foo", "bar"}, - Audience: []string{"https://cloud.ory.sh/api", "https://www.authelia.com/api"}, + Audience: []string{"https://cloud.authelia.com/api", "https://www.authelia.com/api"}, Secret: []byte("1234"), }, nil).MaxTimes(2) hasher.EXPECT().Compare(ctx, gomock.Eq([]byte("1234")), gomock.Eq([]byte("1234"))).Return(nil) @@ -227,13 +228,13 @@ func TestNewPushedAuthorizeRequest(t *testing.T) { State: "strong-state", Request: Request{ Client: &DefaultClient{ - ResponseTypes: []string{"code token"}, RedirectURIs: []string{"https://foo.bar/cb"}, + ResponseTypes: []string{consts.ResponseTypeHybridFlowToken}, RedirectURIs: []string{"https://foo.bar/cb"}, Scopes: []string{"foo", "bar"}, - Audience: []string{"https://cloud.ory.sh/api", "https://www.authelia.com/api"}, + Audience: []string{"https://cloud.authelia.com/api", "https://www.authelia.com/api"}, Secret: []byte("1234"), }, RequestedScope: []string{"foo", "bar"}, - RequestedAudience: []string{"https://cloud.ory.sh/api", "https://www.authelia.com/api"}, + RequestedAudience: []string{"https://cloud.authelia.com/api", "https://www.authelia.com/api"}, }, }, }, @@ -242,37 +243,37 @@ func TestNewPushedAuthorizeRequest(t *testing.T) { desc: "repeated audience parameter", provider: provider, query: url.Values{ - "redirect_uri": {"https://foo.bar/cb"}, - "client_id": {"1234"}, - "client_secret": []string{"1234"}, - "response_type": {"code token"}, - "state": {"strong-state"}, - "scope": {"foo bar"}, - "audience": {"https://cloud.ory.sh/api", "https://www.authelia.com/api"}, + consts.FormParameterRedirectURI: {"https://foo.bar/cb"}, + consts.FormParameterClientID: {"1234"}, + consts.FormParameterClientSecret: []string{"1234"}, + consts.FormParameterResponseType: []string{consts.ResponseTypeHybridFlowToken}, + consts.FormParameterState: {"strong-state"}, + consts.FormParameterScope: {"foo bar"}, + consts.FormParameterAudience: {"https://cloud.authelia.com/api", "https://www.authelia.com/api"}, }, mock: func() { store.EXPECT().GetClient(gomock.Any(), "1234").Return(&DefaultClient{ - ResponseTypes: []string{"code token"}, + ResponseTypes: []string{consts.ResponseTypeHybridFlowToken}, RedirectURIs: []string{"https://foo.bar/cb"}, Scopes: []string{"foo", "bar"}, - Audience: []string{"https://cloud.ory.sh/api", "https://www.authelia.com/api"}, + Audience: []string{"https://cloud.authelia.com/api", "https://www.authelia.com/api"}, Secret: []byte("1234"), }, nil).MaxTimes(2) hasher.EXPECT().Compare(ctx, gomock.Eq([]byte("1234")), gomock.Eq([]byte("1234"))).Return(nil) }, expect: &AuthorizeRequest{ RedirectURI: redir, - ResponseTypes: []string{"code", "token"}, + ResponseTypes: []string{consts.ResponseTypeAuthorizationCodeFlow, consts.ResponseTypeImplicitFlowToken}, State: "strong-state", Request: Request{ Client: &DefaultClient{ - ResponseTypes: []string{"code token"}, RedirectURIs: []string{"https://foo.bar/cb"}, + ResponseTypes: []string{consts.ResponseTypeHybridFlowToken}, RedirectURIs: []string{"https://foo.bar/cb"}, Scopes: []string{"foo", "bar"}, - Audience: []string{"https://cloud.ory.sh/api", "https://www.authelia.com/api"}, + Audience: []string{"https://cloud.authelia.com/api", "https://www.authelia.com/api"}, Secret: []byte("1234"), }, RequestedScope: []string{"foo", "bar"}, - RequestedAudience: []string{"https://cloud.ory.sh/api", "https://www.authelia.com/api"}, + RequestedAudience: []string{"https://cloud.authelia.com/api", "https://www.authelia.com/api"}, }, }, }, @@ -281,17 +282,17 @@ func TestNewPushedAuthorizeRequest(t *testing.T) { desc: "repeated audience parameter with tricky values", provider: provider, query: url.Values{ - "redirect_uri": {"https://foo.bar/cb"}, - "client_id": {"1234"}, - "client_secret": []string{"1234"}, - "response_type": {"code token"}, - "state": {"strong-state"}, - "scope": {"foo bar"}, - "audience": {"test value", ""}, + consts.FormParameterRedirectURI: {"https://foo.bar/cb"}, + consts.FormParameterClientID: {"1234"}, + consts.FormParameterClientSecret: []string{"1234"}, + consts.FormParameterResponseType: []string{consts.ResponseTypeHybridFlowToken}, + consts.FormParameterState: {"strong-state"}, + consts.FormParameterScope: {"foo bar"}, + consts.FormParameterAudience: {"test value", ""}, }, mock: func() { store.EXPECT().GetClient(gomock.Any(), "1234").Return(&DefaultClient{ - ResponseTypes: []string{"code token"}, + ResponseTypes: []string{consts.ResponseTypeHybridFlowToken}, RedirectURIs: []string{"https://foo.bar/cb"}, Scopes: []string{"foo", "bar"}, Audience: []string{"test value"}, @@ -301,11 +302,11 @@ func TestNewPushedAuthorizeRequest(t *testing.T) { }, expect: &AuthorizeRequest{ RedirectURI: redir, - ResponseTypes: []string{"code", "token"}, + ResponseTypes: []string{consts.ResponseTypeAuthorizationCodeFlow, consts.ResponseTypeImplicitFlowToken}, State: "strong-state", Request: Request{ Client: &DefaultClient{ - ResponseTypes: []string{"code token"}, RedirectURIs: []string{"https://foo.bar/cb"}, + ResponseTypes: []string{consts.ResponseTypeHybridFlowToken}, RedirectURIs: []string{"https://foo.bar/cb"}, Scopes: []string{"foo", "bar"}, Audience: []string{"test value"}, Secret: []byte("1234"), @@ -320,37 +321,37 @@ func TestNewPushedAuthorizeRequest(t *testing.T) { desc: "redirect_uri with special character", provider: provider, query: url.Values{ - "redirect_uri": {"web+application://callback"}, - "client_id": {"1234"}, - "client_secret": []string{"1234"}, - "response_type": {"code token"}, - "state": {"strong-state"}, - "scope": {"foo bar"}, - "audience": {"https://cloud.ory.sh/api https://www.authelia.com/api"}, + consts.FormParameterRedirectURI: {"web+application://callback"}, + consts.FormParameterClientID: {"1234"}, + consts.FormParameterClientSecret: []string{"1234"}, + consts.FormParameterResponseType: []string{consts.ResponseTypeHybridFlowToken}, + consts.FormParameterState: {"strong-state"}, + consts.FormParameterScope: {"foo bar"}, + consts.FormParameterAudience: {"https://cloud.authelia.com/api https://www.authelia.com/api"}, }, mock: func() { store.EXPECT().GetClient(gomock.Any(), "1234").Return(&DefaultClient{ - ResponseTypes: []string{"code token"}, + ResponseTypes: []string{consts.ResponseTypeHybridFlowToken}, RedirectURIs: []string{"web+application://callback"}, Scopes: []string{"foo", "bar"}, - Audience: []string{"https://cloud.ory.sh/api", "https://www.authelia.com/api"}, + Audience: []string{"https://cloud.authelia.com/api", "https://www.authelia.com/api"}, Secret: []byte("1234"), }, nil).MaxTimes(2) hasher.EXPECT().Compare(ctx, gomock.Eq([]byte("1234")), gomock.Eq([]byte("1234"))).Return(nil) }, expect: &AuthorizeRequest{ RedirectURI: specialCharRedir, - ResponseTypes: []string{"code", "token"}, + ResponseTypes: []string{consts.ResponseTypeAuthorizationCodeFlow, consts.ResponseTypeImplicitFlowToken}, State: "strong-state", Request: Request{ Client: &DefaultClient{ - ResponseTypes: []string{"code token"}, RedirectURIs: []string{"web+application://callback"}, + ResponseTypes: []string{consts.ResponseTypeHybridFlowToken}, RedirectURIs: []string{"web+application://callback"}, Scopes: []string{"foo", "bar"}, - Audience: []string{"https://cloud.ory.sh/api", "https://www.authelia.com/api"}, + Audience: []string{"https://cloud.authelia.com/api", "https://www.authelia.com/api"}, Secret: []byte("1234"), }, RequestedScope: []string{"foo", "bar"}, - RequestedAudience: []string{"https://cloud.ory.sh/api", "https://www.authelia.com/api"}, + RequestedAudience: []string{"https://cloud.authelia.com/api", "https://www.authelia.com/api"}, }, }, }, @@ -359,37 +360,37 @@ func TestNewPushedAuthorizeRequest(t *testing.T) { desc: "audience with double spaces between values", provider: provider, query: url.Values{ - "redirect_uri": {"https://foo.bar/cb"}, - "client_id": {"1234"}, - "client_secret": []string{"1234"}, - "response_type": {"code token"}, - "state": {"strong-state"}, - "scope": {"foo bar"}, - "audience": {"https://cloud.ory.sh/api https://www.authelia.com/api"}, + consts.FormParameterRedirectURI: {"https://foo.bar/cb"}, + consts.FormParameterClientID: {"1234"}, + consts.FormParameterClientSecret: []string{"1234"}, + consts.FormParameterResponseType: []string{consts.ResponseTypeHybridFlowToken}, + consts.FormParameterState: {"strong-state"}, + consts.FormParameterScope: {"foo bar"}, + consts.FormParameterAudience: {"https://cloud.authelia.com/api https://www.authelia.com/api"}, }, mock: func() { store.EXPECT().GetClient(gomock.Any(), "1234").Return(&DefaultClient{ - ResponseTypes: []string{"code token"}, + ResponseTypes: []string{consts.ResponseTypeHybridFlowToken}, RedirectURIs: []string{"https://foo.bar/cb"}, Scopes: []string{"foo", "bar"}, - Audience: []string{"https://cloud.ory.sh/api", "https://www.authelia.com/api"}, + Audience: []string{"https://cloud.authelia.com/api", "https://www.authelia.com/api"}, Secret: []byte("1234"), }, nil).MaxTimes(2) hasher.EXPECT().Compare(ctx, gomock.Eq([]byte("1234")), gomock.Eq([]byte("1234"))).Return(nil) }, expect: &AuthorizeRequest{ RedirectURI: redir, - ResponseTypes: []string{"code", "token"}, + ResponseTypes: []string{consts.ResponseTypeAuthorizationCodeFlow, consts.ResponseTypeImplicitFlowToken}, State: "strong-state", Request: Request{ Client: &DefaultClient{ - ResponseTypes: []string{"code token"}, RedirectURIs: []string{"https://foo.bar/cb"}, + ResponseTypes: []string{consts.ResponseTypeHybridFlowToken}, RedirectURIs: []string{"https://foo.bar/cb"}, Scopes: []string{"foo", "bar"}, - Audience: []string{"https://cloud.ory.sh/api", "https://www.authelia.com/api"}, + Audience: []string{"https://cloud.authelia.com/api", "https://www.authelia.com/api"}, Secret: []byte("1234"), }, RequestedScope: []string{"foo", "bar"}, - RequestedAudience: []string{"https://cloud.ory.sh/api", "https://www.authelia.com/api"}, + RequestedAudience: []string{"https://cloud.authelia.com/api", "https://www.authelia.com/api"}, }, }, }, @@ -398,16 +399,16 @@ func TestNewPushedAuthorizeRequest(t *testing.T) { desc: "should fail because unknown response_mode", provider: provider, query: url.Values{ - "redirect_uri": {"https://foo.bar/cb"}, - "client_id": {"1234"}, - "client_secret": []string{"1234"}, - "response_type": {"code token"}, - "state": {"strong-state"}, - "scope": {"foo bar"}, - "response_mode": {"unknown"}, + consts.FormParameterRedirectURI: {"https://foo.bar/cb"}, + consts.FormParameterClientID: {"1234"}, + consts.FormParameterClientSecret: []string{"1234"}, + consts.FormParameterResponseType: []string{consts.ResponseTypeHybridFlowToken}, + consts.FormParameterState: {"strong-state"}, + consts.FormParameterScope: {"foo bar"}, + consts.FormParameterResponseMode: {"unknown"}, }, mock: func() { - store.EXPECT().GetClient(gomock.Any(), "1234").Return(&DefaultClient{RedirectURIs: []string{"https://foo.bar/cb"}, Scopes: []string{"foo", "bar"}, ResponseTypes: []string{"code token"}, Secret: []byte("1234")}, nil).MaxTimes(2) + store.EXPECT().GetClient(gomock.Any(), "1234").Return(&DefaultClient{RedirectURIs: []string{"https://foo.bar/cb"}, Scopes: []string{"foo", "bar"}, ResponseTypes: []string{consts.ResponseTypeHybridFlowToken}, Secret: []byte("1234")}, nil).MaxTimes(2) hasher.EXPECT().Compare(ctx, gomock.Eq([]byte("1234")), gomock.Eq([]byte("1234"))).Return(nil) }, expectedError: ErrUnsupportedResponseMode, @@ -417,16 +418,16 @@ func TestNewPushedAuthorizeRequest(t *testing.T) { desc: "should fail because response_mode is requested but the OAuth 2.0 client doesn't support response mode", provider: provider, query: url.Values{ - "redirect_uri": {"https://foo.bar/cb"}, - "client_id": {"1234"}, - "client_secret": []string{"1234"}, - "response_type": {"code token"}, - "state": {"strong-state"}, - "scope": {"foo bar"}, - "response_mode": {"form_post"}, + consts.FormParameterRedirectURI: {"https://foo.bar/cb"}, + consts.FormParameterClientID: {"1234"}, + consts.FormParameterClientSecret: []string{"1234"}, + consts.FormParameterResponseType: []string{consts.ResponseTypeHybridFlowToken}, + consts.FormParameterState: {"strong-state"}, + consts.FormParameterScope: {"foo bar"}, + consts.FormParameterResponseMode: {consts.ResponseModeFormPost}, }, mock: func() { - store.EXPECT().GetClient(gomock.Any(), "1234").Return(&DefaultClient{RedirectURIs: []string{"https://foo.bar/cb"}, Scopes: []string{"foo", "bar"}, ResponseTypes: []string{"code token"}, Secret: []byte("1234")}, nil).MaxTimes(2) + store.EXPECT().GetClient(gomock.Any(), "1234").Return(&DefaultClient{RedirectURIs: []string{"https://foo.bar/cb"}, Scopes: []string{"foo", "bar"}, ResponseTypes: []string{consts.ResponseTypeHybridFlowToken}, Secret: []byte("1234")}, nil).MaxTimes(2) hasher.EXPECT().Compare(ctx, gomock.Eq([]byte("1234")), gomock.Eq([]byte("1234"))).Return(nil) }, expectedError: ErrUnsupportedResponseMode, @@ -436,20 +437,20 @@ func TestNewPushedAuthorizeRequest(t *testing.T) { desc: "should fail because requested response mode is not allowed", provider: provider, query: url.Values{ - "redirect_uri": {"https://foo.bar/cb"}, - "client_id": {"1234"}, - "client_secret": []string{"1234"}, - "response_type": {"code token"}, - "state": {"strong-state"}, - "scope": {"foo bar"}, - "response_mode": {"form_post"}, + consts.FormParameterRedirectURI: {"https://foo.bar/cb"}, + consts.FormParameterClientID: {"1234"}, + consts.FormParameterClientSecret: []string{"1234"}, + consts.FormParameterResponseType: []string{consts.ResponseTypeHybridFlowToken}, + consts.FormParameterState: {"strong-state"}, + consts.FormParameterScope: {"foo bar"}, + consts.FormParameterResponseMode: {consts.ResponseModeFormPost}, }, mock: func() { store.EXPECT().GetClient(gomock.Any(), "1234").Return(&DefaultResponseModeClient{ DefaultClient: &DefaultClient{ RedirectURIs: []string{"https://foo.bar/cb"}, Scopes: []string{"foo", "bar"}, - ResponseTypes: []string{"code token"}, + ResponseTypes: []string{consts.ResponseTypeHybridFlowToken}, Secret: []byte("1234"), }, ResponseModes: []ResponseModeType{ResponseModeQuery}, @@ -463,22 +464,22 @@ func TestNewPushedAuthorizeRequest(t *testing.T) { desc: "success with response mode", provider: provider, query: url.Values{ - "redirect_uri": {"https://foo.bar/cb"}, - "client_id": {"1234"}, - "client_secret": []string{"1234"}, - "response_type": {"code token"}, - "state": {"strong-state"}, - "scope": {"foo bar"}, - "response_mode": {"form_post"}, - "audience": {"https://cloud.ory.sh/api https://www.authelia.com/api"}, + consts.FormParameterRedirectURI: {"https://foo.bar/cb"}, + consts.FormParameterClientID: {"1234"}, + consts.FormParameterClientSecret: []string{"1234"}, + consts.FormParameterResponseType: []string{consts.ResponseTypeHybridFlowToken}, + consts.FormParameterState: {"strong-state"}, + consts.FormParameterScope: {"foo bar"}, + consts.FormParameterResponseMode: {consts.ResponseModeFormPost}, + consts.FormParameterAudience: {"https://cloud.authelia.com/api https://www.authelia.com/api"}, }, mock: func() { store.EXPECT().GetClient(gomock.Any(), "1234").Return(&DefaultResponseModeClient{ DefaultClient: &DefaultClient{ RedirectURIs: []string{"https://foo.bar/cb"}, Scopes: []string{"foo", "bar"}, - ResponseTypes: []string{"code token"}, - Audience: []string{"https://cloud.ory.sh/api", "https://www.authelia.com/api"}, + ResponseTypes: []string{consts.ResponseTypeHybridFlowToken}, + Audience: []string{"https://cloud.authelia.com/api", "https://www.authelia.com/api"}, Secret: []byte("1234"), }, ResponseModes: []ResponseModeType{ResponseModeFormPost}, @@ -487,21 +488,21 @@ func TestNewPushedAuthorizeRequest(t *testing.T) { }, expect: &AuthorizeRequest{ RedirectURI: redir, - ResponseTypes: []string{"code", "token"}, + ResponseTypes: []string{consts.ResponseTypeAuthorizationCodeFlow, consts.ResponseTypeImplicitFlowToken}, State: "strong-state", Request: Request{ Client: &DefaultResponseModeClient{ DefaultClient: &DefaultClient{ RedirectURIs: []string{"https://foo.bar/cb"}, Scopes: []string{"foo", "bar"}, - ResponseTypes: []string{"code token"}, - Audience: []string{"https://cloud.ory.sh/api", "https://www.authelia.com/api"}, + ResponseTypes: []string{consts.ResponseTypeHybridFlowToken}, + Audience: []string{"https://cloud.authelia.com/api", "https://www.authelia.com/api"}, Secret: []byte("1234"), }, ResponseModes: []ResponseModeType{ResponseModeFormPost}, }, RequestedScope: []string{"foo", "bar"}, - RequestedAudience: []string{"https://cloud.ory.sh/api", "https://www.authelia.com/api"}, + RequestedAudience: []string{"https://cloud.authelia.com/api", "https://www.authelia.com/api"}, }, }, }, @@ -510,21 +511,21 @@ func TestNewPushedAuthorizeRequest(t *testing.T) { desc: "success with response mode", provider: provider, query: url.Values{ - "redirect_uri": {"https://foo.bar/cb"}, - "client_id": {"1234"}, - "client_secret": []string{"1234"}, - "response_type": {"code"}, - "state": {"strong-state"}, - "scope": {"foo bar"}, - "audience": {"https://cloud.ory.sh/api https://www.authelia.com/api"}, + consts.FormParameterRedirectURI: {"https://foo.bar/cb"}, + consts.FormParameterClientID: {"1234"}, + consts.FormParameterClientSecret: []string{"1234"}, + consts.FormParameterResponseType: {"code"}, + consts.FormParameterState: {"strong-state"}, + consts.FormParameterScope: {"foo bar"}, + consts.FormParameterAudience: {"https://cloud.authelia.com/api https://www.authelia.com/api"}, }, mock: func() { store.EXPECT().GetClient(gomock.Any(), "1234").Return(&DefaultResponseModeClient{ DefaultClient: &DefaultClient{ RedirectURIs: []string{"https://foo.bar/cb"}, Scopes: []string{"foo", "bar"}, - ResponseTypes: []string{"code"}, - Audience: []string{"https://cloud.ory.sh/api", "https://www.authelia.com/api"}, + ResponseTypes: []string{consts.ResponseTypeAuthorizationCodeFlow}, + Audience: []string{"https://cloud.authelia.com/api", "https://www.authelia.com/api"}, Secret: []byte("1234"), }, ResponseModes: []ResponseModeType{ResponseModeQuery}, @@ -533,21 +534,21 @@ func TestNewPushedAuthorizeRequest(t *testing.T) { }, expect: &AuthorizeRequest{ RedirectURI: redir, - ResponseTypes: []string{"code"}, + ResponseTypes: []string{consts.ResponseTypeAuthorizationCodeFlow}, State: "strong-state", Request: Request{ Client: &DefaultResponseModeClient{ DefaultClient: &DefaultClient{ RedirectURIs: []string{"https://foo.bar/cb"}, Scopes: []string{"foo", "bar"}, - ResponseTypes: []string{"code"}, - Audience: []string{"https://cloud.ory.sh/api", "https://www.authelia.com/api"}, + ResponseTypes: []string{consts.ResponseTypeAuthorizationCodeFlow}, + Audience: []string{"https://cloud.authelia.com/api", "https://www.authelia.com/api"}, Secret: []byte("1234"), }, ResponseModes: []ResponseModeType{ResponseModeQuery}, }, RequestedScope: []string{"foo", "bar"}, - RequestedAudience: []string{"https://cloud.ory.sh/api", "https://www.authelia.com/api"}, + RequestedAudience: []string{"https://cloud.authelia.com/api", "https://www.authelia.com/api"}, }, }, }, @@ -556,21 +557,21 @@ func TestNewPushedAuthorizeRequest(t *testing.T) { desc: "success with response mode", provider: provider, query: url.Values{ - "redirect_uri": {"https://foo.bar/cb"}, - "client_id": {"1234"}, - "client_secret": []string{"1234"}, - "response_type": {"code token"}, - "state": {"strong-state"}, - "scope": {"foo bar"}, - "audience": {"https://cloud.ory.sh/api https://www.authelia.com/api"}, + consts.FormParameterRedirectURI: {"https://foo.bar/cb"}, + consts.FormParameterClientID: {"1234"}, + consts.FormParameterClientSecret: []string{"1234"}, + consts.FormParameterResponseType: []string{consts.ResponseTypeHybridFlowToken}, + consts.FormParameterState: {"strong-state"}, + consts.FormParameterScope: {"foo bar"}, + consts.FormParameterAudience: {"https://cloud.authelia.com/api https://www.authelia.com/api"}, }, mock: func() { store.EXPECT().GetClient(gomock.Any(), "1234").Return(&DefaultResponseModeClient{ DefaultClient: &DefaultClient{ RedirectURIs: []string{"https://foo.bar/cb"}, Scopes: []string{"foo", "bar"}, - ResponseTypes: []string{"code token"}, - Audience: []string{"https://cloud.ory.sh/api", "https://www.authelia.com/api"}, + ResponseTypes: []string{consts.ResponseTypeHybridFlowToken}, + Audience: []string{"https://cloud.authelia.com/api", "https://www.authelia.com/api"}, Secret: []byte("1234"), }, ResponseModes: []ResponseModeType{ResponseModeFragment}, @@ -579,21 +580,21 @@ func TestNewPushedAuthorizeRequest(t *testing.T) { }, expect: &AuthorizeRequest{ RedirectURI: redir, - ResponseTypes: []string{"code", "token"}, + ResponseTypes: []string{consts.ResponseTypeAuthorizationCodeFlow, consts.ResponseTypeImplicitFlowToken}, State: "strong-state", Request: Request{ Client: &DefaultResponseModeClient{ DefaultClient: &DefaultClient{ RedirectURIs: []string{"https://foo.bar/cb"}, Scopes: []string{"foo", "bar"}, - ResponseTypes: []string{"code token"}, - Audience: []string{"https://cloud.ory.sh/api", "https://www.authelia.com/api"}, + ResponseTypes: []string{consts.ResponseTypeHybridFlowToken}, + Audience: []string{"https://cloud.authelia.com/api", "https://www.authelia.com/api"}, Secret: []byte("1234"), }, ResponseModes: []ResponseModeType{ResponseModeFragment}, }, RequestedScope: []string{"foo", "bar"}, - RequestedAudience: []string{"https://cloud.ory.sh/api", "https://www.authelia.com/api"}, + RequestedAudience: []string{"https://cloud.authelia.com/api", "https://www.authelia.com/api"}, }, }, }, @@ -602,17 +603,17 @@ func TestNewPushedAuthorizeRequest(t *testing.T) { desc: "should fail because request_uri is provided in the request", provider: provider, query: url.Values{ - "request_uri": {"https://foo.bar/ru"}, - "redirect_uri": {"https://foo.bar/cb"}, - "client_id": {"1234"}, - "client_secret": []string{"1234"}, - "response_type": {"code token"}, - "state": {"strong-state"}, - "scope": {"foo bar"}, - "response_mode": {"form_post"}, + consts.FormParameterRequestURI: {"https://foo.bar/ru"}, + consts.FormParameterRedirectURI: {"https://foo.bar/cb"}, + consts.FormParameterClientID: {"1234"}, + consts.FormParameterClientSecret: []string{"1234"}, + consts.FormParameterResponseType: []string{consts.ResponseTypeHybridFlowToken}, + consts.FormParameterState: {"strong-state"}, + consts.FormParameterScope: {"foo bar"}, + consts.FormParameterResponseMode: {consts.ResponseModeFormPost}, }, mock: func() { - store.EXPECT().GetClient(gomock.Any(), "1234").Return(&DefaultClient{RedirectURIs: []string{"https://foo.bar/cb"}, Scopes: []string{"foo", "bar"}, ResponseTypes: []string{"code token"}, Secret: []byte("1234")}, nil).MaxTimes(2) + store.EXPECT().GetClient(gomock.Any(), "1234").Return(&DefaultClient{RedirectURIs: []string{"https://foo.bar/cb"}, Scopes: []string{"foo", "bar"}, ResponseTypes: []string{consts.ResponseTypeHybridFlowToken}, Secret: []byte("1234")}, nil).MaxTimes(2) hasher.EXPECT().Compare(ctx, gomock.Eq([]byte("1234")), gomock.Eq([]byte("1234"))).Return(nil) }, expectedError: ErrInvalidRequest.WithHint("The request must not contain 'request_uri'."), @@ -622,17 +623,17 @@ func TestNewPushedAuthorizeRequest(t *testing.T) { desc: "should fail because of invalid client creds", provider: provider, query: url.Values{ - "request_uri": {"https://foo.bar/ru"}, - "redirect_uri": {"https://foo.bar/cb"}, - "client_id": {"1234"}, - "client_secret": []string{"4321"}, - "response_type": {"code token"}, - "state": {"strong-state"}, - "scope": {"foo bar"}, - "response_mode": {"form_post"}, + consts.FormParameterRequestURI: {"https://foo.bar/ru"}, + consts.FormParameterRedirectURI: {"https://foo.bar/cb"}, + consts.FormParameterClientID: {"1234"}, + consts.FormParameterClientSecret: []string{"4321"}, + consts.FormParameterResponseType: []string{consts.ResponseTypeHybridFlowToken}, + consts.FormParameterState: {"strong-state"}, + consts.FormParameterScope: {"foo bar"}, + consts.FormParameterResponseMode: {consts.ResponseModeFormPost}, }, mock: func() { - store.EXPECT().GetClient(gomock.Any(), "1234").Return(&DefaultClient{RedirectURIs: []string{"https://foo.bar/cb"}, Scopes: []string{"foo", "bar"}, ResponseTypes: []string{"code token"}, Secret: []byte("1234")}, nil).MaxTimes(2) + store.EXPECT().GetClient(gomock.Any(), "1234").Return(&DefaultClient{RedirectURIs: []string{"https://foo.bar/cb"}, Scopes: []string{"foo", "bar"}, ResponseTypes: []string{consts.ResponseTypeHybridFlowToken}, Secret: []byte("1234")}, nil).MaxTimes(2) hasher.EXPECT().Compare(ctx, gomock.Eq([]byte("1234")), gomock.Eq([]byte("4321"))).Return(fmt.Errorf("invalid hash")) }, expectedError: ErrInvalidClient, diff --git a/pushed_authorize_response_writer.go b/pushed_authorize_response_writer.go index 79586aab..b7498559 100644 --- a/pushed_authorize_response_writer.go +++ b/pushed_authorize_response_writer.go @@ -9,6 +9,7 @@ import ( "fmt" "net/http" + "authelia.com/provider/oauth2/internal/consts" "authelia.com/provider/oauth2/internal/errorsx" ) @@ -47,9 +48,9 @@ func (f *Fosite) WritePushedAuthorizeResponse(ctx context.Context, rw http.Respo wh.Set(k, rh.Get(k)) } - wh.Set("Cache-Control", "no-store") - wh.Set("Pragma", "no-cache") - wh.Set("Content-Type", "application/json;charset=UTF-8") + wh.Set(consts.HeaderCacheControl, consts.CacheControlNoStore) + wh.Set(consts.HeaderPragma, consts.PragmaNoCache) + wh.Set(consts.HeaderContentType, consts.ContentTypeApplicationJSON) js, err := json.Marshal(resp.ToMap()) if err != nil { @@ -57,7 +58,7 @@ func (f *Fosite) WritePushedAuthorizeResponse(ctx context.Context, rw http.Respo return } - rw.Header().Set("Content-Type", "application/json;charset=UTF-8") + rw.Header().Set(consts.HeaderContentType, consts.ContentTypeApplicationJSON) rw.WriteHeader(http.StatusCreated) _, _ = rw.Write(js) @@ -65,9 +66,9 @@ func (f *Fosite) WritePushedAuthorizeResponse(ctx context.Context, rw http.Respo // WritePushedAuthorizeError writes the PAR error func (f *Fosite) WritePushedAuthorizeError(ctx context.Context, rw http.ResponseWriter, ar AuthorizeRequester, err error) { - rw.Header().Set("Cache-Control", "no-store") - rw.Header().Set("Pragma", "no-cache") - rw.Header().Set("Content-Type", "application/json;charset=UTF-8") + rw.Header().Set(consts.HeaderCacheControl, consts.CacheControlNoStore) + rw.Header().Set(consts.HeaderPragma, consts.PragmaNoCache) + rw.Header().Set(consts.HeaderContentType, consts.ContentTypeApplicationJSON) sendDebugMessagesToClient := f.Config.GetSendDebugMessagesToClients(ctx) rfcerr := ErrorToRFC6749Error(err).WithLegacyFormat(f.Config.GetUseLegacyErrorFormat(ctx)). diff --git a/response_handler.go b/response_handler.go index 1d6dd811..5733a800 100644 --- a/response_handler.go +++ b/response_handler.go @@ -21,15 +21,15 @@ type ResponseModeHandler interface { // WriteAuthorizeResponse writes successful responses // // Following headers are expected to be set by default: - // header.Set("Cache-Control", "no-store") - // header.Set("Pragma", "no-cache") + // header.Set(consts.HeaderCacheControl, consts.CacheControlNoStore) + // header.Set(consts.HeaderPragma, consts.PragmaNoCache) WriteAuthorizeResponse(ctx context.Context, rw http.ResponseWriter, ar AuthorizeRequester, resp AuthorizeResponder) // WriteAuthorizeError writes error responses // // Following headers are expected to be set by default: - // header.Set("Cache-Control", "no-store") - // header.Set("Pragma", "no-cache") + // header.Set(consts.HeaderCacheControl, consts.CacheControlNoStore) + // header.Set(consts.HeaderPragma, consts.PragmaNoCache) WriteAuthorizeError(ctx context.Context, rw http.ResponseWriter, ar AuthorizeRequester, err error) } diff --git a/revoke_handler.go b/revoke_handler.go index bc071bd3..273a2228 100644 --- a/revoke_handler.go +++ b/revoke_handler.go @@ -11,7 +11,6 @@ import ( "net/http" "authelia.com/provider/oauth2/internal/consts" - "authelia.com/provider/oauth2/internal/errorsx" ) @@ -81,8 +80,8 @@ func (f *Fosite) NewRevocationRequest(ctx context.Context, r *http.Request) erro // purpose of the revocation request, invalidating the particular token, // is already achieved. func (f *Fosite) WriteRevocationResponse(ctx context.Context, rw http.ResponseWriter, err error) { - rw.Header().Set("Cache-Control", "no-store") - rw.Header().Set("Pragma", "no-cache") + rw.Header().Set(consts.HeaderCacheControl, consts.CacheControlNoStore) + rw.Header().Set(consts.HeaderPragma, consts.PragmaNoCache) switch { case err == nil: @@ -105,7 +104,7 @@ func (f *Fosite) WriteRevocationResponse(ctx context.Context, rw http.ResponseWr } func (f *Fosite) writeRevocationResponseError(ctx context.Context, rw http.ResponseWriter, rfc *RFC6749Error) { - rw.Header().Set("Content-Type", "application/json; charset=utf-8") + rw.Header().Set(consts.HeaderContentType, consts.ContentTypeApplicationJSON) js, err := json.Marshal(rfc) if err != nil { diff --git a/revoke_handler_test.go b/revoke_handler_test.go index e18dff8a..44372ec8 100644 --- a/revoke_handler_test.go +++ b/revoke_handler_test.go @@ -17,6 +17,7 @@ import ( . "authelia.com/provider/oauth2" "authelia.com/provider/oauth2/internal" + "authelia.com/provider/oauth2/internal/consts" ) func TestNewRevocationRequest(t *testing.T) { @@ -56,18 +57,18 @@ func TestNewRevocationRequest(t *testing.T) { header: http.Header{}, method: "POST", form: url.Values{ - "token": {"foo"}, + consts.FormParameterToken: {"foo"}, }, mock: func() {}, expectErr: ErrInvalidRequest, }, { header: http.Header{ - "Authorization": {basicAuth("foo", "bar")}, + consts.HeaderAuthorization: {basicAuth("foo", "bar")}, }, method: "POST", form: url.Values{ - "token": {"foo"}, + consts.FormParameterToken: {"foo"}, }, expectErr: ErrInvalidClient, mock: func() { @@ -76,11 +77,11 @@ func TestNewRevocationRequest(t *testing.T) { }, { header: http.Header{ - "Authorization": {basicAuth("foo", "bar")}, + consts.HeaderAuthorization: {basicAuth("foo", "bar")}, }, method: "POST", form: url.Values{ - "token": {"foo"}, + consts.FormParameterToken: {"foo"}, }, expectErr: ErrInvalidClient, mock: func() { @@ -92,11 +93,11 @@ func TestNewRevocationRequest(t *testing.T) { }, { header: http.Header{ - "Authorization": {basicAuth("foo", "bar")}, + consts.HeaderAuthorization: {basicAuth("foo", "bar")}, }, method: "POST", form: url.Values{ - "token": {"foo"}, + consts.FormParameterToken: {"foo"}, }, expectErr: nil, mock: func() { @@ -110,12 +111,12 @@ func TestNewRevocationRequest(t *testing.T) { }, { header: http.Header{ - "Authorization": {basicAuth("foo", "bar")}, + consts.HeaderAuthorization: {basicAuth("foo", "bar")}, }, method: "POST", form: url.Values{ - "token": {"foo"}, - "token_type_hint": {"access_token"}, + consts.FormParameterToken: {"foo"}, + consts.FormParameterTokenTypeHint: {consts.TokenTypeAccessToken}, }, expectErr: nil, mock: func() { @@ -129,12 +130,12 @@ func TestNewRevocationRequest(t *testing.T) { }, { header: http.Header{ - "Authorization": {basicAuth("foo", "")}, + consts.HeaderAuthorization: {basicAuth("foo", "")}, }, method: "POST", form: url.Values{ - "token": {"foo"}, - "token_type_hint": {"refresh_token"}, + consts.FormParameterToken: {"foo"}, + consts.FormParameterTokenTypeHint: {consts.TokenTypeRefreshToken}, }, expectErr: nil, mock: func() { @@ -146,12 +147,12 @@ func TestNewRevocationRequest(t *testing.T) { }, { header: http.Header{ - "Authorization": {basicAuth("foo", "bar")}, + consts.HeaderAuthorization: {basicAuth("foo", "bar")}, }, method: "POST", form: url.Values{ - "token": {"foo"}, - "token_type_hint": {"refresh_token"}, + consts.FormParameterToken: {"foo"}, + consts.FormParameterTokenTypeHint: {consts.TokenTypeRefreshToken}, }, expectErr: nil, mock: func() { @@ -165,12 +166,12 @@ func TestNewRevocationRequest(t *testing.T) { }, { header: http.Header{ - "Authorization": {basicAuth("foo", "bar")}, + consts.HeaderAuthorization: {basicAuth("foo", "bar")}, }, method: "POST", form: url.Values{ - "token": {"foo"}, - "token_type_hint": {"bar"}, + consts.FormParameterToken: {"foo"}, + consts.FormParameterTokenTypeHint: {"bar"}, }, expectErr: nil, mock: func() { @@ -191,9 +192,9 @@ func TestNewRevocationRequest(t *testing.T) { Method: c.method, } c.mock() - ctx := NewContext() + config.RevocationHandlers = c.handlers - err := provider.NewRevocationRequest(ctx, r) + err := provider.NewRevocationRequest(context.TODO(), r) if c.expectErr != nil { assert.EqualError(t, err, c.expectErr.Error()) diff --git a/scope_strategy_test.go b/scope_strategy_test.go index d6461efb..9c4a5705 100644 --- a/scope_strategy_test.go +++ b/scope_strategy_test.go @@ -8,6 +8,8 @@ import ( "testing" "github.com/stretchr/testify/assert" + + "authelia.com/provider/oauth2/internal/consts" ) func TestHierarchicScopeStrategy(t *testing.T) { @@ -35,14 +37,14 @@ func TestHierarchicScopeStrategy(t *testing.T) { assert.True(t, strategy(scopes, "authelia.key.get")) assert.True(t, strategy(scopes, "authelia.key.update")) - scopes = []string{"authelia", "openid", "offline"} + scopes = []string{"authelia", consts.ScopeOpenID, consts.ScopeOffline} assert.False(t, strategy(scopes, "foo.bar")) assert.False(t, strategy(scopes, "foo")) assert.True(t, strategy(scopes, "authelia")) assert.True(t, strategy(scopes, "authelia.bar")) - assert.True(t, strategy(scopes, "openid")) + assert.True(t, strategy(scopes, consts.ScopeOpenID)) assert.True(t, strategy(scopes, "openid.baz.bar")) - assert.True(t, strategy(scopes, "offline")) + assert.True(t, strategy(scopes, consts.ScopeOffline)) assert.True(t, strategy(scopes, "offline.baz.bar.baz")) } @@ -113,8 +115,8 @@ func TestWildcardScopeStrategy(t *testing.T) { assert.True(t, strategy(scopes, "hydra.clients")) assert.True(t, strategy(scopes, "hydra.clients.get")) assert.True(t, strategy(scopes, "hydra")) - assert.True(t, strategy(scopes, "offline")) - assert.True(t, strategy(scopes, "openid")) + assert.True(t, strategy(scopes, consts.ScopeOffline)) + assert.True(t, strategy(scopes, consts.ScopeOpenID)) } func TestExactScopeStrategy2ScopeStrategy(t *testing.T) { diff --git a/storage/memory.go b/storage/memory.go index b269cc70..91b272e1 100644 --- a/storage/memory.go +++ b/storage/memory.go @@ -9,10 +9,11 @@ import ( "sync" "time" - "github.com/go-jose/go-jose/v3" + jose "github.com/go-jose/go-jose/v3" "authelia.com/provider/oauth2" "authelia.com/provider/oauth2/internal" + "authelia.com/provider/oauth2/internal/consts" ) type MemoryUserRelation struct { @@ -103,7 +104,7 @@ func NewExampleStore() *MemoryStore { RedirectURIs: []string{"http://localhost:3846/callback"}, ResponseTypes: []string{"id_token", "code", "token", "id_token token", "code id_token", "code token", "code id_token token"}, GrantTypes: []string{"implicit", "refresh_token", "authorization_code", "password", "client_credentials"}, - Scopes: []string{"oauth2", "openid", "photos", "offline"}, + Scopes: []string{"oauth2", consts.ScopeOpenID, "photos", consts.ScopeOffline}, }, "custom-lifespan-client": &oauth2.DefaultClientWithCustomTokenLifespans{ DefaultClient: &oauth2.DefaultClient{ @@ -113,7 +114,7 @@ func NewExampleStore() *MemoryStore { RedirectURIs: []string{"http://localhost:3846/callback"}, ResponseTypes: []string{"id_token", "code", "token", "id_token token", "code id_token", "code token", "code id_token token"}, GrantTypes: []string{"implicit", "refresh_token", "authorization_code", "password", "client_credentials"}, - Scopes: []string{"oauth2", "openid", "photos", "offline"}, + Scopes: []string{"oauth2", consts.ScopeOpenID, "photos", consts.ScopeOffline}, }, TokenLifespans: &internal.TestLifespans, }, @@ -124,7 +125,7 @@ func NewExampleStore() *MemoryStore { RedirectURIs: []string{"http://localhost:3846/callback"}, ResponseTypes: []string{"id_token", "code", "token", "id_token token", "code id_token", "code token", "code id_token token"}, GrantTypes: []string{"implicit", "refresh_token", "authorization_code", "password", "client_credentials"}, - Scopes: []string{"oauth2", "openid", "photos", "offline"}, + Scopes: []string{"oauth2", consts.ScopeOpenID, "photos", consts.ScopeOffline}, }, }, Users: map[string]MemoryUserRelation{ diff --git a/token/jwt/claims_id_token.go b/token/jwt/claims_id_token.go index c37a3f95..2eccf6dd 100644 --- a/token/jwt/claims_id_token.go +++ b/token/jwt/claims_id_token.go @@ -6,8 +6,9 @@ package jwt import ( "time" - "authelia.com/provider/oauth2/internal/consts" "github.com/google/uuid" + + "authelia.com/provider/oauth2/internal/consts" ) // IDTokenClaims represent the claims used in open id connect requests diff --git a/token/jwt/claims_id_token_test.go b/token/jwt/claims_id_token_test.go index 7565ee58..4ff075b2 100644 --- a/token/jwt/claims_id_token_test.go +++ b/token/jwt/claims_id_token_test.go @@ -7,9 +7,9 @@ import ( "testing" "time" - "authelia.com/provider/oauth2/internal/consts" "github.com/stretchr/testify/assert" + "authelia.com/provider/oauth2/internal/consts" . "authelia.com/provider/oauth2/token/jwt" ) diff --git a/token/jwt/claims_jwt.go b/token/jwt/claims_jwt.go index 0141fbd8..a0a1e8aa 100644 --- a/token/jwt/claims_jwt.go +++ b/token/jwt/claims_jwt.go @@ -7,8 +7,9 @@ import ( "strings" "time" - "authelia.com/provider/oauth2/internal/consts" "github.com/google/uuid" + + "authelia.com/provider/oauth2/internal/consts" ) // Enum for different types of scope encoding. diff --git a/token/jwt/claims_jwt_test.go b/token/jwt/claims_jwt_test.go index d50f6332..3bd1f393 100644 --- a/token/jwt/claims_jwt_test.go +++ b/token/jwt/claims_jwt_test.go @@ -9,6 +9,7 @@ import ( "github.com/stretchr/testify/assert" + "authelia.com/provider/oauth2/internal/consts" . "authelia.com/provider/oauth2/token/jwt" ) @@ -20,7 +21,7 @@ var jwtClaims = &JWTClaims{ Audience: []string{"tests"}, ExpiresAt: time.Now().UTC().Add(time.Hour).Round(time.Second), JTI: "abcdef", - Scope: []string{"email", "offline"}, + Scope: []string{consts.ScopeEmail, consts.ScopeOffline}, Extra: map[string]any{ "foo": "bar", "baz": "bar", @@ -29,16 +30,16 @@ var jwtClaims = &JWTClaims{ } var jwtClaimsMap = map[string]any{ - "sub": jwtClaims.Subject, - "iat": jwtClaims.IssuedAt.Unix(), - "iss": jwtClaims.Issuer, - "nbf": jwtClaims.NotBefore.Unix(), - "aud": jwtClaims.Audience, - "exp": jwtClaims.ExpiresAt.Unix(), - "jti": jwtClaims.JTI, - "scp": []string{"email", "offline"}, - "foo": jwtClaims.Extra["foo"], - "baz": jwtClaims.Extra["baz"], + consts.ClaimSubject: jwtClaims.Subject, + consts.ClaimIssuedAt: jwtClaims.IssuedAt.Unix(), + consts.ClaimIssuer: jwtClaims.Issuer, + consts.ClaimNotBefore: jwtClaims.NotBefore.Unix(), + consts.ClaimAudience: jwtClaims.Audience, + consts.ClaimExpirationTime: jwtClaims.ExpiresAt.Unix(), + consts.ClaimJWTID: jwtClaims.JTI, + consts.ClaimScopeNonStandard: []string{consts.ScopeEmail, consts.ScopeOffline}, + "foo": jwtClaims.Extra["foo"], + "baz": jwtClaims.Extra["baz"], } func TestClaimAddGetString(t *testing.T) { diff --git a/token/jwt/map_claims.go b/token/jwt/map_claims.go index 94912cfd..e748d052 100644 --- a/token/jwt/map_claims.go +++ b/token/jwt/map_claims.go @@ -10,9 +10,9 @@ import ( "errors" "time" - "authelia.com/provider/oauth2/internal/consts" jjson "github.com/go-jose/go-jose/v3/json" + "authelia.com/provider/oauth2/internal/consts" "authelia.com/provider/oauth2/internal/errorsx" ) diff --git a/token/jwt/token.go b/token/jwt/token.go index 3a0da501..17732f5a 100644 --- a/token/jwt/token.go +++ b/token/jwt/token.go @@ -9,10 +9,10 @@ import ( "fmt" "reflect" - "authelia.com/provider/oauth2/internal/consts" "github.com/go-jose/go-jose/v3" "github.com/go-jose/go-jose/v3/jwt" + "authelia.com/provider/oauth2/internal/consts" "authelia.com/provider/oauth2/internal/errorsx" ) diff --git a/token/jwt/token_test.go b/token/jwt/token_test.go index ded5fb9f..a63fac2b 100644 --- a/token/jwt/token_test.go +++ b/token/jwt/token_test.go @@ -18,6 +18,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "authelia.com/provider/oauth2/internal/consts" "authelia.com/provider/oauth2/internal/gen" ) @@ -319,12 +320,12 @@ func TestParser_Parse(t *testing.T) { given: given{ name: "used before issued", generate: &generate{ - claims: MapClaims{"foo": "bar", "iat": time.Now().Unix() + 500}, + claims: MapClaims{"foo": "bar", consts.ClaimIssuedAt: time.Now().Unix() + 500}, }, }, expected: expected{ keyFunc: defaultKeyFunc, - claims: MapClaims{"foo": "bar", "iat": time.Now().Unix() + 500}, + claims: MapClaims{"foo": "bar", consts.ClaimIssuedAt: time.Now().Unix() + 500}, valid: false, errors: ValidationErrorIssuedAt, },