Skip to content

Commit 0fd4098

Browse files
author
CI Bot
committed
Merge remote-tracking branch 'origin/pr/client-credentials-grant-sync'
2 parents 363fecb + 08844c6 commit 0fd4098

File tree

5 files changed

+39
-4
lines changed

5 files changed

+39
-4
lines changed

server/handlers.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -861,6 +861,8 @@ func (s *Server) handleToken(w http.ResponseWriter, r *http.Request) {
861861
s.withClientFromStorage(w, r, s.handlePasswordGrant)
862862
case grantTypeTokenExchange:
863863
s.withClientFromStorage(w, r, s.handleTokenExchange)
864+
case grantTypeClientCredentials:
865+
s.withClientFromStorage(w, r, s.handleClientCredentialsGrant)
864866
default:
865867
s.tokenErrHelper(w, errUnsupportedGrantType, "", http.StatusBadRequest)
866868
}
@@ -1113,6 +1115,35 @@ func (s *Server) handleUserInfo(w http.ResponseWriter, r *http.Request) {
11131115
w.Write(claims)
11141116
}
11151117

1118+
func (s *Server) handleClientCredentialsGrant(w http.ResponseWriter, r *http.Request, client storage.Client) {
1119+
if err := r.ParseForm(); err != nil {
1120+
s.tokenErrHelper(w, errInvalidRequest, "Couldn't parse data", http.StatusBadRequest)
1121+
return
1122+
}
1123+
q := r.Form
1124+
1125+
nonce := q.Get("nonce")
1126+
scopes := strings.Fields(q.Get("scope"))
1127+
1128+
claims := storage.Claims{UserID: client.ID}
1129+
1130+
accessToken, _, err := s.newAccessToken(r.Context(), client.ID, claims, scopes, nonce, "client")
1131+
if err != nil {
1132+
s.logger.ErrorContext(r.Context(), "failed to create new access token", "err", err)
1133+
s.tokenErrHelper(w, errServerError, err.Error(), http.StatusInternalServerError)
1134+
return
1135+
}
1136+
1137+
idToken, expiry, err := s.newIDToken(r.Context(), client.ID, claims, scopes, nonce, accessToken, "", "client")
1138+
if err != nil {
1139+
s.tokenErrHelper(w, errServerError, fmt.Sprintf("failed to create ID token: %v", err), http.StatusInternalServerError)
1140+
return
1141+
}
1142+
1143+
resp := s.toAccessTokenResponse(idToken, accessToken, "", expiry)
1144+
s.writeAccessToken(w, resp)
1145+
}
1146+
11161147
func (s *Server) handlePasswordGrant(w http.ResponseWriter, r *http.Request, client storage.Client) {
11171148
ctx := r.Context()
11181149
// Parse the fields

server/handlers_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ func TestHandleDiscovery(t *testing.T) {
6363
Introspect: fmt.Sprintf("%s/token/introspect", httpServer.URL),
6464
GrantTypes: []string{
6565
"authorization_code",
66+
"client_credentials",
6667
"refresh_token",
6768
"urn:ietf:params:oauth:grant-type:device_code",
6869
"urn:ietf:params:oauth:grant-type:token-exchange",

server/oauth2.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ const (
133133
grantTypePassword = "password"
134134
grantTypeDeviceCode = "urn:ietf:params:oauth:grant-type:device_code"
135135
grantTypeTokenExchange = "urn:ietf:params:oauth:grant-type:token-exchange"
136+
grantTypeClientCredentials = "client_credentials"
136137
)
137138

138139
const (

server/server.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ func newServer(ctx context.Context, c Config, rotationStrategy rotationStrategy)
236236
grantTypeRefreshToken: true,
237237
grantTypeDeviceCode: true,
238238
grantTypeTokenExchange: true,
239+
grantTypeClientCredentials: true,
239240
}
240241
supportedRes := make(map[string]bool)
241242

server/server_test.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ func newTestServer(ctx context.Context, t *testing.T, updateConfig func(c *Confi
101101
grantTypeTokenExchange,
102102
grantTypeImplicit,
103103
grantTypePassword,
104+
grantTypeClientCredentials,
104105
},
105106
}
106107
if updateConfig != nil {
@@ -1760,7 +1761,7 @@ func TestServerSupportedGrants(t *testing.T) {
17601761
{
17611762
name: "Simple",
17621763
config: func(c *Config) {},
1763-
resGrants: []string{grantTypeAuthorizationCode, grantTypeRefreshToken, grantTypeDeviceCode, grantTypeTokenExchange},
1764+
resGrants: []string{grantTypeAuthorizationCode, grantTypeClientCredentials, grantTypeRefreshToken, grantTypeDeviceCode, grantTypeTokenExchange},
17641765
},
17651766
{
17661767
name: "Minimal",
@@ -1770,20 +1771,20 @@ func TestServerSupportedGrants(t *testing.T) {
17701771
{
17711772
name: "With password connector",
17721773
config: func(c *Config) { c.PasswordConnector = "local" },
1773-
resGrants: []string{grantTypeAuthorizationCode, grantTypePassword, grantTypeRefreshToken, grantTypeDeviceCode, grantTypeTokenExchange},
1774+
resGrants: []string{grantTypeAuthorizationCode, grantTypeClientCredentials, grantTypePassword, grantTypeRefreshToken, grantTypeDeviceCode, grantTypeTokenExchange},
17741775
},
17751776
{
17761777
name: "With token response",
17771778
config: func(c *Config) { c.SupportedResponseTypes = append(c.SupportedResponseTypes, responseTypeToken) },
1778-
resGrants: []string{grantTypeAuthorizationCode, grantTypeImplicit, grantTypeRefreshToken, grantTypeDeviceCode, grantTypeTokenExchange},
1779+
resGrants: []string{grantTypeAuthorizationCode, grantTypeClientCredentials, grantTypeImplicit, grantTypeRefreshToken, grantTypeDeviceCode, grantTypeTokenExchange},
17791780
},
17801781
{
17811782
name: "All",
17821783
config: func(c *Config) {
17831784
c.PasswordConnector = "local"
17841785
c.SupportedResponseTypes = append(c.SupportedResponseTypes, responseTypeToken)
17851786
},
1786-
resGrants: []string{grantTypeAuthorizationCode, grantTypeImplicit, grantTypePassword, grantTypeRefreshToken, grantTypeDeviceCode, grantTypeTokenExchange},
1787+
resGrants: []string{grantTypeAuthorizationCode, grantTypeClientCredentials, grantTypeImplicit, grantTypePassword, grantTypeRefreshToken, grantTypeDeviceCode, grantTypeTokenExchange},
17871788
},
17881789
}
17891790

0 commit comments

Comments
 (0)