Commit 1ac213f9 authored by ale's avatar ale

Add the "shard" field to UserInfo

Useful for partitioned (sharded) services that need to make
partition-related decisions at authentication time.
parent 66f3bb51
Pipeline #715 passed with stages
in 1 minute and 2 seconds
......@@ -90,9 +90,11 @@ func (r *Request) DecodeFromMap(m map[string]string, prefix string) {
r.DeviceInfo = decodeDeviceInfoFromMap(m, prefix+"device.")
}
// UserInfo contains optional user information.
// UserInfo contains optional user information that may be useful to
// authentication endpoints.
type UserInfo struct {
Email string
Shard string
Groups []string
}
......@@ -100,13 +102,19 @@ func (u *UserInfo) EncodeToMap(m map[string]string, prefix string) {
if u.Email != "" {
m[prefix+"email"] = u.Email
}
if u.Shard != "" {
m[prefix+"shard"] = u.Shard
}
for i, g := range u.Groups {
m[fmt.Sprintf("%sgroup.%d.", prefix, i)] = g
}
}
func decodeUserInfoFromMap(m map[string]string, prefix string) *UserInfo {
u := UserInfo{Email: m[prefix+"email"]}
u := UserInfo{
Email: m[prefix+"email"],
Shard: m[prefix+"shard"],
}
i := 0
for {
s, ok := m[fmt.Sprintf("%sgroup.%d.", prefix, i)]
......
......@@ -71,6 +71,7 @@ func TestProtocol_SerializeResponse(t *testing.T) {
},
UserInfo: &UserInfo{
Email: "test@example.com",
Shard: "42",
Groups: []string{"group1", "group2", "group3"},
},
}
......
......@@ -26,6 +26,7 @@ import (
type User struct {
Name string
Email string
Shard string
EncryptedPassword []byte
TOTPSecret string
U2FRegistrations []u2f.Registration
......@@ -59,6 +60,7 @@ func (u *User) HasU2F() bool {
func (u *User) UserInfo() *auth.UserInfo {
return &auth.UserInfo{
Email: u.Email,
Shard: u.Shard,
Groups: u.Groups,
}
}
......
......@@ -73,6 +73,7 @@ var (
- name: 2fauser
email: 2fauser@example.com
shard: 42
password: "16384$8$1$c479e8eb722f1b071efea7826ccf9c20$96d63ebed0c64afb746026f56f71b2a1f8796c73141d2d6b1958d4ea26c60a0b"
totp_secret: "O32OBVS5BL5EAPB5"
`
......
......@@ -11,6 +11,7 @@ import (
type fileBackendUser struct {
Name string `yaml:"name"`
Email string `yaml:"email"`
Shard string `yaml:"shard"`
EncryptedPassword string `yaml:"password"`
TOTPSecret string `yaml:"totp_secret"`
Groups []string `yaml:"groups"`
......@@ -20,6 +21,7 @@ func (f *fileBackendUser) ToUser() *User {
return &User{
Name: f.Name,
Email: f.Email,
Shard: f.Shard,
EncryptedPassword: []byte(f.EncryptedPassword),
TOTPSecret: f.TOTPSecret,
Groups: f.Groups,
......
......@@ -100,10 +100,13 @@ func (c *LDAPServiceConfig) userFromResponse(username string, result *ldap.Searc
entry := result.Entries[0]
// Apply the attribute map.
// Apply the attribute map. We don't care if an attribute is
// not defined in the map, as the get* functions will silently
// ignore an empty attribute name.
u := User{
Name: username,
Email: getStringFromLDAPEntry(entry, c.Attrs["email"]),
Shard: getStringFromLDAPEntry(entry, c.Attrs["shard"]),
EncryptedPassword: []byte(dropCryptPrefix(getStringFromLDAPEntry(entry, c.Attrs["password"]))),
TOTPSecret: getStringFromLDAPEntry(entry, c.Attrs["totp_secret"]),
AppSpecificPasswords: decodeAppSpecificPasswordList(getListFromLDAPEntry(entry, c.Attrs["app_specific_password"])),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment