forked from mystiq/dex
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:
parent
cd054c71af
commit
0a85a97ba9
4 changed files with 72 additions and 0 deletions
|
@ -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
|
||||||
```
|
```
|
||||||
|
|
|
@ -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:
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue