From 57e9611ff6578602a876bd74fac84ab9f7d34955 Mon Sep 17 00:00:00 2001 From: "m.nabokikh" Date: Tue, 8 Mar 2022 16:16:25 +0400 Subject: [PATCH] fix: Implicit Grant discovery Signed-off-by: m.nabokikh --- server/oauth2.go | 1 + server/server.go | 11 +++++++++-- server/server_test.go | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/server/oauth2.go b/server/oauth2.go index 23f06b82..998bf02a 100644 --- a/server/oauth2.go +++ b/server/oauth2.go @@ -128,6 +128,7 @@ const ( const ( grantTypeAuthorizationCode = "authorization_code" grantTypeRefreshToken = "refresh_token" + grantTypeImplicit = "implicit" grantTypePassword = "password" grantTypeDeviceCode = "urn:ietf:params:oauth:grant-type:device_code" ) diff --git a/server/server.go b/server/server.go index 6b653fdb..d617a401 100755 --- a/server/server.go +++ b/server/server.go @@ -213,20 +213,27 @@ func newServer(ctx context.Context, c Config, rotationStrategy rotationStrategy) c.SupportedResponseTypes = []string{responseTypeCode} } + supportedGrant := []string{grantTypeAuthorizationCode, grantTypeRefreshToken, grantTypeDeviceCode} // default supportedRes := make(map[string]bool) + for _, respType := range c.SupportedResponseTypes { switch respType { - case responseTypeCode, responseTypeIDToken, responseTypeToken: + case responseTypeCode, responseTypeIDToken: + // continue + case responseTypeToken: + // response_type=token is an implicit flow, let's add it to the discovery info + // https://datatracker.ietf.org/doc/html/rfc6749#section-4.2.1 + supportedGrant = append(supportedGrant, grantTypeImplicit) default: return nil, fmt.Errorf("unsupported response_type %q", respType) } supportedRes[respType] = true } - supportedGrant := []string{grantTypeAuthorizationCode, grantTypeRefreshToken, grantTypeDeviceCode} // default if c.PasswordConnector != "" { supportedGrant = append(supportedGrant, grantTypePassword) } + sort.Strings(supportedGrant) webFS := web.FS() diff --git a/server/server_test.go b/server/server_test.go index 12130dfa..828e7faf 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -1735,3 +1735,42 @@ func TestOAuth2DeviceFlow(t *testing.T) { } } } + +func TestServerSupportedGrants(t *testing.T) { + tests := []struct { + name string + config func(c *Config) + resGrants []string + }{ + { + name: "Simple", + config: func(c *Config) {}, + resGrants: []string{grantTypeAuthorizationCode, grantTypeRefreshToken, grantTypeDeviceCode}, + }, + { + name: "With password connector", + config: func(c *Config) { c.PasswordConnector = "local" }, + resGrants: []string{grantTypeAuthorizationCode, grantTypePassword, grantTypeRefreshToken, grantTypeDeviceCode}, + }, + { + name: "With token response", + config: func(c *Config) { c.SupportedResponseTypes = append(c.SupportedResponseTypes, responseTypeToken) }, + resGrants: []string{grantTypeAuthorizationCode, grantTypeImplicit, grantTypeRefreshToken, grantTypeDeviceCode}, + }, + { + name: "All", + config: func(c *Config) { + c.PasswordConnector = "local" + c.SupportedResponseTypes = append(c.SupportedResponseTypes, responseTypeToken) + }, + resGrants: []string{grantTypeAuthorizationCode, grantTypeImplicit, grantTypePassword, grantTypeRefreshToken, grantTypeDeviceCode}, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + _, srv := newTestServer(context.TODO(), t, tc.config) + require.Equal(t, srv.supportedGrantTypes, tc.resGrants) + }) + } +}