make userName configurable

This commit is contained in:
flarno11 2019-06-02 21:33:53 +02:00
parent dfb2dfd333
commit 8c1716d356
3 changed files with 42 additions and 10 deletions

View file

@ -71,7 +71,11 @@ connectors:
# Default: sub # Default: sub
# Claims list at https://openid.net/specs/openid-connect-core-1_0.html#Claims # Claims list at https://openid.net/specs/openid-connect-core-1_0.html#Claims
# #
# userIdKey: nickname # userIDKey: nickname
# The set claim is used as user name.
# Default: name
# userNameKey: nickname
``` ```
[oidc-doc]: openid-connect.md [oidc-doc]: openid-connect.md

View file

@ -47,6 +47,9 @@ type Config struct {
// Configurable key which contains the user id claim // Configurable key which contains the user id claim
UserIDKey string `json:"userIDKey"` UserIDKey string `json:"userIDKey"`
// Configurable key which contains the user name claim
UserNameKey string `json:"userNameKey"`
} }
// Domains that don't support basic auth. golang.org/x/oauth2 has an internal // Domains that don't support basic auth. golang.org/x/oauth2 has an internal
@ -131,6 +134,7 @@ func (c *Config) Open(id string, logger log.Logger) (conn connector.Connector, e
insecureSkipEmailVerified: c.InsecureSkipEmailVerified, insecureSkipEmailVerified: c.InsecureSkipEmailVerified,
getUserInfo: c.GetUserInfo, getUserInfo: c.GetUserInfo,
userIDKey: c.UserIDKey, userIDKey: c.UserIDKey,
userNameKey: c.UserNameKey,
}, nil }, nil
} }
@ -151,6 +155,7 @@ type oidcConnector struct {
insecureSkipEmailVerified bool insecureSkipEmailVerified bool
getUserInfo bool getUserInfo bool
userIDKey string userIDKey string
userNameKey string
} }
func (c *oidcConnector) Close() error { func (c *oidcConnector) Close() error {
@ -209,9 +214,13 @@ func (c *oidcConnector) HandleCallback(s connector.Scopes, r *http.Request) (ide
return identity, fmt.Errorf("oidc: failed to decode claims: %v", err) return identity, fmt.Errorf("oidc: failed to decode claims: %v", err)
} }
name, found := claims["name"].(string) userNameKey := "name"
if c.userNameKey != "" {
userNameKey = c.userNameKey
}
name, found := claims[userNameKey].(string)
if !found { if !found {
return identity, errors.New("missing \"name\" claim") return identity, fmt.Errorf("missing \"%s\" claim", userNameKey)
} }
email, found := claims["email"].(string) email, found := claims["email"].(string)
if !found { if !found {

View file

@ -47,14 +47,18 @@ func TestHandleCallback(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
userIDKey string userIDKey string
userNameKey string
insecureSkipEmailVerified bool insecureSkipEmailVerified bool
expectUserID string expectUserID string
expectUserName string
token map[string]interface{} token map[string]interface{}
}{ }{
{ {
name: "simpleCase", name: "simpleCase",
userIDKey: "", // not configured userIDKey: "", // not configured
expectUserID: "subvalue", userNameKey: "", // not configured
expectUserID: "subvalue",
expectUserName: "namevalue",
token: map[string]interface{}{ token: map[string]interface{}{
"sub": "subvalue", "sub": "subvalue",
"name": "namevalue", "name": "namevalue",
@ -66,6 +70,7 @@ func TestHandleCallback(t *testing.T) {
name: "email_verified not in claims, configured to be skipped", name: "email_verified not in claims, configured to be skipped",
insecureSkipEmailVerified: true, insecureSkipEmailVerified: true,
expectUserID: "subvalue", expectUserID: "subvalue",
expectUserName: "namevalue",
token: map[string]interface{}{ token: map[string]interface{}{
"sub": "subvalue", "sub": "subvalue",
"name": "namevalue", "name": "namevalue",
@ -73,9 +78,10 @@ func TestHandleCallback(t *testing.T) {
}, },
}, },
{ {
name: "withUserIDKey", name: "withUserIDKey",
userIDKey: "name", userIDKey: "name",
expectUserID: "namevalue", expectUserID: "namevalue",
expectUserName: "namevalue",
token: map[string]interface{}{ token: map[string]interface{}{
"sub": "subvalue", "sub": "subvalue",
"name": "namevalue", "name": "namevalue",
@ -83,6 +89,18 @@ func TestHandleCallback(t *testing.T) {
"email_verified": true, "email_verified": true,
}, },
}, },
{
name: "withUserNameKey",
userNameKey: "user_name",
expectUserID: "subvalue",
expectUserName: "username",
token: map[string]interface{}{
"sub": "subvalue",
"user_name": "username",
"email": "emailvalue",
"email_verified": true,
},
},
} }
for _, tc := range tests { for _, tc := range tests {
@ -100,6 +118,7 @@ func TestHandleCallback(t *testing.T) {
Scopes: []string{"groups"}, Scopes: []string{"groups"},
RedirectURI: fmt.Sprintf("%s/callback", serverURL), RedirectURI: fmt.Sprintf("%s/callback", serverURL),
UserIDKey: tc.userIDKey, UserIDKey: tc.userIDKey,
UserNameKey: tc.userNameKey,
InsecureSkipEmailVerified: tc.insecureSkipEmailVerified, InsecureSkipEmailVerified: tc.insecureSkipEmailVerified,
} }
@ -119,7 +138,7 @@ func TestHandleCallback(t *testing.T) {
} }
expectEquals(t, identity.UserID, tc.expectUserID) expectEquals(t, identity.UserID, tc.expectUserID)
expectEquals(t, identity.Username, "namevalue") expectEquals(t, identity.Username, tc.expectUserName)
expectEquals(t, identity.Email, "emailvalue") expectEquals(t, identity.Email, "emailvalue")
expectEquals(t, identity.EmailVerified, true) expectEquals(t, identity.EmailVerified, true)
}) })