Auth: Improve username validation and parsing
Signed-off-by: Michael Mayer <michael@photoprism.app>
This commit is contained in:
parent
9762150da6
commit
9ab833c2ec
4 changed files with 32 additions and 9 deletions
|
@ -112,6 +112,15 @@ export class User extends RestModel {
|
|||
};
|
||||
}
|
||||
|
||||
getHandle() {
|
||||
if (!this.Name) {
|
||||
return "";
|
||||
}
|
||||
|
||||
const s = this.Name.split("@");
|
||||
return s[0].trim();
|
||||
}
|
||||
|
||||
getDisplayName() {
|
||||
if (this.DisplayName) {
|
||||
return this.DisplayName;
|
||||
|
|
|
@ -429,11 +429,11 @@ func (m *User) CanUpload() bool {
|
|||
|
||||
// DefaultBasePath returns the default base path of the user based on the user name.
|
||||
func (m *User) DefaultBasePath() string {
|
||||
if m.UserName == "" {
|
||||
if s := m.Handle(); s == "" {
|
||||
return ""
|
||||
} else {
|
||||
return fmt.Sprintf("users/%s", s)
|
||||
}
|
||||
|
||||
return fmt.Sprintf("users/%s", m.UserName)
|
||||
}
|
||||
|
||||
// GetBasePath returns the user's relative base path.
|
||||
|
@ -591,8 +591,7 @@ func (m *User) Email() string {
|
|||
|
||||
// Handle returns the user's login handle.
|
||||
func (m *User) Handle() string {
|
||||
handle, _, _ := strings.Cut(m.UserName, "@")
|
||||
return handle
|
||||
return clean.Handle(m.UserName)
|
||||
}
|
||||
|
||||
// FullName returns the name of the user for display purposes.
|
||||
|
|
|
@ -12,13 +12,16 @@ var EmailRegexp = regexp.MustCompile("^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0
|
|||
|
||||
// Handle returns the sanitized username with trimmed whitespace and in lowercase.
|
||||
func Handle(s string) string {
|
||||
s, _, _ = strings.Cut(s, "@")
|
||||
s = strings.TrimSpace(s)
|
||||
|
||||
// Remove unwanted characters.
|
||||
s = strings.Map(func(r rune) rune {
|
||||
if r <= 42 || r == 127 {
|
||||
if r <= 31 || r == 127 {
|
||||
return -1
|
||||
}
|
||||
switch r {
|
||||
case '`', '~', '?', '|', '*', '\\', '%', '$', '@', ':', ';', '<', '>', '{', '}':
|
||||
case '"', '\'', '(', ')', '#', '&', '$', ',', '+', '=', '`', '~', '?', '|', '*', '\\', '/', ':', ';', '<', '>', '{', '}':
|
||||
return -1
|
||||
}
|
||||
return r
|
||||
|
@ -42,7 +45,7 @@ func Username(s string) string {
|
|||
return -1
|
||||
}
|
||||
switch r {
|
||||
case '"', ',', '+', '=', '`', '~', '?', '|', '*', '\\', ':', ';', '<', '>', '{', '}':
|
||||
case '"', '\'', '(', ')', '#', '&', '$', ',', '+', '=', '`', '~', '?', '|', '*', '\\', '/', ':', ';', '<', '>', '{', '}':
|
||||
return -1
|
||||
}
|
||||
return r
|
||||
|
|
|
@ -11,11 +11,17 @@ func TestHandle(t *testing.T) {
|
|||
assert.Equal(t, "admin", Handle("Admin "))
|
||||
})
|
||||
t.Run(" Admin ", func(t *testing.T) {
|
||||
assert.Equal(t, "adminfoo", Handle(" Admin@foo "))
|
||||
assert.Equal(t, "admin", Handle(" Admin@foo "))
|
||||
})
|
||||
t.Run(" Admin ", func(t *testing.T) {
|
||||
assert.Equal(t, "admin foo", Handle(" Admin foo "))
|
||||
})
|
||||
t.Run(" admin ", func(t *testing.T) {
|
||||
assert.Equal(t, "admin", Handle(" admin "))
|
||||
})
|
||||
t.Run("admin/user", func(t *testing.T) {
|
||||
assert.Equal(t, "adminuser", Handle("admin/user"))
|
||||
})
|
||||
}
|
||||
|
||||
func TestUsername(t *testing.T) {
|
||||
|
@ -25,9 +31,15 @@ func TestUsername(t *testing.T) {
|
|||
t.Run(" Admin ", func(t *testing.T) {
|
||||
assert.Equal(t, "admin@foo", Username(" Admin@foo "))
|
||||
})
|
||||
t.Run(" Admin ", func(t *testing.T) {
|
||||
assert.Equal(t, "admin foo", Username(" Admin foo "))
|
||||
})
|
||||
t.Run(" admin ", func(t *testing.T) {
|
||||
assert.Equal(t, "admin", Username(" admin "))
|
||||
})
|
||||
t.Run("admin/user", func(t *testing.T) {
|
||||
assert.Equal(t, "adminuser", Username("admin/user"))
|
||||
})
|
||||
}
|
||||
|
||||
func TestEmail(t *testing.T) {
|
||||
|
|
Loading…
Reference in a new issue