[FEATURE] Add configurable display name to frontend (#1124)
* [FEATURE] Add configurable display name to frontend This feature allows users with a LDAP backend to specify an attribute (default is "displayname") to retrieve a users name for the portal greeting. Similarly for the file based backend a new required key "name" has been introduced. This can also be used down the line with OIDC as a separate scope. * Update references from Name to DisplayName * Update compose bundles to include displayname refs * Update LDAP automatic profile refresh * Ensure display name is updated * Fix bug which prevented trace logging for profile refresh to not triggerpull/1123/head^2
parent
91376a5b3d
commit
e43bc93047
32
BREAKING.md
32
BREAKING.md
|
@ -6,6 +6,38 @@ recommended not to use the 'latest' Docker image tag blindly but pick a version
|
|||
and read this documentation before upgrading. This is where you will get information about
|
||||
breaking changes and about what you should do to overcome those changes.
|
||||
|
||||
## Breaking in v4.21.0
|
||||
* New LDAP attribute `display_name_attribute` has been introduced, defaults to value: `displayname`.
|
||||
* New key `displayname` has been introduced into the file based user database.
|
||||
|
||||
These are utilised to greet the logged in user.
|
||||
|
||||
If utilising a file based user backend:
|
||||
* Administrators will need to update users and include the `displayname` key.
|
||||
|
||||
**Before:**
|
||||
```yaml
|
||||
users:
|
||||
john:
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: john.doe@authelia.com
|
||||
groups:
|
||||
- admins
|
||||
- dev
|
||||
```
|
||||
**After:**
|
||||
```yaml
|
||||
users:
|
||||
john:
|
||||
displayname: "John Doe"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: john.doe@authelia.com
|
||||
groups:
|
||||
- admins
|
||||
- dev
|
||||
```
|
||||
* Users with long-lived sessions will need to recreate the session (logout and login) to propagate the changes.
|
||||
|
||||
## Breaking in v4.20.0
|
||||
* Authelia's Docker volumes have been refactored. All data should reside within a single volume of `/config`.
|
||||
All examples have been updated to reflect this change. The entrypoint for the container changed from
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
# List of users
|
||||
users:
|
||||
authelia:
|
||||
displayname: "Authelia User"
|
||||
password: "$6$rounds=50000$BpLnfgDsc2WD8F2q$Zis.ixdg9s/UOJYrs56b5QEZFiZECu0qZVNsIYxBaNJ7ucIL.nlxVCT5tqh8KHG8X4tlwCFm5r6NTOZZ5qRFN/" # Password is 'authelia'
|
||||
email: authelia@authelia.com
|
||||
groups:
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
# List of users
|
||||
users:
|
||||
<USERNAME>:
|
||||
displayname: "<DISPLAYNAME>"
|
||||
password: "<PASSWORD>"
|
||||
email: <USERNAME>@example.com
|
||||
groups:
|
||||
|
|
|
@ -8,6 +8,10 @@ password(){
|
|||
read -esp "Enter a password for $USERNAME: " PASSWORD
|
||||
}
|
||||
|
||||
displayname(){
|
||||
read -ep "Enter your display name for Authelia (eg. John Doe): " DISPLAYNAME
|
||||
}
|
||||
|
||||
echo "Checking for pre-requisites"
|
||||
|
||||
if [[ ! -x "$(command -v docker)" ]]; then
|
||||
|
@ -63,6 +67,19 @@ else
|
|||
username
|
||||
fi
|
||||
|
||||
displayname
|
||||
|
||||
if [[ $DISPLAYNAME != "" ]]; then
|
||||
if [[ $(uname) == "Darwin" ]]; then
|
||||
sed -i '' "s/<DISPLAYNAME>/$DISPLAYNAME/g" authelia/users_database.yml
|
||||
else
|
||||
sed -i "s/<DISPLAYNAME>/$DISPLAYNAME/g" authelia/users_database.yml
|
||||
fi
|
||||
else
|
||||
echo "Display name cannot be empty"
|
||||
displayname
|
||||
fi
|
||||
|
||||
password
|
||||
|
||||
if [[ $PASSWORD != "" ]]; then
|
||||
|
|
|
@ -151,6 +151,9 @@ authentication_backend:
|
|||
# one returned by the LDAP server is used.
|
||||
mail_attribute: mail
|
||||
|
||||
# The attribute holding the display name of the user. This will be used to greet an authenticated user.
|
||||
display_name_attribute: displayname
|
||||
|
||||
# The username and password of the admin user.
|
||||
user: cn=admin,dc=example,dc=com
|
||||
# Password can also be set using a secret: https://docs.authelia.com/configuration/secrets.html
|
||||
|
|
|
@ -51,21 +51,25 @@ The format of the users file is as follows.
|
|||
```yaml
|
||||
users:
|
||||
john:
|
||||
displayname: "John Doe"
|
||||
password: "$argon2id$v=19$m=65536,t=3,p=2$BpLnfgDsc2WD8F2q$o/vzA4myCqZZ36bUGsDY//8mKUYNZZaR0t4MFFSs+iM"
|
||||
email: john.doe@authelia.com
|
||||
groups:
|
||||
- admins
|
||||
- dev
|
||||
harry:
|
||||
displayname: "Harry Potter"
|
||||
password: "$argon2id$v=19$m=65536,t=3,p=2$BpLnfgDsc2WD8F2q$o/vzA4myCqZZ36bUGsDY//8mKUYNZZaR0t4MFFSs+iM"
|
||||
email: harry.potter@authelia.com
|
||||
groups: []
|
||||
bob:
|
||||
displayname: "Bob Dylan"
|
||||
password: "$argon2id$v=19$m=65536,t=3,p=2$BpLnfgDsc2WD8F2q$o/vzA4myCqZZ36bUGsDY//8mKUYNZZaR0t4MFFSs+iM"
|
||||
email: bob.dylan@authelia.com
|
||||
groups:
|
||||
- dev
|
||||
james:
|
||||
displayname: "James Dean"
|
||||
password: "$argon2id$v=19$m=65536,t=3,p=2$BpLnfgDsc2WD8F2q$o/vzA4myCqZZ36bUGsDY//8mKUYNZZaR0t4MFFSs+iM"
|
||||
email: james.dean@authelia.com
|
||||
```
|
||||
|
|
|
@ -88,6 +88,9 @@ authentication_backend:
|
|||
# The attribute holding the mail address of the user
|
||||
mail_attribute: mail
|
||||
|
||||
# The attribute holding the display name of the user. This will be used to greet an authenticated user.
|
||||
display_name_attribute: displayname
|
||||
|
||||
# The username and password of the admin user. If multiple email addresses are defined for a user, only the first
|
||||
# one returned by the LDAP server is used.
|
||||
user: cn=admin,dc=example,dc=com
|
||||
|
|
|
@ -2,4 +2,4 @@ package authentication
|
|||
|
||||
import "aletheia.icu/broccoli/fs"
|
||||
|
||||
var cfg = fs.New(false, []byte("\x8b\xa1\x80\r\xff\x83\x02\x01\x02\xff\x84\x00\x01\xff\x82\x00\x00=\xff\x81\x03\x01\x02\xff\x82\x00\x01\x05\x01\x04Data\x01\n\x00\x01\x05Fpath\x01\f\x00\x01\x05Fname\x01\f\x00\x01\x05Fsize\x01\x04\x00\x01\x05Ftime\x01\x04\x00\x00\x00\xff\xf6\xff\x84\x00\x01\x01\xff\xaa\x1b\xe6\x00`\x1c\x87\xb1\xf3\xa4II\xda\xd3]\xbci`\x9e\xa9θ\x13\x91\xe6\x06\xb8A\xc2Z\x14F\x8fNn~P\xeb\xe7nAy@\x10C 7\xecwSb\xed\x15\xee>\x0f\xa3\xbe\x8b\xfc,\xb6\xa3\x98\xfe\xe7\x00Bj²\x90b\x0f\x19\xc4=\x92\x8b\xc2j\xb7\xden\x98Nd\xaa\x1d\xa2?J\xc9\xd3ŗ\xb9\x9cM+\u07bf\xfe\xcf{c\x85H9\xaf\xec97\xa6\xe4o\xeaƘ\xdfO\xf1\xf3\xdd\\\xd2Iٮ\u074b\xaa4i#\x17\xc5w=\x19\xd9\n\x02\xbf3o\xdc\x028\rp:\xf7\x011\x8fY\x88g\x87\x9c\b}\xf8\xa1\xc8mݞ?\x00\x01\x1busers_database.template.yml\x01\x1busers_database.template.yml\x01\xfe\x01\xce\x01\xfc\xbd\xcb\xdc\xf6\x00\x03"))
|
||||
var cfg = fs.New(false, []byte("\x1b\x8b\x01\x006B\xe6\xf4A<4\x19\x01\x1fdurk\v(@<\x06\xdf\n0L=\x92\xc0\x12\xe5JP:\xc3\x02sv\x9cu\xc2GRQ \n\x92\x06 \x92\x02\x80<\x92\x8c\nQ\x16D\x87h/\xa1\x808\\\x03O\x887\x80\n\xdd \x1a:\xd2\x00\xfc\x87\xf2\xb1\xa7A\xe4\x13-@a\xca+\x13x_\xa6|\xfb\xd6\xf1\x84\xb9ś\xe5~Ҵf\xe1L~@~\x05OՈ\xec\x1c]\x00\xd1\xeer\xd8\xd0\xd3L\x8f\xb7\x16\xae\x94>\xb5\xbd\a\x16\xba\xf44\x9f\x1e\x1e)o\xe4`\xa1\x9e\x88[\rlY\xbaa=I\x13\xda\xc2}X(x2l[\x192\xe7\xf8`\x9b\xba\xdfd!s\xf3u\xf6\xa59'\xda?q\x0e\xa5\xcf1\x01\x96\x9b\xf6\"u@jh\x9cj,,\xed\v\xd6\xfc\xc1\xd3\xda\xf8\x15\x8e\x1f\xfb\xcf\xfc>T\xbc\xbd\u0379*u\x9fi\xa6\xfc\xf9\xfa\xd4d\x90Y\xb6\xdf\xe1\xed\xb3\xb3\x9eC$\xfd\x97\v\xe5\xb9\xec\xf8N\xfc\xb0\xb3\xa0\xa2\xe4\xafz\x8f\a\xf1\x9e\n\xf5\xf1\x06\xe5\u007f\a.\xa6(\t\x1f\x18?t_\xff\xf42aJ\xf6E\xe8\ue7c3\x02\x01\xfc\x8e\xf3\xd8\x0f\fD\x12\xb5h\xbf\v\v\\\x1cB\x85KB\x88\x9b&\xf5]\"\x95Tɿeކ|À\xb4\x8et\xe4\xa1\xc0\xeb\x81@\xb4\xbf_\xb0\xfcGC\x81\u007f\xe7/\x8e\x00\x00"))
|
||||
|
|
|
@ -29,6 +29,7 @@ type FileUserProvider struct {
|
|||
// UserDetailsModel is the model of user details in the file database.
|
||||
type UserDetailsModel struct {
|
||||
HashedPassword string `yaml:"password" valid:"required"`
|
||||
DisplayName string `yaml:"displayname" valid:"required"`
|
||||
Email string `yaml:"email"`
|
||||
Groups []string `yaml:"groups"`
|
||||
}
|
||||
|
@ -183,9 +184,10 @@ func (p *FileUserProvider) CheckUserPassword(username string, password string) (
|
|||
func (p *FileUserProvider) GetDetails(username string) (*UserDetails, error) {
|
||||
if details, ok := p.database.Users[username]; ok {
|
||||
return &UserDetails{
|
||||
Username: username,
|
||||
Groups: details.Groups,
|
||||
Emails: []string{details.Email},
|
||||
Username: username,
|
||||
DisplayName: details.DisplayName,
|
||||
Groups: details.Groups,
|
||||
Emails: []string{details.Email},
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -287,6 +287,7 @@ var (
|
|||
var UserDatabaseContent = []byte(`
|
||||
users:
|
||||
john:
|
||||
displayname: "John Doe"
|
||||
password: "{CRYPT}$argon2id$v=19$m=65536,t=3,p=2$BpLnfgDsc2WD8F2q$o/vzA4myCqZZ36bUGsDY//8mKUYNZZaR0t4MFFSs+iM"
|
||||
email: john.doe@authelia.com
|
||||
groups:
|
||||
|
@ -294,22 +295,26 @@ users:
|
|||
- dev
|
||||
|
||||
harry:
|
||||
displayname: "Harry Potter"
|
||||
password: "{CRYPT}$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: harry.potter@authelia.com
|
||||
groups: []
|
||||
|
||||
bob:
|
||||
displayname: "Bob Dylan"
|
||||
password: "{CRYPT}$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: bob.dylan@authelia.com
|
||||
groups:
|
||||
- dev
|
||||
|
||||
james:
|
||||
displayname: "James Dean"
|
||||
password: "{CRYPT}$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: james.dean@authelia.com
|
||||
|
||||
|
||||
enumeration:
|
||||
displayname: "Enumeration"
|
||||
password: "$argon2id$v=19$m=131072,p=8$BpLnfgDsc2WD8F2q$O126GHPeZ5fwj7OLSs7PndXsTbje76R+QW9/EGfhkJg"
|
||||
email: james.dean@authelia.com
|
||||
`)
|
||||
|
@ -327,6 +332,7 @@ groups:
|
|||
var BadSchemaUserDatabaseContent = []byte(`
|
||||
user:
|
||||
john:
|
||||
displayname: "John Doe"
|
||||
password: "{CRYPT}$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: john.doe@authelia.com
|
||||
groups:
|
||||
|
@ -337,12 +343,14 @@ user:
|
|||
var UserDatabaseWithoutCryptContent = []byte(`
|
||||
users:
|
||||
john:
|
||||
displayname: "John Doe"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: john.doe@authelia.com
|
||||
groups:
|
||||
- admins
|
||||
- dev
|
||||
james:
|
||||
displayname: "James Dean"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: james.dean@authelia.com
|
||||
`)
|
||||
|
@ -350,12 +358,14 @@ users:
|
|||
var BadSHA512HashContent = []byte(`
|
||||
users:
|
||||
john:
|
||||
displayname: "John Doe"
|
||||
password: "$6$rounds00000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: john.doe@authelia.com
|
||||
groups:
|
||||
- admins
|
||||
- dev
|
||||
james:
|
||||
displayname: "James Dean"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: james.dean@authelia.com
|
||||
`)
|
||||
|
@ -363,12 +373,14 @@ users:
|
|||
var BadArgon2idHashSettingsContent = []byte(`
|
||||
users:
|
||||
john:
|
||||
displayname: "John Doe"
|
||||
password: "$argon2id$v=19$m65536,t3,p2$BpLnfgDsc2WD8F2q$o/vzA4myCqZZ36bUGsDY//8mKUYNZZaR0t4MFFSs+iM"
|
||||
email: john.doe@authelia.com
|
||||
groups:
|
||||
- admins
|
||||
- dev
|
||||
james:
|
||||
displayname: "James Dean"
|
||||
password: "$argon2id$v=19$m=65536,t=3,p=2$BpLnfgDsc2WD8F2q$o/vzA4myCqZZ36bUGsDY//8mKUYNZZaR0t4MFFSs+iM"
|
||||
email: james.dean@authelia.com
|
||||
`)
|
||||
|
@ -376,6 +388,7 @@ users:
|
|||
var BadArgon2idHashKeyContent = []byte(`
|
||||
users:
|
||||
john:
|
||||
displayname: "John Doe"
|
||||
password: "$argon2id$v=19$m=65536,t=3,p=2$BpLnfgDsc2WD8F2q$^^vzA4myCqZZ36bUGsDY//8mKUYNZZaR0t4MFFSs+iM"
|
||||
email: john.doe@authelia.com
|
||||
groups:
|
||||
|
@ -385,6 +398,7 @@ users:
|
|||
var BadArgon2idHashSaltContent = []byte(`
|
||||
users:
|
||||
john:
|
||||
displayname: "John Doe"
|
||||
password: "$argon2id$v=19$m=65536,t=3,p=2$^^LnfgDsc2WD8F2q$o/vzA4myCqZZ36bUGsDY//8mKUYNZZaR0t4MFFSs+iM"
|
||||
email: john.doe@authelia.com
|
||||
groups:
|
||||
|
|
|
@ -108,9 +108,10 @@ func (p *LDAPUserProvider) ldapEscape(inputUsername string) string {
|
|||
}
|
||||
|
||||
type ldapUserProfile struct {
|
||||
DN string
|
||||
Emails []string
|
||||
Username string
|
||||
DN string
|
||||
Emails []string
|
||||
DisplayName string
|
||||
Username string
|
||||
}
|
||||
|
||||
func (p *LDAPUserProvider) resolveUsersFilter(userFilter string, inputUsername string) string {
|
||||
|
@ -126,6 +127,7 @@ func (p *LDAPUserProvider) resolveUsersFilter(userFilter string, inputUsername s
|
|||
// in configuration.
|
||||
userFilter = strings.ReplaceAll(userFilter, "{username_attribute}", p.configuration.UsernameAttribute)
|
||||
userFilter = strings.ReplaceAll(userFilter, "{mail_attribute}", p.configuration.MailAttribute)
|
||||
userFilter = strings.ReplaceAll(userFilter, "{display_name_attribute}", p.configuration.DisplayNameAttribute)
|
||||
|
||||
return userFilter
|
||||
}
|
||||
|
@ -140,6 +142,7 @@ func (p *LDAPUserProvider) getUserProfile(conn LDAPConnection, inputUsername str
|
|||
}
|
||||
|
||||
attributes := []string{"dn",
|
||||
p.configuration.DisplayNameAttribute,
|
||||
p.configuration.MailAttribute,
|
||||
p.configuration.UsernameAttribute}
|
||||
|
||||
|
@ -167,6 +170,10 @@ func (p *LDAPUserProvider) getUserProfile(conn LDAPConnection, inputUsername str
|
|||
}
|
||||
|
||||
for _, attr := range sr.Entries[0].Attributes {
|
||||
if attr.Name == p.configuration.DisplayNameAttribute {
|
||||
userProfile.DisplayName = attr.Values[0]
|
||||
}
|
||||
|
||||
if attr.Name == p.configuration.MailAttribute {
|
||||
userProfile.Emails = attr.Values
|
||||
}
|
||||
|
@ -254,9 +261,10 @@ func (p *LDAPUserProvider) GetDetails(inputUsername string) (*UserDetails, error
|
|||
}
|
||||
|
||||
return &UserDetails{
|
||||
Username: profile.Username,
|
||||
Emails: profile.Emails,
|
||||
Groups: groups,
|
||||
Username: profile.Username,
|
||||
DisplayName: profile.DisplayName,
|
||||
Emails: profile.Emails,
|
||||
Groups: groups,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -97,9 +97,10 @@ func TestEscapeSpecialCharsInGroupsFilter(t *testing.T) {
|
|||
}, mockFactory)
|
||||
|
||||
profile := ldapUserProfile{
|
||||
DN: "cn=john (external),dc=example,dc=com",
|
||||
Username: "john",
|
||||
Emails: []string{"john.doe@authelia.com"},
|
||||
DN: "cn=john (external),dc=example,dc=com",
|
||||
Username: "john",
|
||||
DisplayName: "John Doe",
|
||||
Emails: []string{"john.doe@authelia.com"},
|
||||
}
|
||||
|
||||
filter, _ := ldap.resolveGroupsFilter("john", &profile)
|
||||
|
@ -134,14 +135,15 @@ func TestShouldEscapeUserInput(t *testing.T) {
|
|||
mockConn := NewMockLDAPConnection(ctrl)
|
||||
|
||||
ldapClient := NewLDAPUserProviderWithFactory(schema.LDAPAuthenticationBackendConfiguration{
|
||||
URL: "ldap://127.0.0.1:389",
|
||||
User: "cn=admin,dc=example,dc=com",
|
||||
UsersFilter: "(|({username_attribute}={input})({mail_attribute}={input}))",
|
||||
UsernameAttribute: "uid",
|
||||
MailAttribute: "mail",
|
||||
Password: "password",
|
||||
AdditionalUsersDN: "ou=users",
|
||||
BaseDN: "dc=example,dc=com",
|
||||
URL: "ldap://127.0.0.1:389",
|
||||
User: "cn=admin,dc=example,dc=com",
|
||||
UsersFilter: "(|({username_attribute}={input})({mail_attribute}={input}))",
|
||||
UsernameAttribute: "uid",
|
||||
MailAttribute: "mail",
|
||||
DisplayNameAttribute: "displayname",
|
||||
Password: "password",
|
||||
AdditionalUsersDN: "ou=users",
|
||||
BaseDN: "dc=example,dc=com",
|
||||
}, mockFactory)
|
||||
|
||||
mockConn.EXPECT().
|
||||
|
@ -160,14 +162,15 @@ func TestShouldCombineUsernameFilterAndUsersFilter(t *testing.T) {
|
|||
mockConn := NewMockLDAPConnection(ctrl)
|
||||
|
||||
ldapClient := NewLDAPUserProviderWithFactory(schema.LDAPAuthenticationBackendConfiguration{
|
||||
URL: "ldap://127.0.0.1:389",
|
||||
User: "cn=admin,dc=example,dc=com",
|
||||
UsernameAttribute: "uid",
|
||||
UsersFilter: "(&({username_attribute}={input})(&(objectCategory=person)(objectClass=user)))",
|
||||
Password: "password",
|
||||
AdditionalUsersDN: "ou=users",
|
||||
BaseDN: "dc=example,dc=com",
|
||||
MailAttribute: "mail",
|
||||
URL: "ldap://127.0.0.1:389",
|
||||
User: "cn=admin,dc=example,dc=com",
|
||||
UsernameAttribute: "uid",
|
||||
UsersFilter: "(&({username_attribute}={input})(&(objectCategory=person)(objectClass=user)))",
|
||||
Password: "password",
|
||||
AdditionalUsersDN: "ou=users",
|
||||
BaseDN: "dc=example,dc=com",
|
||||
MailAttribute: "mail",
|
||||
DisplayNameAttribute: "displayname",
|
||||
}, mockFactory)
|
||||
|
||||
mockConn.EXPECT().
|
||||
|
@ -199,14 +202,15 @@ func TestShouldNotCrashWhenGroupsAreNotRetrievedFromLDAP(t *testing.T) {
|
|||
mockConn := NewMockLDAPConnection(ctrl)
|
||||
|
||||
ldapClient := NewLDAPUserProviderWithFactory(schema.LDAPAuthenticationBackendConfiguration{
|
||||
URL: "ldap://127.0.0.1:389",
|
||||
User: "cn=admin,dc=example,dc=com",
|
||||
Password: "password",
|
||||
UsernameAttribute: "uid",
|
||||
MailAttribute: "mail",
|
||||
UsersFilter: "uid={input}",
|
||||
AdditionalUsersDN: "ou=users",
|
||||
BaseDN: "dc=example,dc=com",
|
||||
URL: "ldap://127.0.0.1:389",
|
||||
User: "cn=admin,dc=example,dc=com",
|
||||
Password: "password",
|
||||
UsernameAttribute: "uid",
|
||||
MailAttribute: "mail",
|
||||
DisplayNameAttribute: "displayname",
|
||||
UsersFilter: "uid={input}",
|
||||
AdditionalUsersDN: "ou=users",
|
||||
BaseDN: "dc=example,dc=com",
|
||||
}, mockFactory)
|
||||
|
||||
mockFactory.EXPECT().
|
||||
|
@ -230,6 +234,10 @@ func TestShouldNotCrashWhenGroupsAreNotRetrievedFromLDAP(t *testing.T) {
|
|||
{
|
||||
DN: "uid=test,dc=example,dc=com",
|
||||
Attributes: []*ldap.EntryAttribute{
|
||||
{
|
||||
Name: "displayname",
|
||||
Values: []string{"John Doe"},
|
||||
},
|
||||
{
|
||||
Name: "mail",
|
||||
Values: []string{"test@example.com"},
|
||||
|
@ -250,6 +258,7 @@ func TestShouldNotCrashWhenGroupsAreNotRetrievedFromLDAP(t *testing.T) {
|
|||
|
||||
assert.ElementsMatch(t, details.Groups, []string{})
|
||||
assert.ElementsMatch(t, details.Emails, []string{"test@example.com"})
|
||||
assert.Equal(t, details.DisplayName, "John Doe")
|
||||
assert.Equal(t, details.Username, "john")
|
||||
}
|
||||
|
||||
|
@ -318,14 +327,15 @@ func TestShouldReturnUsernameFromLDAP(t *testing.T) {
|
|||
mockConn := NewMockLDAPConnection(ctrl)
|
||||
|
||||
ldapClient := NewLDAPUserProviderWithFactory(schema.LDAPAuthenticationBackendConfiguration{
|
||||
URL: "ldap://127.0.0.1:389",
|
||||
User: "cn=admin,dc=example,dc=com",
|
||||
Password: "password",
|
||||
UsernameAttribute: "uid",
|
||||
MailAttribute: "mail",
|
||||
UsersFilter: "uid={input}",
|
||||
AdditionalUsersDN: "ou=users",
|
||||
BaseDN: "dc=example,dc=com",
|
||||
URL: "ldap://127.0.0.1:389",
|
||||
User: "cn=admin,dc=example,dc=com",
|
||||
Password: "password",
|
||||
UsernameAttribute: "uid",
|
||||
MailAttribute: "mail",
|
||||
DisplayNameAttribute: "displayname",
|
||||
UsersFilter: "uid={input}",
|
||||
AdditionalUsersDN: "ou=users",
|
||||
BaseDN: "dc=example,dc=com",
|
||||
}, mockFactory)
|
||||
|
||||
mockFactory.EXPECT().
|
||||
|
@ -349,6 +359,10 @@ func TestShouldReturnUsernameFromLDAP(t *testing.T) {
|
|||
{
|
||||
DN: "uid=test,dc=example,dc=com",
|
||||
Attributes: []*ldap.EntryAttribute{
|
||||
{
|
||||
Name: "displayname",
|
||||
Values: []string{"John Doe"},
|
||||
},
|
||||
{
|
||||
Name: "mail",
|
||||
Values: []string{"test@example.com"},
|
||||
|
@ -369,5 +383,6 @@ func TestShouldReturnUsernameFromLDAP(t *testing.T) {
|
|||
|
||||
assert.ElementsMatch(t, details.Groups, []string{"group1", "group2"})
|
||||
assert.ElementsMatch(t, details.Emails, []string{"test@example.com"})
|
||||
assert.Equal(t, details.DisplayName, "John Doe")
|
||||
assert.Equal(t, details.Username, "John")
|
||||
}
|
||||
|
|
|
@ -2,7 +2,8 @@ package authentication
|
|||
|
||||
// UserDetails represent the details retrieved for a given user.
|
||||
type UserDetails struct {
|
||||
Username string
|
||||
Emails []string
|
||||
Groups []string
|
||||
Username string
|
||||
DisplayName string
|
||||
Emails []string
|
||||
Groups []string
|
||||
}
|
||||
|
|
|
@ -2,18 +2,19 @@ package schema
|
|||
|
||||
// LDAPAuthenticationBackendConfiguration represents the configuration related to LDAP server.
|
||||
type LDAPAuthenticationBackendConfiguration struct {
|
||||
URL string `mapstructure:"url"`
|
||||
SkipVerify bool `mapstructure:"skip_verify"`
|
||||
BaseDN string `mapstructure:"base_dn"`
|
||||
AdditionalUsersDN string `mapstructure:"additional_users_dn"`
|
||||
UsersFilter string `mapstructure:"users_filter"`
|
||||
AdditionalGroupsDN string `mapstructure:"additional_groups_dn"`
|
||||
GroupsFilter string `mapstructure:"groups_filter"`
|
||||
GroupNameAttribute string `mapstructure:"group_name_attribute"`
|
||||
UsernameAttribute string `mapstructure:"username_attribute"`
|
||||
MailAttribute string `mapstructure:"mail_attribute"`
|
||||
User string `mapstructure:"user"`
|
||||
Password string `mapstructure:"password"`
|
||||
URL string `mapstructure:"url"`
|
||||
SkipVerify bool `mapstructure:"skip_verify"`
|
||||
BaseDN string `mapstructure:"base_dn"`
|
||||
AdditionalUsersDN string `mapstructure:"additional_users_dn"`
|
||||
UsersFilter string `mapstructure:"users_filter"`
|
||||
AdditionalGroupsDN string `mapstructure:"additional_groups_dn"`
|
||||
GroupsFilter string `mapstructure:"groups_filter"`
|
||||
GroupNameAttribute string `mapstructure:"group_name_attribute"`
|
||||
UsernameAttribute string `mapstructure:"username_attribute"`
|
||||
MailAttribute string `mapstructure:"mail_attribute"`
|
||||
DisplayNameAttribute string `mapstructure:"display_name_attribute"`
|
||||
User string `mapstructure:"user"`
|
||||
Password string `mapstructure:"password"`
|
||||
}
|
||||
|
||||
// FileAuthenticationBackendConfiguration represents the configuration related to file-based backend.
|
||||
|
@ -69,6 +70,7 @@ var DefaultPasswordSHA512Configuration = PasswordConfiguration{
|
|||
|
||||
// DefaultLDAPAuthenticationBackendConfiguration represents the default LDAP config.
|
||||
var DefaultLDAPAuthenticationBackendConfiguration = LDAPAuthenticationBackendConfiguration{
|
||||
MailAttribute: "mail",
|
||||
GroupNameAttribute: "cn",
|
||||
MailAttribute: "mail",
|
||||
DisplayNameAttribute: "displayname",
|
||||
GroupNameAttribute: "cn",
|
||||
}
|
||||
|
|
|
@ -151,6 +151,10 @@ func validateLdapAuthenticationBackend(configuration *schema.LDAPAuthenticationB
|
|||
if configuration.MailAttribute == "" {
|
||||
configuration.MailAttribute = schema.DefaultLDAPAuthenticationBackendConfiguration.MailAttribute
|
||||
}
|
||||
|
||||
if configuration.DisplayNameAttribute == "" {
|
||||
configuration.DisplayNameAttribute = schema.DefaultLDAPAuthenticationBackendConfiguration.DisplayNameAttribute
|
||||
}
|
||||
}
|
||||
|
||||
// ValidateAuthenticationBackend validates and update authentication backend configuration.
|
||||
|
|
|
@ -98,6 +98,7 @@ var validKeys = []string{
|
|||
"authentication_backend.ldap.groups_filter",
|
||||
"authentication_backend.ldap.group_name_attribute",
|
||||
"authentication_backend.ldap.mail_attribute",
|
||||
"authentication_backend.ldap.display_name_attribute",
|
||||
"authentication_backend.ldap.user",
|
||||
"authentication_backend.ldap.password",
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
// ExtendedConfigurationBody the content returned by extended configuration endpoint.
|
||||
type ExtendedConfigurationBody struct {
|
||||
AvailableMethods MethodList `json:"available_methods"`
|
||||
DisplayName string `json:"display_name"`
|
||||
SecondFactorEnabled bool `json:"second_factor_enabled"` // whether second factor is enabled or not.
|
||||
TOTPPeriod int `json:"totp_period"`
|
||||
}
|
||||
|
@ -16,6 +17,7 @@ type ExtendedConfigurationBody struct {
|
|||
func ExtendedConfigurationGet(ctx *middlewares.AutheliaCtx) {
|
||||
body := ExtendedConfigurationBody{}
|
||||
body.AvailableMethods = MethodList{authentication.TOTP, authentication.U2F}
|
||||
body.DisplayName = ctx.GetSession().DisplayName
|
||||
body.TOTPPeriod = ctx.Configuration.TOTP.Period
|
||||
|
||||
if ctx.Configuration.DuoAPI != nil {
|
||||
|
|
|
@ -163,6 +163,7 @@ func FirstFactorPost(msInitialDelay time.Duration, delayEnabled bool) middleware
|
|||
// And set those information in the new session.
|
||||
userSession := ctx.GetSession()
|
||||
userSession.Username = userDetails.Username
|
||||
userSession.DisplayName = userDetails.DisplayName
|
||||
userSession.Groups = userDetails.Groups
|
||||
userSession.Emails = userDetails.Emails
|
||||
userSession.AuthenticationLevel = authentication.OneFactor
|
||||
|
|
|
@ -268,6 +268,7 @@ func generateVerifySessionHasUpToDateProfileTraceLogs(ctx *middlewares.AutheliaC
|
|||
details *authentication.UserDetails) {
|
||||
groupsAdded, groupsRemoved := utils.StringSlicesDelta(userSession.Groups, details.Groups)
|
||||
emailsAdded, emailsRemoved := utils.StringSlicesDelta(userSession.Emails, details.Emails)
|
||||
nameDelta := userSession.DisplayName != details.DisplayName
|
||||
|
||||
// Check Groups.
|
||||
var groupsDelta []string
|
||||
|
@ -300,6 +301,13 @@ func generateVerifySessionHasUpToDateProfileTraceLogs(ctx *middlewares.AutheliaC
|
|||
} else {
|
||||
ctx.Logger.Tracef("No updated emails detected for %s", userSession.Username)
|
||||
}
|
||||
|
||||
// Check Name.
|
||||
if nameDelta {
|
||||
ctx.Logger.Tracef("Updated display name detected for %s. Added: %s. Removed: %s.", userSession.Username, details.DisplayName, userSession.DisplayName)
|
||||
} else {
|
||||
ctx.Logger.Tracef("No updated display name detected for %s", userSession.Username)
|
||||
}
|
||||
}
|
||||
|
||||
func verifySessionHasUpToDateProfile(ctx *middlewares.AutheliaCtx, targetURL *url.URL, userSession *session.UserSession,
|
||||
|
@ -318,10 +326,11 @@ func verifySessionHasUpToDateProfile(ctx *middlewares.AutheliaCtx, targetURL *ur
|
|||
return err
|
||||
}
|
||||
|
||||
groupsDiff := utils.IsStringSlicesDifferent(userSession.Groups, details.Groups)
|
||||
emailsDiff := utils.IsStringSlicesDifferent(userSession.Emails, details.Emails)
|
||||
groupsDiff := utils.IsStringSlicesDifferent(userSession.Groups, details.Groups)
|
||||
nameDiff := userSession.DisplayName != details.DisplayName
|
||||
|
||||
if !groupsDiff && !emailsDiff {
|
||||
if !groupsDiff && !emailsDiff && !nameDiff {
|
||||
ctx.Logger.Tracef("Updated profile not detected for %s.", userSession.Username)
|
||||
// Only update TTL if the user has a interval set.
|
||||
// We get to this check when there were no changes.
|
||||
|
@ -334,11 +343,12 @@ func verifySessionHasUpToDateProfile(ctx *middlewares.AutheliaCtx, targetURL *ur
|
|||
}
|
||||
} else {
|
||||
ctx.Logger.Debugf("Updated profile detected for %s.", userSession.Username)
|
||||
if ctx.Logger.Level.String() == "trace" {
|
||||
if ctx.Configuration.LogLevel == "trace" {
|
||||
generateVerifySessionHasUpToDateProfileTraceLogs(ctx, userSession, details)
|
||||
}
|
||||
userSession.Groups = details.Groups
|
||||
userSession.Emails = details.Emails
|
||||
userSession.Groups = details.Groups
|
||||
userSession.DisplayName = details.DisplayName
|
||||
|
||||
// Only update TTL if the user has a interval set.
|
||||
if refreshProfileInterval != schema.RefreshIntervalAlways {
|
||||
|
|
|
@ -5,7 +5,6 @@ import (
|
|||
|
||||
"github.com/fasthttp/session/v2"
|
||||
"github.com/fasthttp/session/v2/providers/redis"
|
||||
|
||||
"github.com/tstranex/u2f"
|
||||
|
||||
"github.com/authelia/authelia/internal/authentication"
|
||||
|
@ -26,7 +25,8 @@ type U2FRegistration struct {
|
|||
|
||||
// UserSession is the structure representing the session of a user.
|
||||
type UserSession struct {
|
||||
Username string
|
||||
Username string
|
||||
DisplayName string
|
||||
// TODO(c.michaud): move groups out of the session.
|
||||
Groups []string
|
||||
Emails []string
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
# List of users
|
||||
users:
|
||||
john:
|
||||
displayname: "John Doe"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: john.doe@authelia.com
|
||||
groups:
|
||||
|
@ -14,16 +15,19 @@ users:
|
|||
- dev
|
||||
|
||||
harry:
|
||||
displayname: "Harry Potter"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: harry.potter@authelia.com
|
||||
groups: []
|
||||
|
||||
bob:
|
||||
displayname: "Bob Dylan"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: bob.dylan@authelia.com
|
||||
groups:
|
||||
- dev
|
||||
|
||||
james:
|
||||
displayname: "James Dean"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: james.dean@authelia.com
|
|
@ -1,20 +1,33 @@
|
|||
###############################################################
|
||||
# Users Database #
|
||||
###############################################################
|
||||
|
||||
# This file can be used if you do not have an LDAP set up.
|
||||
|
||||
# List of users
|
||||
users:
|
||||
bob:
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: bob.dylan@authelia.com
|
||||
groups:
|
||||
- dev
|
||||
harry:
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: harry.potter@authelia.com
|
||||
groups: []
|
||||
james:
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: james.dean@authelia.com
|
||||
groups: []
|
||||
john:
|
||||
password: "$6$rounds=50000$LnfgDsc2WD8F2qNf$0gcCt8jlqAGZRv2ee3mCFsfAr1P4N7kESWEf36Xtw6OjkhAcQuGVOBHXp0lFuZbppa7YlgHk3VD28aSQu9U9S1"
|
||||
displayname: "John Doe"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: john.doe@authelia.com
|
||||
groups:
|
||||
- admins
|
||||
- dev
|
||||
|
||||
harry:
|
||||
displayname: "Harry Potter"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: harry.potter@authelia.com
|
||||
groups: []
|
||||
|
||||
bob:
|
||||
displayname: "Bob Dylan"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: bob.dylan@authelia.com
|
||||
groups:
|
||||
- dev
|
||||
|
||||
james:
|
||||
displayname: "James Dean"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: james.dean@authelia.com
|
|
@ -7,6 +7,7 @@
|
|||
# List of users
|
||||
users:
|
||||
john:
|
||||
displayname: "John Doe"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: john.doe@authelia.com
|
||||
groups:
|
||||
|
@ -14,16 +15,19 @@ users:
|
|||
- dev
|
||||
|
||||
harry:
|
||||
displayname: "Harry Potter"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: harry.potter@authelia.com
|
||||
groups: []
|
||||
|
||||
bob:
|
||||
displayname: "Bob Dylan"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: bob.dylan@authelia.com
|
||||
groups:
|
||||
- dev
|
||||
|
||||
james:
|
||||
displayname: "James Dean"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: james.dean@authelia.com
|
|
@ -7,6 +7,7 @@
|
|||
# List of users
|
||||
users:
|
||||
john:
|
||||
displayname: "John Doe"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: john.doe@authelia.com
|
||||
groups:
|
||||
|
@ -14,16 +15,19 @@ users:
|
|||
- dev
|
||||
|
||||
harry:
|
||||
displayname: "Harry Potter"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: harry.potter@authelia.com
|
||||
groups: []
|
||||
|
||||
bob:
|
||||
displayname: "Bob Dylan"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: bob.dylan@authelia.com
|
||||
groups:
|
||||
- dev
|
||||
|
||||
james:
|
||||
displayname: "James Dean"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: james.dean@authelia.com
|
|
@ -7,6 +7,7 @@
|
|||
# List of users
|
||||
users:
|
||||
john:
|
||||
displayname: "John Doe"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: john.doe@authelia.com
|
||||
groups:
|
||||
|
@ -14,16 +15,19 @@ users:
|
|||
- dev
|
||||
|
||||
harry:
|
||||
displayname: "Harry Potter"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: harry.potter@authelia.com
|
||||
groups: []
|
||||
|
||||
bob:
|
||||
displayname: "Bob Dylan"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: bob.dylan@authelia.com
|
||||
groups:
|
||||
- dev
|
||||
|
||||
james:
|
||||
displayname: "James Dean"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: james.dean@authelia.com
|
|
@ -7,6 +7,7 @@
|
|||
# List of users
|
||||
users:
|
||||
john:
|
||||
displayname: "John Doe"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: john.doe@authelia.com
|
||||
groups:
|
||||
|
@ -14,16 +15,19 @@ users:
|
|||
- dev
|
||||
|
||||
harry:
|
||||
displayname: "Harry Potter"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: harry.potter@authelia.com
|
||||
groups: []
|
||||
|
||||
bob:
|
||||
displayname: "Bob Dylan"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: bob.dylan@authelia.com
|
||||
groups:
|
||||
- dev
|
||||
|
||||
james:
|
||||
displayname: "James Dean"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: james.dean@authelia.com
|
|
@ -7,6 +7,7 @@
|
|||
# List of users
|
||||
users:
|
||||
john:
|
||||
displayname: "John Doe"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: john.doe@authelia.com
|
||||
groups:
|
||||
|
@ -14,16 +15,19 @@ users:
|
|||
- dev
|
||||
|
||||
harry:
|
||||
displayname: "Harry Potter"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: harry.potter@authelia.com
|
||||
groups: []
|
||||
|
||||
bob:
|
||||
displayname: "Bob Dylan"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: bob.dylan@authelia.com
|
||||
groups:
|
||||
- dev
|
||||
|
||||
james:
|
||||
displayname: "James Dean"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: james.dean@authelia.com
|
|
@ -7,6 +7,7 @@
|
|||
# List of users
|
||||
users:
|
||||
john:
|
||||
displayname: "John Doe"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: john.doe@authelia.com
|
||||
groups:
|
||||
|
@ -14,16 +15,19 @@ users:
|
|||
- dev
|
||||
|
||||
harry:
|
||||
displayname: "Harry Potter"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: harry.potter@authelia.com
|
||||
groups: []
|
||||
|
||||
bob:
|
||||
displayname: "Bob Dylan"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: bob.dylan@authelia.com
|
||||
groups:
|
||||
- dev
|
||||
|
||||
james:
|
||||
displayname: "James Dean"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: james.dean@authelia.com
|
|
@ -7,6 +7,7 @@
|
|||
# List of users
|
||||
users:
|
||||
john:
|
||||
displayname: "John Doe"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: john.doe@authelia.com
|
||||
groups:
|
||||
|
@ -14,16 +15,19 @@ users:
|
|||
- dev
|
||||
|
||||
harry:
|
||||
displayname: "Harry Potter"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: harry.potter@authelia.com
|
||||
groups: []
|
||||
|
||||
bob:
|
||||
displayname: "Bob Dylan"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: bob.dylan@authelia.com
|
||||
groups:
|
||||
- dev
|
||||
|
||||
james:
|
||||
displayname: "James Dean"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: james.dean@authelia.com
|
|
@ -7,6 +7,7 @@
|
|||
# List of users
|
||||
users:
|
||||
john:
|
||||
displayname: "John Doe"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: john.doe@authelia.com
|
||||
groups:
|
||||
|
@ -14,16 +15,19 @@ users:
|
|||
- dev
|
||||
|
||||
harry:
|
||||
displayname: "Harry Potter"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: harry.potter@authelia.com
|
||||
groups: []
|
||||
|
||||
bob:
|
||||
displayname: "Bob Dylan"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: bob.dylan@authelia.com
|
||||
groups:
|
||||
- dev
|
||||
|
||||
james:
|
||||
displayname: "James Dean"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: james.dean@authelia.com
|
|
@ -7,6 +7,7 @@
|
|||
# List of users
|
||||
users:
|
||||
john:
|
||||
displayname: "John Doe"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: john.doe@authelia.com
|
||||
groups:
|
||||
|
@ -14,16 +15,19 @@ users:
|
|||
- dev
|
||||
|
||||
harry:
|
||||
displayname: "Harry Potter"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: harry.potter@authelia.com
|
||||
groups: []
|
||||
|
||||
bob:
|
||||
displayname: "Bob Dylan"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: bob.dylan@authelia.com
|
||||
groups:
|
||||
- dev
|
||||
|
||||
james:
|
||||
displayname: "James Dean"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: james.dean@authelia.com
|
|
@ -1,20 +1,33 @@
|
|||
###############################################################
|
||||
# Users Database #
|
||||
###############################################################
|
||||
|
||||
# This file can be used if you do not have an LDAP set up.
|
||||
|
||||
# List of users
|
||||
users:
|
||||
bob:
|
||||
password: $6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/
|
||||
email: bob.dylan@authelia.com
|
||||
groups:
|
||||
- dev
|
||||
harry:
|
||||
password: $6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/
|
||||
email: harry.potter@authelia.com
|
||||
groups: []
|
||||
james:
|
||||
password: $6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/
|
||||
email: james.dean@authelia.com
|
||||
groups: []
|
||||
john:
|
||||
password: $6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/
|
||||
displayname: "John Doe"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: john.doe@authelia.com
|
||||
groups:
|
||||
- admins
|
||||
- dev
|
||||
- admins
|
||||
- dev
|
||||
|
||||
harry:
|
||||
displayname: "Harry Potter"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: harry.potter@authelia.com
|
||||
groups: []
|
||||
|
||||
bob:
|
||||
displayname: "Bob Dylan"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: bob.dylan@authelia.com
|
||||
groups:
|
||||
- dev
|
||||
|
||||
james:
|
||||
displayname: "James Dean"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: james.dean@authelia.com
|
|
@ -7,6 +7,7 @@
|
|||
# List of users
|
||||
users:
|
||||
john:
|
||||
displayname: "John Doe"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: john.doe@authelia.com
|
||||
groups:
|
||||
|
@ -14,16 +15,19 @@ users:
|
|||
- dev
|
||||
|
||||
harry:
|
||||
displayname: "Harry Potter"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: harry.potter@authelia.com
|
||||
groups: []
|
||||
|
||||
bob:
|
||||
displayname: "Bob Dylan"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: bob.dylan@authelia.com
|
||||
groups:
|
||||
- dev
|
||||
|
||||
james:
|
||||
displayname: "James Dean"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: james.dean@authelia.com
|
|
@ -7,6 +7,7 @@
|
|||
# List of users
|
||||
users:
|
||||
john:
|
||||
displayname: "John Doe"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: john.doe@authelia.com
|
||||
groups:
|
||||
|
@ -14,16 +15,19 @@ users:
|
|||
- dev
|
||||
|
||||
harry:
|
||||
displayname: "Harry Potter"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: harry.potter@authelia.com
|
||||
groups: []
|
||||
|
||||
bob:
|
||||
displayname: "Bob Dylan"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: bob.dylan@authelia.com
|
||||
groups:
|
||||
- dev
|
||||
|
||||
james:
|
||||
displayname: "James Dean"
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: james.dean@authelia.com
|
|
@ -23,6 +23,7 @@ objectclass: top
|
|||
|
||||
dn: cn=John Doe (external),ou=users,dc=example,dc=com
|
||||
cn: John Doe (external)
|
||||
displayname: John Doe
|
||||
givenName: John
|
||||
objectclass: inetOrgPerson
|
||||
objectclass: top
|
||||
|
@ -33,6 +34,7 @@ userpassword: {CRYPT}$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQ
|
|||
|
||||
dn: cn=Harry Potter,ou=users,dc=example,dc=com
|
||||
cn: Harry Potter
|
||||
displayname: Harry Potter
|
||||
givenName: Harry
|
||||
objectclass: inetOrgPerson
|
||||
objectclass: top
|
||||
|
@ -43,6 +45,7 @@ userpassword: {CRYPT}$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQ
|
|||
|
||||
dn: cn=Bob Dylan,ou=users,dc=example,dc=com
|
||||
cn: Bob Dylan
|
||||
displayname: Bob Dylan
|
||||
givenName: Bob
|
||||
objectclass: inetOrgPerson
|
||||
objectclass: top
|
||||
|
@ -53,6 +56,7 @@ userpassword: {CRYPT}$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQ
|
|||
|
||||
dn: cn=James Dean,ou=users,dc=example,dc=com
|
||||
cn: James Dean
|
||||
displayname: James Dean
|
||||
givenName: James
|
||||
objectclass: inetOrgPerson
|
||||
objectclass: top
|
||||
|
@ -63,6 +67,7 @@ userpassword: {CRYPT}$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQ
|
|||
|
||||
dn: cn=Billy Blackhat,ou=users,dc=example,dc=com
|
||||
cn: Billy Blackhat
|
||||
displayname: Billy Blackhat
|
||||
givenName: Billy
|
||||
objectclass: inetOrgPerson
|
||||
objectclass: top
|
||||
|
|
|
@ -7,6 +7,7 @@ export interface Configuration {
|
|||
|
||||
export interface ExtendedConfiguration {
|
||||
available_methods: Set<SecondFactorMethod>;
|
||||
display_name: string;
|
||||
second_factor_enabled: boolean;
|
||||
totp_period: number;
|
||||
}
|
|
@ -9,6 +9,7 @@ export async function getConfiguration(): Promise<Configuration> {
|
|||
|
||||
interface ExtendedConfigurationPayload {
|
||||
available_methods: Method2FA[];
|
||||
display_name: string;
|
||||
second_factor_enabled: boolean;
|
||||
totp_period: number;
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import { LogoutRoute as SignOutRoute } from "../../../Routes";
|
|||
import Authenticated from "../Authenticated";
|
||||
|
||||
export interface Props {
|
||||
username: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export default function (props: Props) {
|
||||
|
@ -20,7 +20,7 @@ export default function (props: Props) {
|
|||
return (
|
||||
<LoginLayout
|
||||
id="authenticated-stage"
|
||||
title={`Hi ${props.username}`}
|
||||
title={`Hi ${props.name}`}
|
||||
showBrand>
|
||||
<Grid container>
|
||||
<Grid item xs={12}>
|
||||
|
|
|
@ -128,7 +128,6 @@ export default function (props: Props) {
|
|||
</Route>
|
||||
<Route path={SecondFactorRoute}>
|
||||
{state && userInfo && configuration ? <SecondFactorForm
|
||||
username={state.username}
|
||||
authenticationLevel={state.authentication_level}
|
||||
userInfo={userInfo}
|
||||
configuration={configuration}
|
||||
|
@ -136,7 +135,7 @@ export default function (props: Props) {
|
|||
onAuthenticationSuccess={handleAuthSuccess} /> : null}
|
||||
</Route>
|
||||
<Route path={AuthenticatedRoute} exact>
|
||||
{state ? <AuthenticatedView username={state.username} /> : null}
|
||||
{configuration ? <AuthenticatedView name={configuration.display_name} /> : null}
|
||||
</Route>
|
||||
<Route path="/">
|
||||
<Redirect to={FirstFactorRoute} />
|
||||
|
|
|
@ -25,7 +25,6 @@ import { AuthenticationLevel } from "../../../services/State";
|
|||
const EMAIL_SENT_NOTIFICATION = "An email has been sent to your address to complete the process.";
|
||||
|
||||
export interface Props {
|
||||
username: string;
|
||||
authenticationLevel: AuthenticationLevel;
|
||||
|
||||
userInfo: UserInfo;
|
||||
|
@ -89,7 +88,7 @@ export default function (props: Props) {
|
|||
return (
|
||||
<LoginLayout
|
||||
id="second-factor-stage"
|
||||
title={`Hi ${props.username}`}
|
||||
title={`Hi ${props.configuration.display_name}`}
|
||||
showBrand>
|
||||
<MethodSelectionDialog
|
||||
open={methodSelectionOpen}
|
||||
|
|
Loading…
Reference in New Issue