MM-32133 shared channel username collisions (#17347)
Support for handling username collisions between remote clusters. Users belonging to remote clusters have their username changed to include the remote name e.g. wiggin becomes wiggin:mattermost. @mentions are also modified so the munged username is replaced with the original username when the post is sync'd with the remote the user belongs to. When adding remote users: - append the remote name to the username with colon separator - append the remote name to the email address with colon separator - store the original username and email address in user props - when resolving @mentions replace with the stored original username
Этот коммит содержится в:
@@ -272,8 +272,14 @@ func (u *User) IsValid() *AppError {
|
||||
return InvalidUserError("update_at", u.Id)
|
||||
}
|
||||
|
||||
if !IsValidUsername(u.Username) {
|
||||
return InvalidUserError("username", u.Id)
|
||||
if u.IsRemote() {
|
||||
if !IsValidUsernameAllowRemote(u.Username) {
|
||||
return InvalidUserError("username", u.Id)
|
||||
}
|
||||
} else {
|
||||
if !IsValidUsername(u.Username) {
|
||||
return InvalidUserError("username", u.Id)
|
||||
}
|
||||
}
|
||||
|
||||
if len(u.Email) > USER_EMAIL_MAX_LENGTH || u.Email == "" || !IsValidEmail(u.Email) {
|
||||
@@ -746,6 +752,21 @@ func (u *User) IsRemote() bool {
|
||||
return u.RemoteId != nil && *u.RemoteId != ""
|
||||
}
|
||||
|
||||
// GetProp fetches a prop value by name.
|
||||
func (u *User) GetProp(name string) (string, bool) {
|
||||
val, ok := u.Props[name]
|
||||
return val, ok
|
||||
}
|
||||
|
||||
// SetProp sets a prop value by name, creating the map if nil.
|
||||
// Not thread safe.
|
||||
func (u *User) SetProp(name string, value string) {
|
||||
if u.Props == nil {
|
||||
u.Props = make(map[string]string)
|
||||
}
|
||||
u.Props[name] = value
|
||||
}
|
||||
|
||||
func (u *User) ToPatch() *UserPatch {
|
||||
return &UserPatch{
|
||||
Username: &u.Username, Password: &u.Password,
|
||||
@@ -836,12 +857,13 @@ func ComparePassword(hash string, password string) bool {
|
||||
}
|
||||
|
||||
var validUsernameChars = regexp.MustCompile(`^[a-z0-9\.\-_]+$`)
|
||||
var validUsernameCharsForRemote = regexp.MustCompile(`^[a-z0-9\.\-_:]+$`)
|
||||
|
||||
var restrictedUsernames = []string{
|
||||
"all",
|
||||
"channel",
|
||||
"matterbot",
|
||||
"system",
|
||||
var restrictedUsernames = map[string]struct{}{
|
||||
"all": {},
|
||||
"channel": {},
|
||||
"matterbot": {},
|
||||
"system": {},
|
||||
}
|
||||
|
||||
func IsValidUsername(s string) bool {
|
||||
@@ -853,13 +875,21 @@ func IsValidUsername(s string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, restrictedUsername := range restrictedUsernames {
|
||||
if s == restrictedUsername {
|
||||
return false
|
||||
}
|
||||
_, found := restrictedUsernames[s]
|
||||
return !found
|
||||
}
|
||||
|
||||
func IsValidUsernameAllowRemote(s string) bool {
|
||||
if len(s) < USER_NAME_MIN_LENGTH || len(s) > USER_NAME_MAX_LENGTH {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
if !validUsernameCharsForRemote.MatchString(s) {
|
||||
return false
|
||||
}
|
||||
|
||||
_, found := restrictedUsernames[s]
|
||||
return !found
|
||||
}
|
||||
|
||||
func CleanUsername(username string) string {
|
||||
|
||||
Ссылка в новой задаче
Block a user