Skip to content

Commit 987419f

Browse files
authored
Merge pull request #31 from pokixing/feature/oauth_jmespath
feature: use jmespath library to support parsing multi-level username key and so on when using oauth
2 parents 12c997b + 1e0a4d6 commit 987419f

File tree

4 files changed

+472
-12
lines changed

4 files changed

+472
-12
lines changed

connector/oauth/oauth.go

Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818

1919
"github.com/dexidp/dex/connector"
2020
"github.com/dexidp/dex/pkg/log"
21+
"github.com/jmespath/go-jmespath"
2122
)
2223

2324
type oauthConnector struct {
@@ -201,29 +202,53 @@ func (c *oauthConnector) HandleCallback(s connector.Scopes, r *http.Request) (id
201202
return identity, fmt.Errorf("OAuth Connector: failed to execute request to userinfo: status %d", userInfoResp.StatusCode)
202203
}
203204

204-
var userInfoResult map[string]interface{}
205+
var userInfoResult interface{}
205206
err = json.NewDecoder(userInfoResp.Body).Decode(&userInfoResult)
206207
if err != nil {
207208
c.logger.Errorf("OAuth Connector: failed to parse userinfo: %v", err)
208209
return identity, fmt.Errorf("OAuth Connector: failed to parse userinfo: %v", err)
209210
}
210211

211-
userID, found := userInfoResult[c.userIDKey].(string)
212+
tmpUserID, _ := jmespath.Search(c.userIDKey, userInfoResult)
213+
userID, found := tmpUserID.(string)
212214
if !found {
213215
c.logger.Errorf("OAuth Connector: not found %v claim", c.userIDKey)
214216
return identity, fmt.Errorf("OAuth Connector: not found %v claim", c.userIDKey)
215217
}
216-
217218
identity.UserID = userID
218-
identity.Username, _ = userInfoResult[c.userNameKey].(string)
219-
identity.PreferredUsername, _ = userInfoResult[c.preferredUsernameKey].(string)
220-
identity.Email, _ = userInfoResult[c.emailKey].(string)
221-
identity.EmailVerified, _ = userInfoResult[c.emailVerifiedKey].(bool)
219+
220+
username, err := jmespath.Search(c.userNameKey, userInfoResult)
221+
if err != nil {
222+
c.logger.Errorf("OAuth Connector: failed to search %v claim: %v", c.userNameKey, err)
223+
return identity, fmt.Errorf("OAuth Connector: failed to search %v claim: %v", c.userNameKey, err)
224+
}
225+
identity.Username, _ = username.(string)
226+
227+
preferredUsername, err := jmespath.Search(c.preferredUsernameKey, userInfoResult)
228+
if err != nil {
229+
c.logger.Errorf("OAuth Connector: failed to search %v claim: %v", c.preferredUsernameKey, err)
230+
return identity, fmt.Errorf("OAuth Connector: failed to search %v claim: %v", c.preferredUsernameKey, err)
231+
}
232+
identity.PreferredUsername, _ = preferredUsername.(string)
233+
234+
email, err := jmespath.Search(c.emailKey, userInfoResult)
235+
if err != nil {
236+
c.logger.Errorf("OAuth Connector: failed to search %v claim: %v", c.emailKey, err)
237+
return identity, fmt.Errorf("OAuth Connector: failed to search %v claim: %v", c.emailKey, err)
238+
}
239+
identity.Email, _ = email.(string)
240+
241+
emailVerified, err := jmespath.Search(c.emailVerifiedKey, userInfoResult)
242+
if err != nil {
243+
c.logger.Errorf("OAuth Connector: failed to search %v claim: %v", c.emailVerifiedKey, err)
244+
return identity, fmt.Errorf("OAuth Connector: failed to search %v claim: %v", c.emailVerifiedKey, err)
245+
}
246+
identity.EmailVerified, _ = emailVerified.(bool)
222247

223248
if s.Groups {
224249
groups := map[string]struct{}{}
225250

226-
c.addGroupsFromMap(groups, userInfoResult)
251+
c.addGroups(groups, userInfoResult)
227252
c.addGroupsFromToken(groups, token.AccessToken)
228253

229254
for groupName := range groups {
@@ -243,15 +268,26 @@ func (c *oauthConnector) HandleCallback(s connector.Scopes, r *http.Request) (id
243268
return identity, nil
244269
}
245270

246-
func (c *oauthConnector) addGroupsFromMap(groups map[string]struct{}, result map[string]interface{}) error {
247-
groupsClaim, ok := result[c.groupsKey].([]interface{})
271+
func (c *oauthConnector) addGroups(groups map[string]struct{}, result interface{}) error {
272+
tmpGroupsClaim, err := jmespath.Search(c.groupsKey, result)
273+
if err != nil {
274+
return errors.New(fmt.Sprintf("failed to search %v claim: %v", c.groupsKey, err))
275+
}
276+
277+
groupsClaim, ok := tmpGroupsClaim.([]interface{})
248278
if !ok {
249279
return errors.New("cannot convert to slice")
250280
}
251281

252282
for _, group := range groupsClaim {
253283
if groupString, ok := group.(string); ok {
254284
groups[groupString] = struct{}{}
285+
continue
286+
}
287+
if groupMap, ok := group.(map[string]interface{}); ok {
288+
if groupName, ok := groupMap["name"].(string); ok {
289+
groups[groupName] = struct{}{}
290+
}
255291
}
256292
}
257293

@@ -269,13 +305,13 @@ func (c *oauthConnector) addGroupsFromToken(groups map[string]struct{}, token st
269305
return err
270306
}
271307

272-
var claimsMap map[string]interface{}
308+
var claimsMap interface{}
273309
err = json.Unmarshal(decoded, &claimsMap)
274310
if err != nil {
275311
return err
276312
}
277313

278-
return c.addGroupsFromMap(groups, claimsMap)
314+
return c.addGroups(groups, claimsMap)
279315
}
280316

281317
func decode(seg string) ([]byte, error) {

0 commit comments

Comments
 (0)