user service: initial implementation (#17668)

* conceptual user service: initial commit

* reflect review comments

* fix i18n issues and some tests

* implement get user methods

* add license

* reflect review comments
Этот коммит содержится в:
Ibrahim Serdar Acikgoz
2021-06-01 14:52:55 +03:00
коммит произвёл GitHub
родитель d320b50abb
Коммит ac3bb2e811
21 изменённых файлов: 777 добавлений и 239 удалений

Просмотреть файл

@@ -230,8 +230,6 @@ type AppIface interface {
InstallPlugin(pluginFile io.ReadSeeker, replace bool) (*model.Manifest, *model.AppError)
// InstallPluginWithSignature verifies and installs plugin.
InstallPluginWithSignature(pluginFile, signature io.ReadSeeker) (*model.Manifest, *model.AppError)
// IsUsernameTaken checks if the username is already used by another user. Return false if the username is invalid.
IsUsernameTaken(name string) bool
// LimitedClientConfigWithComputed gets the configuration in a format suitable for sending to the client.
LimitedClientConfigWithComputed() map[string]string
// LogAuditRec logs an audit record using default LvlAuditCLI.
@@ -326,6 +324,8 @@ type AppIface interface {
// the member's group memberships and the configuration of those groups to the syncable. This method should only
// be invoked on group-synced (aka group-constrained) syncables.
SyncSyncableRoles(syncableID string, syncableType model.GroupSyncableType) *model.AppError
// TODO: migrate this after the user service implementation is completed
GetSanitizeOptions(asAdmin bool) map[string]bool
// TeamMembersMinusGroupMembers returns the set of users on the given team minus the set of users in the given
// groups.
//
@@ -710,7 +710,6 @@ type AppIface interface {
GetSamlCertificateStatus() *model.SamlCertificateStatus
GetSamlMetadata() (string, *model.AppError)
GetSamlMetadataFromIdp(idpMetadataUrl string) (*model.SamlMetadataResponse, *model.AppError)
GetSanitizeOptions(asAdmin bool) map[string]bool
GetScheme(id string) (*model.Scheme, *model.AppError)
GetSchemeByName(name string) (*model.Scheme, *model.AppError)
GetSchemeRolesForTeam(teamID string) (string, string, string, *model.AppError)

Просмотреть файл

@@ -4,13 +4,14 @@
package app
import (
"errors"
"net/http"
"strings"
"github.com/mattermost/mattermost-server/v5/app/request"
"github.com/mattermost/mattermost-server/v5/model"
"github.com/mattermost/mattermost-server/v5/services/users"
"github.com/mattermost/mattermost-server/v5/shared/mfa"
"github.com/mattermost/mattermost-server/v5/utils"
)
type TokenLocation int
@@ -49,7 +50,17 @@ func (a *App) IsPasswordValid(password string) *model.AppError {
return nil
}
return utils.IsPasswordValidWithSettings(password, &a.Config().PasswordSettings)
if err := users.IsPasswordValidWithSettings(password, &a.Config().PasswordSettings); err != nil {
var invErr *users.ErrInvalidPassword
switch {
case errors.As(err, &invErr):
return model.NewAppError("User.IsValid", invErr.Id(), map[string]interface{}{"Min": *a.Config().PasswordSettings.MinimumLength}, "", http.StatusBadRequest)
default:
return model.NewAppError("User.IsValid", "app.valid_password_generic.app_error", nil, err.Error(), http.StatusInternalServerError)
}
}
return nil
}
func (a *App) CheckPasswordAndAllCriteria(user *model.User, password string, mfaToken string) *model.AppError {
@@ -57,14 +68,20 @@ func (a *App) CheckPasswordAndAllCriteria(user *model.User, password string, mfa
return err
}
if err := a.checkUserPassword(user, password); err != nil {
if err := users.CheckUserPassword(user, password); err != nil {
if passErr := a.Srv().Store.User().UpdateFailedPasswordAttempts(user.Id, user.FailedAttempts+1); passErr != nil {
return model.NewAppError("CheckPasswordAndAllCriteria", "app.user.update_failed_pwd_attempts.app_error", nil, passErr.Error(), http.StatusInternalServerError)
}
a.InvalidateCacheForUser(user.Id)
return err
var invErr *users.ErrInvalidPassword
switch {
case errors.As(err, &invErr):
return model.NewAppError("checkUserPassword", "api.user.check_user_password.invalid.app_error", nil, "user_id="+user.Id, http.StatusUnauthorized)
default:
return model.NewAppError("checkUserPassword", "app.valid_password_generic.app_error", nil, err.Error(), http.StatusInternalServerError)
}
}
if err := a.CheckUserMfa(user, mfaToken); err != nil {
@@ -100,14 +117,20 @@ func (a *App) DoubleCheckPassword(user *model.User, password string) *model.AppE
return err
}
if err := a.checkUserPassword(user, password); err != nil {
if err := users.CheckUserPassword(user, password); err != nil {
if passErr := a.Srv().Store.User().UpdateFailedPasswordAttempts(user.Id, user.FailedAttempts+1); passErr != nil {
return model.NewAppError("DoubleCheckPassword", "app.user.update_failed_pwd_attempts.app_error", nil, passErr.Error(), http.StatusInternalServerError)
}
a.InvalidateCacheForUser(user.Id)
return err
var invErr *users.ErrInvalidPassword
switch {
case errors.As(err, &invErr):
return model.NewAppError("DoubleCheckPassword", "api.user.check_user_password.invalid.app_error", nil, "user_id="+user.Id, http.StatusUnauthorized)
default:
return model.NewAppError("DoubleCheckPassword", "app.valid_password_generic.app_error", nil, err.Error(), http.StatusInternalServerError)
}
}
if passErr := a.Srv().Store.User().UpdateFailedPasswordAttempts(user.Id, 0); passErr != nil {
@@ -119,14 +142,6 @@ func (a *App) DoubleCheckPassword(user *model.User, password string) *model.AppE
return nil
}
func (a *App) checkUserPassword(user *model.User, password string) *model.AppError {
if !model.ComparePassword(user.Password, password) {
return model.NewAppError("checkUserPassword", "api.user.check_user_password.invalid.app_error", nil, "user_id="+user.Id, http.StatusUnauthorized)
}
return nil
}
func (a *App) checkLdapUserPasswordAndAllCriteria(c *request.Context, ldapId *string, password string, mfaToken string) (*model.User, *model.AppError) {
if a.Ldap() == nil || ldapId == nil {
err := model.NewAppError("doLdapAuthentication", "api.user.login_ldap.not_available.app_error", nil, "", http.StatusNotImplemented)

Просмотреть файл

@@ -17,6 +17,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/mattermost/mattermost-server/v5/model"
"github.com/mattermost/mattermost-server/v5/services/users"
"github.com/mattermost/mattermost-server/v5/store/storetest/mocks"
)
@@ -1967,9 +1968,9 @@ func TestMarkChannelsAsViewedPanic(t *testing.T) {
"userID": 1,
}
mockChannelStore.On("UpdateLastViewedAt", []string{"channelID"}, "userID", false).Return(times, nil)
th.App.srv.userService = users.New(&mockUserStore, th.App.srv.Config)
mockPreferenceStore := mocks.PreferenceStore{}
mockPreferenceStore.On("Get", mock.AnythingOfType("string"), mock.AnythingOfType("string"), mock.AnythingOfType("string")).Return(&model.Preference{Value: "test"}, nil)
mockStore.On("User").Return(&mockUserStore)
mockStore.On("Channel").Return(&mockChannelStore)
mockStore.On("Preference").Return(&mockPreferenceStore)

Просмотреть файл

@@ -17,6 +17,7 @@ import (
"github.com/mattermost/mattermost-server/v5/app/request"
"github.com/mattermost/mattermost-server/v5/model"
"github.com/mattermost/mattermost-server/v5/services/users"
"github.com/mattermost/mattermost-server/v5/shared/mlog"
"github.com/mattermost/mattermost-server/v5/store"
"github.com/mattermost/mattermost-server/v5/utils"
@@ -481,30 +482,57 @@ func (a *App) importUser(data *UserImportData, dryRun bool) *model.AppError {
}
var savedUser *model.User
var err *model.AppError
var err error
if user.Id == "" {
if savedUser, err = a.createUser(user); err != nil {
return err
if savedUser, err = a.srv.userService.CreateUser(user, users.UserCreateOptions{FromImport: true}); err != nil {
var appErr *model.AppError
var invErr *store.ErrInvalidInput
switch {
case errors.As(err, &appErr):
return appErr
case errors.Is(err, users.AcceptedDomainError):
return model.NewAppError("importUser", "api.user.create_user.accepted_domain.app_error", nil, "", http.StatusBadRequest)
case errors.Is(err, users.UserCountError):
return model.NewAppError("importUser", "app.user.get_total_users_count.app_error", nil, nErr.Error(), http.StatusInternalServerError)
case errors.As(err, &invErr):
switch invErr.Field {
case "email":
return model.NewAppError("importUser", "app.user.save.email_exists.app_error", nil, invErr.Error(), http.StatusBadRequest)
case "username":
return model.NewAppError("importUser", "app.user.save.username_exists.app_error", nil, invErr.Error(), http.StatusBadRequest)
default:
return model.NewAppError("importUser", "app.user.save.existing.app_error", nil, invErr.Error(), http.StatusBadRequest)
}
default:
return model.NewAppError("importUser", "app.user.save.app_error", nil, nErr.Error(), http.StatusInternalServerError)
}
}
pref := model.Preference{UserId: savedUser.Id, Category: model.PREFERENCE_CATEGORY_TUTORIAL_STEPS, Name: savedUser.Id, Value: "0"}
if err := a.Srv().Store.Preference().Save(&model.Preferences{pref}); err != nil {
mlog.Warn("Encountered error saving tutorial preference", mlog.Err(err))
}
} else {
var appErr *model.AppError
if hasUserChanged {
if savedUser, err = a.UpdateUser(user, false); err != nil {
return err
if savedUser, appErr = a.UpdateUser(user, false); appErr != nil {
return appErr
}
}
if hasUserRolesChanged {
if savedUser, err = a.UpdateUserRoles(user.Id, roles, false); err != nil {
return err
if savedUser, appErr = a.UpdateUserRoles(user.Id, roles, false); appErr != nil {
return appErr
}
}
if hasNotifyPropsChanged {
if savedUser, err = a.UpdateUserNotifyProps(user.Id, user.NotifyProps, false); err != nil {
return err
if savedUser, appErr = a.UpdateUserNotifyProps(user.Id, user.NotifyProps, false); appErr != nil {
return appErr
}
}
if password != "" {
if err = a.UpdatePassword(user, password); err != nil {
return err
if appErr = a.UpdatePassword(user, password); appErr != nil {
return appErr
}
} else {
if hasUserAuthDataChanged {

Просмотреть файл

@@ -10813,23 +10813,6 @@ func (a *OpenTracingAppLayer) IsUserSignUpAllowed() *model.AppError {
return resultVar0
}
func (a *OpenTracingAppLayer) IsUsernameTaken(name string) bool {
origCtx := a.ctx
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.IsUsernameTaken")
a.ctx = newCtx
a.app.Srv().Store.SetContext(newCtx)
defer func() {
a.app.Srv().Store.SetContext(origCtx)
a.ctx = origCtx
}()
defer span.Finish()
resultVar0 := a.app.IsUsernameTaken(name)
return resultVar0
}
func (a *OpenTracingAppLayer) JoinChannel(c *request.Context, channel *model.Channel, userID string) *model.AppError {
origCtx := a.ctx
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.JoinChannel")

Просмотреть файл

@@ -57,6 +57,7 @@ import (
"github.com/mattermost/mattermost-server/v5/services/timezones"
"github.com/mattermost/mattermost-server/v5/services/tracing"
"github.com/mattermost/mattermost-server/v5/services/upgrader"
"github.com/mattermost/mattermost-server/v5/services/users"
"github.com/mattermost/mattermost-server/v5/shared/filestore"
"github.com/mattermost/mattermost-server/v5/shared/i18n"
"github.com/mattermost/mattermost-server/v5/shared/mail"
@@ -158,6 +159,7 @@ type Server struct {
limitedClientConfig atomic.Value
telemetryService *telemetry.TelemetryService
userService *users.UserService
serviceMux sync.RWMutex
remoteClusterService remotecluster.RemoteClusterServiceIFace
@@ -407,6 +409,8 @@ func NewServer(options ...Option) (*Server, error) {
return nil, errors.Wrap(err, "cannot create store")
}
s.userService = users.New(s.Store.User(), s.Config)
s.configListenerId = s.AddConfigListener(func(_, _ *model.Config) {
s.configOrLicenseListener()

Просмотреть файл

@@ -33,6 +33,7 @@ import (
"github.com/mattermost/mattermost-server/v5/einterfaces"
"github.com/mattermost/mattermost-server/v5/model"
"github.com/mattermost/mattermost-server/v5/plugin"
"github.com/mattermost/mattermost-server/v5/services/users"
"github.com/mattermost/mattermost-server/v5/shared/i18n"
"github.com/mattermost/mattermost-server/v5/shared/mfa"
"github.com/mattermost/mattermost-server/v5/shared/mlog"
@@ -244,37 +245,58 @@ func (a *App) CreateGuest(c *request.Context, user *model.User) (*model.User, *m
}
func (a *App) createUserOrGuest(c *request.Context, user *model.User, guest bool) (*model.User, *model.AppError) {
user.Roles = model.SYSTEM_USER_ROLE_ID
if guest {
user.Roles = model.SYSTEM_GUEST_ROLE_ID
ruser, nErr := a.srv.userService.CreateUser(user, users.UserCreateOptions{Guest: guest})
if nErr != nil {
var appErr *model.AppError
var invErr *store.ErrInvalidInput
var nfErr *users.ErrInvalidPassword
switch {
case errors.As(nErr, &appErr):
return nil, appErr
case errors.Is(nErr, users.AcceptedDomainError):
return nil, model.NewAppError("createUserOrGuest", "api.user.create_user.accepted_domain.app_error", nil, "", http.StatusBadRequest)
case errors.As(nErr, &nfErr):
return nil, model.NewAppError("createUserOrGuest", "api.user.check_user_password.invalid.app_error", nil, "", http.StatusBadRequest)
case errors.Is(nErr, users.UserCountError):
return nil, model.NewAppError("createUserOrGuest", "app.user.get_total_users_count.app_error", nil, nErr.Error(), http.StatusInternalServerError)
case errors.As(nErr, &invErr):
switch invErr.Field {
case "email":
return nil, model.NewAppError("createUserOrGuest", "app.user.save.email_exists.app_error", nil, invErr.Error(), http.StatusBadRequest)
case "username":
return nil, model.NewAppError("createUserOrGuest", "app.user.save.username_exists.app_error", nil, invErr.Error(), http.StatusBadRequest)
default:
return nil, model.NewAppError("createUserOrGuest", "app.user.save.existing.app_error", nil, invErr.Error(), http.StatusBadRequest)
}
default:
return nil, model.NewAppError("createUserOrGuest", "app.user.save.app_error", nil, nErr.Error(), http.StatusInternalServerError)
}
}
if !user.IsLDAPUser() && !user.IsSAMLUser() && !user.IsGuest() && !CheckUserDomain(user, *a.Config().TeamSettings.RestrictCreationToDomains) {
return nil, model.NewAppError("CreateUser", "api.user.create_user.accepted_domain.app_error", nil, "", http.StatusBadRequest)
if user.EmailVerified {
a.InvalidateCacheForUser(ruser.Id)
nUser, err := a.srv.userService.GetUser(ruser.Id)
if err != nil {
var nfErr *store.ErrNotFound
switch {
case errors.As(err, &nfErr):
return nil, model.NewAppError("createUserOrGuest", MissingAccountError, nil, nfErr.Error(), http.StatusNotFound)
default:
return nil, model.NewAppError("createUserOrGuest", "app.user.get.app_error", nil, err.Error(), http.StatusInternalServerError)
}
}
a.sendUpdatedUserEvent(*nUser)
}
if !user.IsLDAPUser() && !user.IsSAMLUser() && user.IsGuest() && !CheckUserDomain(user, *a.Config().GuestAccountsSettings.RestrictCreationToDomains) {
return nil, model.NewAppError("CreateUser", "api.user.create_user.accepted_domain.app_error", nil, "", http.StatusBadRequest)
pref := model.Preference{UserId: ruser.Id, Category: model.PREFERENCE_CATEGORY_TUTORIAL_STEPS, Name: ruser.Id, Value: "0"}
if err := a.Srv().Store.Preference().Save(&model.Preferences{pref}); err != nil {
mlog.Warn("Encountered error saving tutorial preference", mlog.Err(err))
}
// Below is a special case where the first user in the entire
// system is granted the system_admin role
count, err := a.Srv().Store.User().Count(model.UserCountOptions{IncludeDeleted: true})
if err != nil {
return nil, model.NewAppError("createUserOrGuest", "app.user.get_total_users_count.app_error", nil, err.Error(), http.StatusInternalServerError)
}
if count <= 0 {
user.Roles = model.SYSTEM_ADMIN_ROLE_ID + " " + model.SYSTEM_USER_ROLE_ID
}
go a.UpdateViewedProductNoticesForNewUser(ruser.Id)
if _, ok := i18n.GetSupportedLocales()[user.Locale]; !ok {
user.Locale = *a.Config().LocalizationSettings.DefaultClientLocale
}
ruser, appErr := a.createUser(user)
if appErr != nil {
return nil, appErr
}
// This message goes to everyone, so the teamID, channelID and userID are irrelevant
message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_NEW_USER, "", "", "", nil)
message.Add("user_id", ruser.Id)
@@ -293,53 +315,6 @@ func (a *App) createUserOrGuest(c *request.Context, user *model.User, guest bool
return ruser, nil
}
func (a *App) createUser(user *model.User) (*model.User, *model.AppError) {
user.MakeNonNil()
if err := a.IsPasswordValid(user.Password); user.AuthService == "" && err != nil {
return nil, err
}
ruser, nErr := a.Srv().Store.User().Save(user)
if nErr != nil {
var appErr *model.AppError
var invErr *store.ErrInvalidInput
switch {
case errors.As(nErr, &appErr):
return nil, appErr
case errors.As(nErr, &invErr):
switch invErr.Field {
case "email":
return nil, model.NewAppError("createUser", "app.user.save.email_exists.app_error", nil, invErr.Error(), http.StatusBadRequest)
case "username":
return nil, model.NewAppError("createUser", "app.user.save.username_exists.app_error", nil, invErr.Error(), http.StatusBadRequest)
default:
return nil, model.NewAppError("createUser", "app.user.save.existing.app_error", nil, invErr.Error(), http.StatusBadRequest)
}
default:
return nil, model.NewAppError("createUser", "app.user.save.app_error", nil, nErr.Error(), http.StatusInternalServerError)
}
}
if user.EmailVerified {
if err := a.VerifyUserEmail(ruser.Id, user.Email); err != nil {
mlog.Warn("Failed to set email verified", mlog.Err(err))
}
}
pref := model.Preference{UserId: ruser.Id, Category: model.PREFERENCE_CATEGORY_TUTORIAL_STEPS, Name: ruser.Id, Value: "0"}
if err := a.Srv().Store.Preference().Save(&model.Preferences{pref}); err != nil {
mlog.Warn("Encountered error saving tutorial preference", mlog.Err(err))
}
go a.UpdateViewedProductNoticesForNewUser(ruser.Id)
ruser.Sanitize(map[string]bool{})
// Determine whether to send the created user a welcome email
ruser.DisableWelcomeEmail = user.DisableWelcomeEmail
return ruser, nil
}
func (a *App) CreateOAuthUser(c *request.Context, service string, userData io.Reader, teamID string, tokenUser *model.User) (*model.User, *model.AppError) {
if !*a.Config().TeamSettings.EnableUserCreation {
return nil, model.NewAppError("CreateOAuthUser", "api.user.create_user.disabled.app_error", nil, "", http.StatusNotImplemented)
@@ -360,7 +335,7 @@ func (a *App) CreateOAuthUser(c *request.Context, service string, userData io.Re
found := true
count := 0
for found {
if found = a.IsUsernameTaken(user.Username); found {
if found = a.srv.userService.IsUsernameTaken(user.Username); found {
user.Username = user.Username + strconv.Itoa(count)
count++
}
@@ -430,28 +405,15 @@ func CheckUserDomain(user *model.User, domains string) bool {
return CheckEmailDomain(user.Email, domains)
}
// IsUsernameTaken checks if the username is already used by another user. Return false if the username is invalid.
func (a *App) IsUsernameTaken(name string) bool {
if !model.IsValidUsername(name) {
return false
}
if _, err := a.Srv().Store.User().GetByUsername(name); err != nil {
return false
}
return true
}
func (a *App) GetUser(userID string) (*model.User, *model.AppError) {
user, err := a.Srv().Store.User().Get(context.Background(), userID)
user, err := a.srv.userService.GetUser(userID)
if err != nil {
var nfErr *store.ErrNotFound
switch {
case errors.As(err, &nfErr):
return nil, model.NewAppError("GetUser", MissingAccountError, nil, nfErr.Error(), http.StatusNotFound)
default:
return nil, model.NewAppError("GetUser", "app.user.get.app_error", nil, err.Error(), http.StatusInternalServerError)
return nil, model.NewAppError("GetUser", "app.user.get_by_username.app_error", nil, err.Error(), http.StatusInternalServerError)
}
}
@@ -459,7 +421,7 @@ func (a *App) GetUser(userID string) (*model.User, *model.AppError) {
}
func (a *App) GetUserByUsername(username string) (*model.User, *model.AppError) {
result, err := a.Srv().Store.User().GetByUsername(username)
result, err := a.srv.userService.GetUserByUsername(username)
if err != nil {
var nfErr *store.ErrNotFound
switch {
@@ -473,7 +435,7 @@ func (a *App) GetUserByUsername(username string) (*model.User, *model.AppError)
}
func (a *App) GetUserByEmail(email string) (*model.User, *model.AppError) {
user, err := a.Srv().Store.User().GetByEmail(email)
user, err := a.srv.userService.GetUserByEmail(email)
if err != nil {
var nfErr *store.ErrNotFound
switch {
@@ -487,7 +449,7 @@ func (a *App) GetUserByEmail(email string) (*model.User, *model.AppError) {
}
func (a *App) GetUserByAuth(authData *string, authService string) (*model.User, *model.AppError) {
user, err := a.Srv().Store.User().GetByAuth(authData, authService)
user, err := a.srv.userService.GetUserByAuth(authData, authService)
if err != nil {
var invErr *store.ErrInvalidInput
var nfErr *store.ErrNotFound
@@ -505,7 +467,7 @@ func (a *App) GetUserByAuth(authData *string, authService string) (*model.User,
}
func (a *App) GetUsers(options *model.UserGetOptions) ([]*model.User, *model.AppError) {
users, err := a.Srv().Store.User().GetAllProfiles(options)
users, err := a.srv.userService.GetUsers(options)
if err != nil {
return nil, model.NewAppError("GetUsers", "app.user.get_profiles.app_error", nil, err.Error(), http.StatusInternalServerError)
}
@@ -514,20 +476,20 @@ func (a *App) GetUsers(options *model.UserGetOptions) ([]*model.User, *model.App
}
func (a *App) GetUsersPage(options *model.UserGetOptions, asAdmin bool) ([]*model.User, *model.AppError) {
users, err := a.GetUsers(options)
users, err := a.srv.userService.GetUsersPage(options, asAdmin)
if err != nil {
return nil, err
return nil, model.NewAppError("GetUsersPage", "app.user.get_profiles.app_error", nil, err.Error(), http.StatusInternalServerError)
}
return a.sanitizeProfiles(users, asAdmin), nil
return users, nil
}
func (a *App) GetUsersEtag(restrictionsHash string) string {
return fmt.Sprintf("%v.%v.%v.%v", a.Srv().Store.User().GetEtagForAllProfiles(), a.Config().PrivacySettings.ShowFullName, a.Config().PrivacySettings.ShowEmailAddress, restrictionsHash)
return a.srv.userService.GetUsersEtag(restrictionsHash)
}
func (a *App) GetUsersInTeam(options *model.UserGetOptions) ([]*model.User, *model.AppError) {
users, err := a.Srv().Store.User().GetProfiles(options)
users, err := a.srv.userService.GetUsersInTeam(options)
if err != nil {
return nil, model.NewAppError("GetUsersInTeam", "app.user.get_profiles.app_error", nil, err.Error(), http.StatusInternalServerError)
}
@@ -536,7 +498,7 @@ func (a *App) GetUsersInTeam(options *model.UserGetOptions) ([]*model.User, *mod
}
func (a *App) GetUsersNotInTeam(teamID string, groupConstrained bool, offset int, limit int, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, *model.AppError) {
users, err := a.Srv().Store.User().GetProfilesNotInTeam(teamID, groupConstrained, offset, limit, viewRestrictions)
users, err := a.srv.userService.GetUsersNotInTeam(teamID, groupConstrained, offset, limit, viewRestrictions)
if err != nil {
return nil, model.NewAppError("GetUsersNotInTeam", "app.user.get_profiles.app_error", nil, err.Error(), http.StatusInternalServerError)
}
@@ -545,29 +507,29 @@ func (a *App) GetUsersNotInTeam(teamID string, groupConstrained bool, offset int
}
func (a *App) GetUsersInTeamPage(options *model.UserGetOptions, asAdmin bool) ([]*model.User, *model.AppError) {
users, err := a.GetUsersInTeam(options)
users, err := a.srv.userService.GetUsersInTeamPage(options, asAdmin)
if err != nil {
return nil, err
return nil, model.NewAppError("GetUsersInTeamPage", "app.user.get_profiles.app_error", nil, err.Error(), http.StatusInternalServerError)
}
return a.sanitizeProfiles(users, asAdmin), nil
}
func (a *App) GetUsersNotInTeamPage(teamID string, groupConstrained bool, page int, perPage int, asAdmin bool, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, *model.AppError) {
users, err := a.GetUsersNotInTeam(teamID, groupConstrained, page*perPage, perPage, viewRestrictions)
users, err := a.srv.userService.GetUsersNotInTeamPage(teamID, groupConstrained, page*perPage, perPage, asAdmin, viewRestrictions)
if err != nil {
return nil, err
return nil, model.NewAppError("GetUsersNotInTeamPage", "app.user.get_profiles.app_error", nil, err.Error(), http.StatusInternalServerError)
}
return a.sanitizeProfiles(users, asAdmin), nil
}
func (a *App) GetUsersInTeamEtag(teamID string, restrictionsHash string) string {
return fmt.Sprintf("%v.%v.%v.%v", a.Srv().Store.User().GetEtagForProfiles(teamID), a.Config().PrivacySettings.ShowFullName, a.Config().PrivacySettings.ShowEmailAddress, restrictionsHash)
return a.srv.userService.GetUsersInTeamEtag(teamID, restrictionsHash)
}
func (a *App) GetUsersNotInTeamEtag(teamID string, restrictionsHash string) string {
return fmt.Sprintf("%v.%v.%v.%v", a.Srv().Store.User().GetEtagForProfilesNotInTeam(teamID), a.Config().PrivacySettings.ShowFullName, a.Config().PrivacySettings.ShowEmailAddress, restrictionsHash)
return a.srv.userService.GetUsersNotInTeamEtag(teamID, restrictionsHash)
}
func (a *App) GetUsersInChannel(options *model.UserGetOptions) ([]*model.User, *model.AppError) {
@@ -655,16 +617,16 @@ func (a *App) GetUsersNotInChannelPage(teamID string, channelID string, groupCon
}
func (a *App) GetUsersWithoutTeamPage(options *model.UserGetOptions, asAdmin bool) ([]*model.User, *model.AppError) {
users, err := a.GetUsersWithoutTeam(options)
users, err := a.srv.userService.GetUsersWithoutTeamPage(options, asAdmin)
if err != nil {
return nil, err
return nil, model.NewAppError("GetUsersWithoutTeamPage", "app.user.get_profiles.app_error", nil, err.Error(), http.StatusInternalServerError)
}
return a.sanitizeProfiles(users, asAdmin), nil
}
func (a *App) GetUsersWithoutTeam(options *model.UserGetOptions) ([]*model.User, *model.AppError) {
users, err := a.Srv().Store.User().GetProfilesWithoutTeam(options)
users, err := a.srv.userService.GetUsersWithoutTeam(options)
if err != nil {
return nil, model.NewAppError("GetUsersWithoutTeam", "app.user.get_profiles.app_error", nil, err.Error(), http.StatusInternalServerError)
}
@@ -693,14 +655,12 @@ func (a *App) GetChannelGroupUsers(channelID string) ([]*model.User, *model.AppE
}
func (a *App) GetUsersByIds(userIDs []string, options *store.UserGetByIdsOpts) ([]*model.User, *model.AppError) {
allowFromCache := options.ViewRestrictions == nil
users, err := a.Srv().Store.User().GetProfileByIds(context.Background(), userIDs, options, allowFromCache)
users, err := a.srv.userService.GetUsersByIds(userIDs, options)
if err != nil {
return nil, model.NewAppError("GetUsersByIds", "app.user.get_profiles.app_error", nil, err.Error(), http.StatusInternalServerError)
}
return a.sanitizeProfiles(users, options.IsAdmin), nil
return users, nil
}
func (a *App) GetUsersByGroupChannelIds(c *request.Context, channelIDs []string, asAdmin bool) (map[string][]*model.User, *model.AppError) {
@@ -1125,6 +1085,7 @@ func (a *App) DeactivateGuests(c *request.Context) *model.AppError {
return nil
}
// TODO: migrate this after the user service implementation is completed
func (a *App) GetSanitizeOptions(asAdmin bool) map[string]bool {
options := a.Config().GetSanitizeOptions()
if asAdmin {

Просмотреть файл

@@ -27,27 +27,6 @@ import (
"github.com/mattermost/mattermost-server/v5/utils/testutils"
)
func TestIsUsernameTaken(t *testing.T) {
th := Setup(t).InitBasic()
defer th.TearDown()
user := th.BasicUser
taken := th.App.IsUsernameTaken(user.Username)
if !taken {
t.Logf("the username '%v' should be taken", user.Username)
t.FailNow()
}
newUsername := "randomUsername"
taken = th.App.IsUsernameTaken(newUsername)
if taken {
t.Logf("the username '%v' should not be taken", newUsername)
t.FailNow()
}
}
func TestCheckUserDomain(t *testing.T) {
th := Setup(t).InitBasic()
defer th.TearDown()