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:
		| @@ -36,4 +36,9 @@ connectors: | ||||
|     - my-group | ||||
|     # Prompt for username field. | ||||
|     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 | ||||
| ``` | ||||
|   | ||||
| @@ -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. | | ||||
| | [Bitbucket Cloud](Documentation/connectors/bitbucketcloud.md) | yes | yes | no | alpha | | | ||||
| | [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: | ||||
|  | ||||
|   | ||||
| @@ -35,6 +35,7 @@ import ( | ||||
| //       - admin | ||||
| //       # Prompt for username field | ||||
| //       usernamePrompt: Login | ||||
| //		 preferredUsernameField: name | ||||
| // | ||||
| type Config struct { | ||||
| 	BaseURL      string   `json:"baseURL"` | ||||
| @@ -42,6 +43,11 @@ type Config struct { | ||||
| 	ClientSecret string   `json:"clientSecret"` | ||||
| 	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 | ||||
| 	// in the username/password prompt). If unset, the handler will use. | ||||
| 	// "Username". | ||||
| @@ -368,6 +374,19 @@ func (c *crowdConnector) identityFromCrowdUser(user crowdUser) (connector.Identi | ||||
| 		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 | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -104,6 +104,53 @@ func TestUserPassword(t *testing.T) { | ||||
| 	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 { | ||||
| 	Body interface{} | ||||
| 	Code int | ||||
|   | ||||
		Reference in New Issue
	
	Block a user