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
Этот коммит содержится в:
@@ -11,16 +11,24 @@ import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
RemoteOfflineAfterMillis = 1000 * 60 * 5 // 5 minutes
|
||||
RemoteNameMinLength = 1
|
||||
RemoteNameMaxLength = 64
|
||||
)
|
||||
|
||||
var (
|
||||
validRemoteNameChars = regexp.MustCompile(`^[a-zA-Z0-9\.\-\_]+$`)
|
||||
)
|
||||
|
||||
type RemoteCluster struct {
|
||||
RemoteId string `json:"remote_id"`
|
||||
RemoteTeamId string `json:"remote_team_id"`
|
||||
Name string `json:"name"`
|
||||
DisplayName string `json:"display_name"`
|
||||
SiteURL string `json:"site_url"`
|
||||
CreateAt int64 `json:"create_at"`
|
||||
@@ -36,6 +44,14 @@ func (rc *RemoteCluster) PreSave() {
|
||||
rc.RemoteId = NewId()
|
||||
}
|
||||
|
||||
if rc.DisplayName == "" {
|
||||
rc.DisplayName = rc.Name
|
||||
}
|
||||
|
||||
rc.Name = SanitizeUnicode(rc.Name)
|
||||
rc.DisplayName = SanitizeUnicode(rc.DisplayName)
|
||||
rc.Name = NormalizeRemoteName(rc.Name)
|
||||
|
||||
if rc.Token == "" {
|
||||
rc.Token = NewId()
|
||||
}
|
||||
@@ -51,8 +67,8 @@ func (rc *RemoteCluster) IsValid() *AppError {
|
||||
return NewAppError("RemoteCluster.IsValid", "model.cluster.is_valid.id.app_error", nil, "id="+rc.RemoteId, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if rc.DisplayName == "" {
|
||||
return NewAppError("RemoteCluster.IsValid", "model.cluster.is_valid.name.app_error", nil, "display_name empty", http.StatusBadRequest)
|
||||
if !IsValidRemoteName(rc.Name) {
|
||||
return NewAppError("RemoteCluster.IsValid", "model.cluster.is_valid.name.app_error", nil, "name="+rc.Name, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if rc.CreateAt == 0 {
|
||||
@@ -65,7 +81,21 @@ func (rc *RemoteCluster) IsValid() *AppError {
|
||||
return nil
|
||||
}
|
||||
|
||||
func IsValidRemoteName(s string) bool {
|
||||
if len(s) < RemoteNameMinLength || len(s) > RemoteNameMaxLength {
|
||||
return false
|
||||
}
|
||||
return validRemoteNameChars.MatchString(s)
|
||||
}
|
||||
|
||||
func (rc *RemoteCluster) PreUpdate() {
|
||||
if rc.DisplayName == "" {
|
||||
rc.DisplayName = rc.Name
|
||||
}
|
||||
|
||||
rc.Name = SanitizeUnicode(rc.Name)
|
||||
rc.DisplayName = SanitizeUnicode(rc.DisplayName)
|
||||
rc.Name = NormalizeRemoteName(rc.Name)
|
||||
rc.fixTopics()
|
||||
}
|
||||
|
||||
@@ -105,12 +135,17 @@ func (rc *RemoteCluster) ToJSON() (string, error) {
|
||||
|
||||
func (rc *RemoteCluster) ToRemoteClusterInfo() RemoteClusterInfo {
|
||||
return RemoteClusterInfo{
|
||||
Name: rc.Name,
|
||||
DisplayName: rc.DisplayName,
|
||||
CreateAt: rc.CreateAt,
|
||||
LastPingAt: rc.LastPingAt,
|
||||
}
|
||||
}
|
||||
|
||||
func NormalizeRemoteName(name string) string {
|
||||
return strings.ToLower(name)
|
||||
}
|
||||
|
||||
func RemoteClusterFromJSON(data io.Reader) (*RemoteCluster, *AppError) {
|
||||
var rc RemoteCluster
|
||||
err := json.NewDecoder(data).Decode(&rc)
|
||||
@@ -122,6 +157,7 @@ func RemoteClusterFromJSON(data io.Reader) (*RemoteCluster, *AppError) {
|
||||
|
||||
// RemoteClusterInfo provides a subset of RemoteCluster fields suitable for sending to clients.
|
||||
type RemoteClusterInfo struct {
|
||||
Name string `json:"name"`
|
||||
DisplayName string `json:"display_name"`
|
||||
CreateAt int64 `json:"create_at"`
|
||||
LastPingAt int64 `json:"last_ping_at"`
|
||||
|
||||
Ссылка в новой задаче
Block a user