Allow preferred_username claim to be set for Crowd connector (#1684)

* Add atlassiancrowd connector to list in readme

* Add TestIdentityFromCrowdUser

* Set preferred_username claim when configured

* Add preferredUsernameField option to docs

* Log warning when mapping invalid crowd field
This commit is contained in:
Martijn 2020-04-23 20:14:15 +02:00 committed by GitHub
parent cd054c71af
commit 0a85a97ba9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 72 additions and 0 deletions

View file

@ -36,4 +36,9 @@ connectors:
- my-group - my-group
# Prompt for username field. # Prompt for username field.
usernamePrompt: Login usernamePrompt: Login
# Optionally set preferred_username claim.
# If `preferredUsernameField` is omitted or contains an invalid option, the `preferred_username` claim will be empty.
# If `preferredUsernameField` is set, the `preferred_username` claim will be set to the chosen Crowd user attribute value.
# Possible choices are: "key", "name", "email"
preferredUsernameField: name
``` ```

View file

@ -76,6 +76,7 @@ Dex implements the following connectors:
| [AuthProxy](Documentation/connectors/authproxy.md) | no | no | no | alpha | Authentication proxies such as Apache2 mod_auth, etc. | | [AuthProxy](Documentation/connectors/authproxy.md) | no | no | no | alpha | Authentication proxies such as Apache2 mod_auth, etc. |
| [Bitbucket Cloud](Documentation/connectors/bitbucketcloud.md) | yes | yes | no | alpha | | | [Bitbucket Cloud](Documentation/connectors/bitbucketcloud.md) | yes | yes | no | alpha | |
| [OpenShift](Documentation/connectors/openshift.md) | no | yes | no | stable | | | [OpenShift](Documentation/connectors/openshift.md) | no | yes | no | stable | |
| [Atlassian Crowd](Documentation/connectors/atlassiancrowd.md) | yes | yes | yes *) | beta | preferred_username claim must be configured through config |
Stable, beta, and alpha are defined as: Stable, beta, and alpha are defined as:

View file

@ -35,6 +35,7 @@ import (
// - admin // - admin
// # Prompt for username field // # Prompt for username field
// usernamePrompt: Login // usernamePrompt: Login
// preferredUsernameField: name
// //
type Config struct { type Config struct {
BaseURL string `json:"baseURL"` BaseURL string `json:"baseURL"`
@ -42,6 +43,11 @@ type Config struct {
ClientSecret string `json:"clientSecret"` ClientSecret string `json:"clientSecret"`
Groups []string `json:"groups"` Groups []string `json:"groups"`
// PreferredUsernameField allows users to set the field to any of the
// following values: "key", "name" or "email".
// If unset, the preferred_username field will remain empty.
PreferredUsernameField string `json:"preferredUsernameField"`
// UsernamePrompt allows users to override the username attribute (displayed // UsernamePrompt allows users to override the username attribute (displayed
// in the username/password prompt). If unset, the handler will use. // in the username/password prompt). If unset, the handler will use.
// "Username". // "Username".
@ -368,6 +374,19 @@ func (c *crowdConnector) identityFromCrowdUser(user crowdUser) (connector.Identi
EmailVerified: true, EmailVerified: true,
} }
switch c.PreferredUsernameField {
case "key":
identity.PreferredUsername = user.Key
case "name":
identity.PreferredUsername = user.Name
case "email":
identity.PreferredUsername = user.Email
default:
if c.PreferredUsernameField != "" {
c.logger.Warnf("preferred_username left empty. Invalid crowd field mapped to preferred_username: %s", c.PreferredUsernameField)
}
}
return identity, nil return identity, nil
} }

View file

@ -104,6 +104,53 @@ func TestUserPassword(t *testing.T) {
expectNil(t, err) expectNil(t, err)
} }
func TestIdentityFromCrowdUser(t *testing.T) {
user := crowdUser{
Key: "12345",
Name: "testuser",
Active: true,
Email: "testuser@example.com",
}
c := newTestCrowdConnector("/")
// Sanity checks
expectEquals(t, user.Name, "testuser")
expectEquals(t, user.Email, "testuser@example.com")
// Test unconfigured behaviour
i, err := c.identityFromCrowdUser(user)
expectNil(t, err)
expectEquals(t, i.UserID, "12345")
expectEquals(t, i.Username, "testuser")
expectEquals(t, i.Email, "testuser@example.com")
expectEquals(t, i.EmailVerified, true)
// Test for various PreferredUsernameField settings
// unset
expectEquals(t, i.PreferredUsername, "")
c.Config.PreferredUsernameField = "key"
i, err = c.identityFromCrowdUser(user)
expectNil(t, err)
expectEquals(t, i.PreferredUsername, "12345")
c.Config.PreferredUsernameField = "name"
i, err = c.identityFromCrowdUser(user)
expectNil(t, err)
expectEquals(t, i.PreferredUsername, "testuser")
c.Config.PreferredUsernameField = "email"
i, err = c.identityFromCrowdUser(user)
expectNil(t, err)
expectEquals(t, i.PreferredUsername, "testuser@example.com")
c.Config.PreferredUsernameField = "invalidstring"
i, err = c.identityFromCrowdUser(user)
expectNil(t, err)
expectEquals(t, i.PreferredUsername, "")
}
type TestServerResponse struct { type TestServerResponse struct {
Body interface{} Body interface{}
Code int Code int