mirror of
https://github.com/mattermost/mattermost.git
synced 2025-02-25 18:55:24 -06:00
Sanitize RemoteEmail user prop (#27170)
* Sanitize RemoteEmail user prop If the server is configured to hide user emails, the "RemoteEmail" user property will be sanitized as well, effectively hiding the real email of remote users. * fix merge conflict --------- Co-authored-by: Doug Lauder <wiggin77@warpmail.net> Co-authored-by: Mattermost Build <build@mattermost.com>
This commit is contained in:
parent
59998b0b84
commit
2aff84a72e
@ -30,8 +30,6 @@ const (
|
|||||||
NotifyMinimumDelay = time.Second * 2
|
NotifyMinimumDelay = time.Second * 2
|
||||||
MaxUpsertRetries = 25
|
MaxUpsertRetries = 25
|
||||||
ProfileImageSyncTimeout = time.Second * 5
|
ProfileImageSyncTimeout = time.Second * 5
|
||||||
KeyRemoteUsername = "RemoteUsername"
|
|
||||||
KeyRemoteEmail = "RemoteEmail"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Mocks can be re-generated with `make sharedchannel-mocks`.
|
// Mocks can be re-generated with `make sharedchannel-mocks`.
|
||||||
|
@ -254,8 +254,8 @@ func (scs *Service) insertSyncUser(rctx request.CTX, user *model.User, _ *model.
|
|||||||
user = sanitizeUserForSync(user)
|
user = sanitizeUserForSync(user)
|
||||||
|
|
||||||
// save the original username and email in props
|
// save the original username and email in props
|
||||||
user.SetProp(KeyRemoteUsername, user.Username)
|
user.SetProp(model.UserPropsKeyRemoteUsername, user.Username)
|
||||||
user.SetProp(KeyRemoteEmail, user.Email)
|
user.SetProp(model.UserPropsKeyRemoteEmail, user.Email)
|
||||||
|
|
||||||
// Apply a suffix to the username until it is unique. Collisions will be quite
|
// Apply a suffix to the username until it is unique. Collisions will be quite
|
||||||
// rare since we are joining a username that is unique at a remote site with a unique
|
// rare since we are joining a username that is unique at a remote site with a unique
|
||||||
@ -300,8 +300,8 @@ func (scs *Service) updateSyncUser(rctx request.CTX, patch *model.UserPatch, use
|
|||||||
// preserve existing real username/email since Patch will over-write them;
|
// preserve existing real username/email since Patch will over-write them;
|
||||||
// the real username/email in props can be updated if they don't contain colons,
|
// the real username/email in props can be updated if they don't contain colons,
|
||||||
// meaning the update is coming from the user's origin server (not munged).
|
// meaning the update is coming from the user's origin server (not munged).
|
||||||
realUsername, _ := user.GetProp(KeyRemoteUsername)
|
realUsername, _ := user.GetProp(model.UserPropsKeyRemoteUsername)
|
||||||
realEmail, _ := user.GetProp(KeyRemoteEmail)
|
realEmail, _ := user.GetProp(model.UserPropsKeyRemoteEmail)
|
||||||
|
|
||||||
if patch.Username != nil && !strings.Contains(*patch.Username, ":") {
|
if patch.Username != nil && !strings.Contains(*patch.Username, ":") {
|
||||||
realUsername = *patch.Username
|
realUsername = *patch.Username
|
||||||
@ -312,8 +312,8 @@ func (scs *Service) updateSyncUser(rctx request.CTX, patch *model.UserPatch, use
|
|||||||
|
|
||||||
user.Patch(patch)
|
user.Patch(patch)
|
||||||
user = sanitizeUserForSync(user)
|
user = sanitizeUserForSync(user)
|
||||||
user.SetProp(KeyRemoteUsername, realUsername)
|
user.SetProp(model.UserPropsKeyRemoteUsername, realUsername)
|
||||||
user.SetProp(KeyRemoteEmail, realEmail)
|
user.SetProp(model.UserPropsKeyRemoteEmail, realEmail)
|
||||||
|
|
||||||
// Apply a suffix to the username until it is unique.
|
// Apply a suffix to the username until it is unique.
|
||||||
for i := 1; i <= MaxUpsertRetries; i++ {
|
for i := 1; i <= MaxUpsertRetries; i++ {
|
||||||
|
@ -18,7 +18,7 @@ func fixMention(post *model.Post, mentionMap model.UserMentionMap, user *model.U
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
realUsername, ok := user.GetProp(KeyRemoteUsername)
|
realUsername, ok := user.GetProp(model.UserPropsKeyRemoteUsername)
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,11 @@ import (
|
|||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
UserPropsKeyRemoteUsername = "RemoteUsername"
|
||||||
|
UserPropsKeyRemoteEmail = "RemoteEmail"
|
||||||
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ErrChannelAlreadyShared = errors.New("channel is already shared")
|
ErrChannelAlreadyShared = errors.New("channel is already shared")
|
||||||
ErrChannelHomedOnRemote = errors.New("channel is homed on a remote cluster")
|
ErrChannelHomedOnRemote = errors.New("channel is homed on a remote cluster")
|
||||||
|
@ -637,6 +637,7 @@ func (u *User) Sanitize(options map[string]bool) {
|
|||||||
|
|
||||||
if len(options) != 0 && !options["email"] {
|
if len(options) != 0 && !options["email"] {
|
||||||
u.Email = ""
|
u.Email = ""
|
||||||
|
delete(u.Props, UserPropsKeyRemoteEmail)
|
||||||
}
|
}
|
||||||
if len(options) != 0 && !options["fullname"] {
|
if len(options) != 0 && !options["fullname"] {
|
||||||
u.FirstName = ""
|
u.FirstName = ""
|
||||||
|
@ -384,3 +384,22 @@ func TestValidateCustomStatus(t *testing.T) {
|
|||||||
assert.True(t, user0.ValidateCustomStatus())
|
assert.True(t, user0.ValidateCustomStatus())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSanitizeProfile(t *testing.T) {
|
||||||
|
t.Run("should correctly sanitize email and remote email", func(t *testing.T) {
|
||||||
|
user := &User{
|
||||||
|
Email: "john@doe.com",
|
||||||
|
Props: StringMap{UserPropsKeyRemoteEmail: "remote@doe.com"},
|
||||||
|
}
|
||||||
|
|
||||||
|
user.SanitizeProfile(nil)
|
||||||
|
|
||||||
|
require.Equal(t, "john@doe.com", user.Email)
|
||||||
|
require.Equal(t, "remote@doe.com", user.Props[UserPropsKeyRemoteEmail])
|
||||||
|
|
||||||
|
user.SanitizeProfile(map[string]bool{"email": false})
|
||||||
|
|
||||||
|
require.Empty(t, user.Email)
|
||||||
|
require.Empty(t, user.Props[UserPropsKeyRemoteEmail])
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user