Skip to content

Commit 67c4050

Browse files
author
CI Bot
committed
Merge remote-tracking branch 'origin/pr/client-credentials-grant-sync'
2 parents 014564c + 3925296 commit 67c4050

5 files changed

Lines changed: 39 additions & 4 deletions

File tree

server/handlers.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -864,6 +864,8 @@ func (s *Server) handleToken(w http.ResponseWriter, r *http.Request) {
864864
s.withClientFromStorage(w, r, s.handlePasswordGrant)
865865
case grantTypeTokenExchange:
866866
s.withClientFromStorage(w, r, s.handleTokenExchange)
867+
case grantTypeClientCredentials:
868+
s.withClientFromStorage(w, r, s.handleClientCredentialsGrant)
867869
default:
868870
s.tokenErrHelper(w, errUnsupportedGrantType, "", http.StatusBadRequest)
869871
}
@@ -1116,6 +1118,35 @@ func (s *Server) handleUserInfo(w http.ResponseWriter, r *http.Request) {
11161118
w.Write(claims)
11171119
}
11181120

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

server/handlers_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ func TestHandleDiscovery(t *testing.T) {
5757
Introspect: fmt.Sprintf("%s/token/introspect", httpServer.URL),
5858
GrantTypes: []string{
5959
"authorization_code",
60+
"client_credentials",
6061
"refresh_token",
6162
"urn:ietf:params:oauth:grant-type:device_code",
6263
"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
@@ -240,6 +240,7 @@ func newServer(ctx context.Context, c Config, rotationStrategy rotationStrategy)
240240
grantTypeRefreshToken: true,
241241
grantTypeDeviceCode: true,
242242
grantTypeTokenExchange: true,
243+
grantTypeClientCredentials: true,
243244
}
244245
supportedRes := make(map[string]bool)
245246

server/server_test.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ func newTestServer(t *testing.T, updateConfig func(c *Config)) (*httptest.Server
101101
grantTypeTokenExchange,
102102
grantTypeImplicit,
103103
grantTypePassword,
104+
grantTypeClientCredentials,
104105
},
105106
}
106107
if updateConfig != nil {
@@ -1757,7 +1758,7 @@ func TestServerSupportedGrants(t *testing.T) {
17571758
{
17581759
name: "Simple",
17591760
config: func(c *Config) {},
1760-
resGrants: []string{grantTypeAuthorizationCode, grantTypeRefreshToken, grantTypeDeviceCode, grantTypeTokenExchange},
1761+
resGrants: []string{grantTypeAuthorizationCode, grantTypeClientCredentials, grantTypeRefreshToken, grantTypeDeviceCode, grantTypeTokenExchange},
17611762
},
17621763
{
17631764
name: "Minimal",
@@ -1767,20 +1768,20 @@ func TestServerSupportedGrants(t *testing.T) {
17671768
{
17681769
name: "With password connector",
17691770
config: func(c *Config) { c.PasswordConnector = "local" },
1770-
resGrants: []string{grantTypeAuthorizationCode, grantTypePassword, grantTypeRefreshToken, grantTypeDeviceCode, grantTypeTokenExchange},
1771+
resGrants: []string{grantTypeAuthorizationCode, grantTypeClientCredentials, grantTypePassword, grantTypeRefreshToken, grantTypeDeviceCode, grantTypeTokenExchange},
17711772
},
17721773
{
17731774
name: "With token response",
17741775
config: func(c *Config) { c.SupportedResponseTypes = append(c.SupportedResponseTypes, responseTypeToken) },
1775-
resGrants: []string{grantTypeAuthorizationCode, grantTypeImplicit, grantTypeRefreshToken, grantTypeDeviceCode, grantTypeTokenExchange},
1776+
resGrants: []string{grantTypeAuthorizationCode, grantTypeClientCredentials, grantTypeImplicit, grantTypeRefreshToken, grantTypeDeviceCode, grantTypeTokenExchange},
17761777
},
17771778
{
17781779
name: "All",
17791780
config: func(c *Config) {
17801781
c.PasswordConnector = "local"
17811782
c.SupportedResponseTypes = append(c.SupportedResponseTypes, responseTypeToken)
17821783
},
1783-
resGrants: []string{grantTypeAuthorizationCode, grantTypeImplicit, grantTypePassword, grantTypeRefreshToken, grantTypeDeviceCode, grantTypeTokenExchange},
1784+
resGrants: []string{grantTypeAuthorizationCode, grantTypeClientCredentials, grantTypeImplicit, grantTypePassword, grantTypeRefreshToken, grantTypeDeviceCode, grantTypeTokenExchange},
17841785
},
17851786
}
17861787

0 commit comments

Comments
 (0)