github.com/mattermost/mattermost-server/v5@v5.39.3/services/users/users.go (about)

     1  // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
     2  // See LICENSE.txt for license information.
     3  
     4  package users
     5  
     6  import (
     7  	"context"
     8  	"encoding/base64"
     9  	"fmt"
    10  
    11  	"github.com/mattermost/mattermost-server/v5/model"
    12  	"github.com/mattermost/mattermost-server/v5/shared/i18n"
    13  	"github.com/mattermost/mattermost-server/v5/shared/mfa"
    14  	"github.com/mattermost/mattermost-server/v5/shared/mlog"
    15  	"github.com/mattermost/mattermost-server/v5/store"
    16  )
    17  
    18  type UserCreateOptions struct {
    19  	Guest      bool
    20  	FromImport bool
    21  }
    22  
    23  // CreateUser creates a user
    24  func (us *UserService) CreateUser(user *model.User, opts UserCreateOptions) (*model.User, error) {
    25  	if opts.FromImport {
    26  		return us.createUser(user)
    27  	}
    28  
    29  	user.Roles = model.SYSTEM_USER_ROLE_ID
    30  	if opts.Guest {
    31  		user.Roles = model.SYSTEM_GUEST_ROLE_ID
    32  	}
    33  
    34  	if !user.IsLDAPUser() && !user.IsSAMLUser() && !user.IsGuest() && !CheckUserDomain(user, *us.config().TeamSettings.RestrictCreationToDomains) {
    35  		return nil, AcceptedDomainError
    36  	}
    37  
    38  	if !user.IsLDAPUser() && !user.IsSAMLUser() && user.IsGuest() && !CheckUserDomain(user, *us.config().GuestAccountsSettings.RestrictCreationToDomains) {
    39  		return nil, AcceptedDomainError
    40  	}
    41  
    42  	// Below is a special case where the first user in the entire
    43  	// system is granted the system_admin role
    44  	count, err := us.store.Count(model.UserCountOptions{IncludeDeleted: true})
    45  	if err != nil {
    46  		return nil, UserCountError
    47  	}
    48  	if count <= 0 {
    49  		user.Roles = model.SYSTEM_ADMIN_ROLE_ID + " " + model.SYSTEM_USER_ROLE_ID
    50  	}
    51  
    52  	if _, ok := i18n.GetSupportedLocales()[user.Locale]; !ok {
    53  		user.Locale = *us.config().LocalizationSettings.DefaultClientLocale
    54  	}
    55  
    56  	return us.createUser(user)
    57  }
    58  
    59  func (us *UserService) createUser(user *model.User) (*model.User, error) {
    60  	user.MakeNonNil()
    61  
    62  	if err := us.isPasswordValid(user.Password); user.AuthService == "" && err != nil {
    63  		return nil, err
    64  	}
    65  
    66  	ruser, err := us.store.Save(user)
    67  	if err != nil {
    68  		return nil, err
    69  	}
    70  
    71  	if user.EmailVerified {
    72  		if err := us.verifyUserEmail(ruser.Id, user.Email); err != nil {
    73  			mlog.Warn("Failed to set email verified", mlog.Err(err))
    74  		}
    75  	}
    76  
    77  	// Determine whether to send the created user a welcome email
    78  	ruser.DisableWelcomeEmail = user.DisableWelcomeEmail
    79  	ruser.Sanitize(map[string]bool{})
    80  
    81  	return ruser, nil
    82  }
    83  
    84  func (us *UserService) verifyUserEmail(userID, email string) error {
    85  	if _, err := us.store.VerifyEmail(userID, email); err != nil {
    86  		return VerifyUserError
    87  	}
    88  
    89  	return nil
    90  }
    91  
    92  func (us *UserService) GetUser(userID string) (*model.User, error) {
    93  	return us.store.Get(context.Background(), userID)
    94  }
    95  
    96  func (us *UserService) GetUserByUsername(username string) (*model.User, error) {
    97  	return us.store.GetByUsername(username)
    98  }
    99  
   100  func (us *UserService) GetUserByEmail(email string) (*model.User, error) {
   101  	return us.store.GetByEmail(email)
   102  }
   103  
   104  func (us *UserService) GetUserByAuth(authData *string, authService string) (*model.User, error) {
   105  	return us.store.GetByAuth(authData, authService)
   106  }
   107  
   108  func (us *UserService) GetUsers(options *model.UserGetOptions) ([]*model.User, error) {
   109  	return us.store.GetAllProfiles(options)
   110  }
   111  
   112  func (us *UserService) GetUsersByUsernames(usernames []string, options *model.UserGetOptions) ([]*model.User, error) {
   113  	return us.store.GetProfilesByUsernames(usernames, options.ViewRestrictions)
   114  }
   115  
   116  func (us *UserService) GetUsersPage(options *model.UserGetOptions, asAdmin bool) ([]*model.User, error) {
   117  	users, err := us.GetUsers(options)
   118  	if err != nil {
   119  		return nil, err
   120  	}
   121  
   122  	return us.sanitizeProfiles(users, asAdmin), nil
   123  }
   124  
   125  func (us *UserService) GetUsersEtag(restrictionsHash string) string {
   126  	return fmt.Sprintf("%v.%v.%v.%v", us.store.GetEtagForAllProfiles(), us.config().PrivacySettings.ShowFullName, us.config().PrivacySettings.ShowEmailAddress, restrictionsHash)
   127  }
   128  
   129  func (us *UserService) GetUsersByIds(userIDs []string, options *store.UserGetByIdsOpts) ([]*model.User, error) {
   130  	allowFromCache := options.ViewRestrictions == nil
   131  
   132  	users, err := us.store.GetProfileByIds(context.Background(), userIDs, options, allowFromCache)
   133  	if err != nil {
   134  		return nil, err
   135  	}
   136  
   137  	return us.sanitizeProfiles(users, options.IsAdmin), nil
   138  }
   139  
   140  func (us *UserService) GetUsersInTeam(options *model.UserGetOptions) ([]*model.User, error) {
   141  	return us.store.GetProfiles(options)
   142  }
   143  
   144  func (us *UserService) GetUsersNotInTeam(teamID string, groupConstrained bool, offset int, limit int, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, error) {
   145  	return us.store.GetProfilesNotInTeam(teamID, groupConstrained, offset, limit, viewRestrictions)
   146  }
   147  
   148  func (us *UserService) GetUsersInTeamPage(options *model.UserGetOptions, asAdmin bool) ([]*model.User, error) {
   149  	users, err := us.GetUsersInTeam(options)
   150  	if err != nil {
   151  		return nil, err
   152  	}
   153  
   154  	return us.sanitizeProfiles(users, asAdmin), nil
   155  }
   156  
   157  func (us *UserService) GetUsersNotInTeamPage(teamID string, groupConstrained bool, page int, perPage int, asAdmin bool, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, error) {
   158  	users, err := us.GetUsersNotInTeam(teamID, groupConstrained, page*perPage, perPage, viewRestrictions)
   159  	if err != nil {
   160  		return nil, err
   161  	}
   162  
   163  	return us.sanitizeProfiles(users, asAdmin), nil
   164  }
   165  
   166  func (us *UserService) GetUsersInTeamEtag(teamID string, restrictionsHash string) string {
   167  	return fmt.Sprintf("%v.%v.%v.%v", us.store.GetEtagForProfiles(teamID), us.config().PrivacySettings.ShowFullName, us.config().PrivacySettings.ShowEmailAddress, restrictionsHash)
   168  }
   169  
   170  func (us *UserService) GetUsersNotInTeamEtag(teamID string, restrictionsHash string) string {
   171  	return fmt.Sprintf("%v.%v.%v.%v", us.store.GetEtagForProfilesNotInTeam(teamID), us.config().PrivacySettings.ShowFullName, us.config().PrivacySettings.ShowEmailAddress, restrictionsHash)
   172  }
   173  
   174  func (us *UserService) GetUsersWithoutTeamPage(options *model.UserGetOptions, asAdmin bool) ([]*model.User, error) {
   175  	users, err := us.GetUsersWithoutTeam(options)
   176  	if err != nil {
   177  		return nil, err
   178  	}
   179  
   180  	return us.sanitizeProfiles(users, asAdmin), nil
   181  }
   182  
   183  func (us *UserService) GetUsersWithoutTeam(options *model.UserGetOptions) ([]*model.User, error) {
   184  	users, err := us.store.GetProfilesWithoutTeam(options)
   185  	if err != nil {
   186  		return nil, err
   187  	}
   188  
   189  	return users, nil
   190  }
   191  
   192  func (us *UserService) UpdateUser(user *model.User, allowRoleUpdate bool) (*model.UserUpdate, error) {
   193  	return us.store.Update(user, allowRoleUpdate)
   194  }
   195  
   196  func (us *UserService) DeactivateAllGuests() ([]string, error) {
   197  	users, err := us.store.DeactivateGuests()
   198  	if err != nil {
   199  		return nil, err
   200  	}
   201  
   202  	for _, userID := range users {
   203  		if err := us.RevokeAllSessions(userID); err != nil {
   204  			return nil, err
   205  		}
   206  	}
   207  
   208  	return users, nil
   209  }
   210  
   211  func (us *UserService) InvalidateCacheForUser(userID string) {
   212  	us.store.InvalidateProfilesInChannelCacheByUser(userID)
   213  	us.store.InvalidateProfileCacheForUser(userID)
   214  
   215  	if us.cluster != nil {
   216  		msg := &model.ClusterMessage{
   217  			Event:    model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_USER,
   218  			SendType: model.CLUSTER_SEND_BEST_EFFORT,
   219  			Data:     userID,
   220  		}
   221  		us.cluster.SendClusterMessage(msg)
   222  	}
   223  }
   224  
   225  func (us *UserService) GenerateMfaSecret(user *model.User) (*model.MfaSecret, error) {
   226  	secret, img, err := mfa.New(us.store).GenerateSecret(*us.config().ServiceSettings.SiteURL, user.Email, user.Id)
   227  	if err != nil {
   228  		return nil, err
   229  	}
   230  
   231  	// Make sure the old secret is not cached on any cluster nodes.
   232  	us.InvalidateCacheForUser(user.Id)
   233  
   234  	mfaSecret := &model.MfaSecret{Secret: secret, QRCode: base64.StdEncoding.EncodeToString(img)}
   235  	return mfaSecret, nil
   236  }
   237  
   238  func (us *UserService) ActivateMfa(user *model.User, token string) error {
   239  	return mfa.New(us.store).Activate(user.MfaSecret, user.Id, token)
   240  }
   241  
   242  func (us *UserService) DeactivateMfa(user *model.User) error {
   243  	return mfa.New(us.store).Deactivate(user.Id)
   244  }