github.com/masterhung0112/hk_server/v5@v5.0.0-20220302090640-ec71aef15e1c/api4/user.go (about)

     1  // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
     2  // See LICENSE.txt for license information.
     3  
     4  package api4
     5  
     6  import (
     7  	"encoding/json"
     8  	"fmt"
     9  	"io"
    10  	"io/ioutil"
    11  	"net/http"
    12  	"strconv"
    13  	"strings"
    14  	"time"
    15  
    16  	"github.com/masterhung0112/hk_server/v5/app"
    17  	"github.com/masterhung0112/hk_server/v5/audit"
    18  	"github.com/masterhung0112/hk_server/v5/model"
    19  	"github.com/masterhung0112/hk_server/v5/shared/mlog"
    20  	"github.com/masterhung0112/hk_server/v5/store"
    21  	"github.com/masterhung0112/hk_server/v5/utils"
    22  )
    23  
    24  func (api *API) InitUser() {
    25  	api.BaseRoutes.Users.Handle("", api.ApiHandler(createUser)).Methods("POST")
    26  	api.BaseRoutes.Users.Handle("", api.ApiSessionRequired(getUsers)).Methods("GET")
    27  	api.BaseRoutes.Users.Handle("/ids", api.ApiSessionRequired(getUsersByIds)).Methods("POST")
    28  	api.BaseRoutes.Users.Handle("/usernames", api.ApiSessionRequired(getUsersByNames)).Methods("POST")
    29  	api.BaseRoutes.Users.Handle("/known", api.ApiSessionRequired(getKnownUsers)).Methods("GET")
    30  	api.BaseRoutes.Users.Handle("/search", api.ApiSessionRequiredDisableWhenBusy(searchUsers)).Methods("POST")
    31  	api.BaseRoutes.Users.Handle("/autocomplete", api.ApiSessionRequired(autocompleteUsers)).Methods("GET")
    32  	api.BaseRoutes.Users.Handle("/stats", api.ApiSessionRequired(getTotalUsersStats)).Methods("GET")
    33  	api.BaseRoutes.Users.Handle("/stats/filtered", api.ApiSessionRequired(getFilteredUsersStats)).Methods("GET")
    34  	api.BaseRoutes.Users.Handle("/group_channels", api.ApiSessionRequired(getUsersByGroupChannelIds)).Methods("POST")
    35  
    36  	api.BaseRoutes.User.Handle("", api.ApiSessionRequired(getUser)).Methods("GET")
    37  	api.BaseRoutes.User.Handle("/image/default", api.ApiSessionRequiredTrustRequester(getDefaultProfileImage)).Methods("GET")
    38  	api.BaseRoutes.User.Handle("/image", api.ApiSessionRequiredTrustRequester(getProfileImage)).Methods("GET")
    39  	api.BaseRoutes.User.Handle("/image", api.ApiSessionRequired(setProfileImage)).Methods("POST")
    40  	api.BaseRoutes.User.Handle("/image", api.ApiSessionRequired(setDefaultProfileImage)).Methods("DELETE")
    41  	api.BaseRoutes.User.Handle("", api.ApiSessionRequired(updateUser)).Methods("PUT")
    42  	api.BaseRoutes.User.Handle("/patch", api.ApiSessionRequired(patchUser)).Methods("PUT")
    43  	api.BaseRoutes.User.Handle("", api.ApiSessionRequired(deleteUser)).Methods("DELETE")
    44  	api.BaseRoutes.User.Handle("/roles", api.ApiSessionRequired(updateUserRoles)).Methods("PUT")
    45  	api.BaseRoutes.User.Handle("/active", api.ApiSessionRequired(updateUserActive)).Methods("PUT")
    46  	api.BaseRoutes.User.Handle("/password", api.ApiSessionRequired(updatePassword)).Methods("PUT")
    47  	api.BaseRoutes.User.Handle("/promote", api.ApiSessionRequired(promoteGuestToUser)).Methods("POST")
    48  	api.BaseRoutes.User.Handle("/demote", api.ApiSessionRequired(demoteUserToGuest)).Methods("POST")
    49  	api.BaseRoutes.User.Handle("/convert_to_bot", api.ApiSessionRequired(convertUserToBot)).Methods("POST")
    50  	api.BaseRoutes.Users.Handle("/password/reset", api.ApiHandler(resetPassword)).Methods("POST")
    51  	api.BaseRoutes.Users.Handle("/password/reset/send", api.ApiHandler(sendPasswordReset)).Methods("POST")
    52  	api.BaseRoutes.Users.Handle("/email/verify", api.ApiHandler(verifyUserEmail)).Methods("POST")
    53  	api.BaseRoutes.Users.Handle("/email/verify/send", api.ApiHandler(sendVerificationEmail)).Methods("POST")
    54  	api.BaseRoutes.User.Handle("/email/verify/member", api.ApiSessionRequired(verifyUserEmailWithoutToken)).Methods("POST")
    55  	api.BaseRoutes.User.Handle("/terms_of_service", api.ApiSessionRequired(saveUserTermsOfService)).Methods("POST")
    56  	api.BaseRoutes.User.Handle("/terms_of_service", api.ApiSessionRequired(getUserTermsOfService)).Methods("GET")
    57  
    58  	api.BaseRoutes.User.Handle("/auth", api.ApiSessionRequiredTrustRequester(updateUserAuth)).Methods("PUT")
    59  
    60  	api.BaseRoutes.Users.Handle("/mfa", api.ApiHandler(checkUserMfa)).Methods("POST")
    61  	api.BaseRoutes.User.Handle("/mfa", api.ApiSessionRequiredMfa(updateUserMfa)).Methods("PUT")
    62  	api.BaseRoutes.User.Handle("/mfa/generate", api.ApiSessionRequiredMfa(generateMfaSecret)).Methods("POST")
    63  
    64  	api.BaseRoutes.Users.Handle("/login", api.ApiHandler(login)).Methods("POST")
    65  	api.BaseRoutes.Users.Handle("/login/switch", api.ApiHandler(switchAccountType)).Methods("POST")
    66  	api.BaseRoutes.Users.Handle("/login/cws", api.ApiHandlerTrustRequester(loginCWS)).Methods("POST")
    67  	api.BaseRoutes.Users.Handle("/logout", api.ApiHandler(logout)).Methods("POST")
    68  
    69  	api.BaseRoutes.UserByUsername.Handle("", api.ApiSessionRequired(getUserByUsername)).Methods("GET")
    70  	api.BaseRoutes.UserByEmail.Handle("", api.ApiSessionRequired(getUserByEmail)).Methods("GET")
    71  
    72  	api.BaseRoutes.User.Handle("/sessions", api.ApiSessionRequired(getSessions)).Methods("GET")
    73  	api.BaseRoutes.User.Handle("/sessions/revoke", api.ApiSessionRequired(revokeSession)).Methods("POST")
    74  	api.BaseRoutes.User.Handle("/sessions/revoke/all", api.ApiSessionRequired(revokeAllSessionsForUser)).Methods("POST")
    75  	api.BaseRoutes.Users.Handle("/sessions/revoke/all", api.ApiSessionRequired(revokeAllSessionsAllUsers)).Methods("POST")
    76  	api.BaseRoutes.Users.Handle("/sessions/device", api.ApiSessionRequired(attachDeviceId)).Methods("PUT")
    77  	api.BaseRoutes.User.Handle("/audits", api.ApiSessionRequired(getUserAudits)).Methods("GET")
    78  
    79  	api.BaseRoutes.User.Handle("/tokens", api.ApiSessionRequired(createUserAccessToken)).Methods("POST")
    80  	api.BaseRoutes.User.Handle("/tokens", api.ApiSessionRequired(getUserAccessTokensForUser)).Methods("GET")
    81  	api.BaseRoutes.Users.Handle("/tokens", api.ApiSessionRequired(getUserAccessTokens)).Methods("GET")
    82  	api.BaseRoutes.Users.Handle("/tokens/search", api.ApiSessionRequired(searchUserAccessTokens)).Methods("POST")
    83  	api.BaseRoutes.Users.Handle("/tokens/{token_id:[A-Za-z0-9]+}", api.ApiSessionRequired(getUserAccessToken)).Methods("GET")
    84  	api.BaseRoutes.Users.Handle("/tokens/revoke", api.ApiSessionRequired(revokeUserAccessToken)).Methods("POST")
    85  	api.BaseRoutes.Users.Handle("/tokens/disable", api.ApiSessionRequired(disableUserAccessToken)).Methods("POST")
    86  	api.BaseRoutes.Users.Handle("/tokens/enable", api.ApiSessionRequired(enableUserAccessToken)).Methods("POST")
    87  
    88  	api.BaseRoutes.User.Handle("/typing", api.ApiSessionRequiredDisableWhenBusy(publishUserTyping)).Methods("POST")
    89  
    90  	api.BaseRoutes.Users.Handle("/migrate_auth/ldap", api.ApiSessionRequired(migrateAuthToLDAP)).Methods("POST")
    91  	api.BaseRoutes.Users.Handle("/migrate_auth/saml", api.ApiSessionRequired(migrateAuthToSaml)).Methods("POST")
    92  
    93  	api.BaseRoutes.User.Handle("/uploads", api.ApiSessionRequired(getUploadsForUser)).Methods("GET")
    94  
    95  	api.BaseRoutes.UserThreads.Handle("", api.ApiSessionRequired(getThreadsForUser)).Methods("GET")
    96  	api.BaseRoutes.UserThreads.Handle("/read", api.ApiSessionRequired(updateReadStateAllThreadsByUser)).Methods("PUT")
    97  
    98  	api.BaseRoutes.UserThread.Handle("", api.ApiSessionRequired(getThreadForUser)).Methods("GET")
    99  	api.BaseRoutes.UserThread.Handle("/following", api.ApiSessionRequired(followThreadByUser)).Methods("PUT")
   100  	api.BaseRoutes.UserThread.Handle("/following", api.ApiSessionRequired(unfollowThreadByUser)).Methods("DELETE")
   101  	api.BaseRoutes.UserThread.Handle("/read/{timestamp:[0-9]+}", api.ApiSessionRequired(updateReadStateThreadByUser)).Methods("PUT")
   102  }
   103  
   104  func createUser(c *Context, w http.ResponseWriter, r *http.Request) {
   105  	user := model.UserFromJson(r.Body)
   106  	if user == nil {
   107  		c.SetInvalidParam("user")
   108  		return
   109  	}
   110  
   111  	user.SanitizeInput(c.IsSystemAdmin())
   112  
   113  	tokenId := r.URL.Query().Get("t")
   114  	inviteId := r.URL.Query().Get("iid")
   115  	redirect := r.URL.Query().Get("r")
   116  
   117  	auditRec := c.MakeAuditRecord("createUser", audit.Fail)
   118  	defer c.LogAuditRec(auditRec)
   119  	auditRec.AddMeta("invite_id", inviteId)
   120  	auditRec.AddMeta("user", user)
   121  
   122  	// No permission check required
   123  
   124  	var ruser *model.User
   125  	var err *model.AppError
   126  	if tokenId != "" {
   127  		token, nErr := c.App.Srv().Store.Token().GetByToken(tokenId)
   128  		if nErr != nil {
   129  			var status int
   130  			switch nErr.(type) {
   131  			case *store.ErrNotFound:
   132  				status = http.StatusNotFound
   133  			default:
   134  				status = http.StatusInternalServerError
   135  			}
   136  			c.Err = model.NewAppError("CreateUserWithToken", "api.user.create_user.signup_link_invalid.app_error", nil, nErr.Error(), status)
   137  			return
   138  		}
   139  		auditRec.AddMeta("token_type", token.Type)
   140  
   141  		if token.Type == app.TokenTypeGuestInvitation {
   142  			if c.App.Srv().License() == nil {
   143  				c.Err = model.NewAppError("CreateUserWithToken", "api.user.create_user.guest_accounts.license.app_error", nil, "", http.StatusBadRequest)
   144  				return
   145  			}
   146  			if !*c.App.Config().GuestAccountsSettings.Enable {
   147  				c.Err = model.NewAppError("CreateUserWithToken", "api.user.create_user.guest_accounts.disabled.app_error", nil, "", http.StatusBadRequest)
   148  				return
   149  			}
   150  		}
   151  		ruser, err = c.App.CreateUserWithToken(c.AppContext, user, token)
   152  	} else if inviteId != "" {
   153  		ruser, err = c.App.CreateUserWithInviteId(c.AppContext, user, inviteId, redirect)
   154  	} else if c.IsSystemAdmin() {
   155  		ruser, err = c.App.CreateUserAsAdmin(c.AppContext, user, redirect)
   156  		auditRec.AddMeta("admin", true)
   157  	} else {
   158  		ruser, err = c.App.CreateUserFromSignup(c.AppContext, user, redirect)
   159  	}
   160  
   161  	if err != nil {
   162  		c.Err = err
   163  		return
   164  	}
   165  
   166  	// New user created, check cloud limits and send emails if needed
   167  	// Soft fail on error since user is already created
   168  	if ruser != nil {
   169  		err = c.App.CheckAndSendUserLimitWarningEmails(c.AppContext)
   170  		if err != nil {
   171  			c.LogErrorByCode(err)
   172  		}
   173  	}
   174  
   175  	auditRec.Success()
   176  	auditRec.AddMeta("user", ruser) // overwrite meta
   177  
   178  	w.WriteHeader(http.StatusCreated)
   179  	w.Write([]byte(ruser.ToJson()))
   180  }
   181  
   182  func getUser(c *Context, w http.ResponseWriter, r *http.Request) {
   183  	c.RequireUserId()
   184  	if c.Err != nil {
   185  		return
   186  	}
   187  
   188  	canSee, err := c.App.UserCanSeeOtherUser(c.AppContext.Session().UserId, c.Params.UserId)
   189  	if err != nil {
   190  		c.SetPermissionError(model.PERMISSION_VIEW_MEMBERS)
   191  		return
   192  	}
   193  
   194  	if !canSee {
   195  		c.SetPermissionError(model.PERMISSION_VIEW_MEMBERS)
   196  		return
   197  	}
   198  
   199  	user, err := c.App.GetUser(c.Params.UserId)
   200  	if err != nil {
   201  		c.Err = err
   202  		return
   203  	}
   204  
   205  	if c.IsSystemAdmin() || c.AppContext.Session().UserId == user.Id {
   206  		userTermsOfService, err := c.App.GetUserTermsOfService(user.Id)
   207  		if err != nil && err.StatusCode != http.StatusNotFound {
   208  			c.Err = err
   209  			return
   210  		}
   211  
   212  		if userTermsOfService != nil {
   213  			user.TermsOfServiceId = userTermsOfService.TermsOfServiceId
   214  			user.TermsOfServiceCreateAt = userTermsOfService.CreateAt
   215  		}
   216  	}
   217  
   218  	etag := user.Etag(*c.App.Config().PrivacySettings.ShowFullName, *c.App.Config().PrivacySettings.ShowEmailAddress)
   219  
   220  	if c.HandleEtag(etag, "Get User", w, r) {
   221  		return
   222  	}
   223  
   224  	if c.AppContext.Session().UserId == user.Id {
   225  		user.Sanitize(map[string]bool{})
   226  	} else {
   227  		c.App.SanitizeProfile(user, c.IsSystemAdmin())
   228  	}
   229  	c.App.UpdateLastActivityAtIfNeeded(*c.AppContext.Session())
   230  	w.Header().Set(model.HEADER_ETAG_SERVER, etag)
   231  	w.Write([]byte(user.ToJson()))
   232  }
   233  
   234  func getUserByUsername(c *Context, w http.ResponseWriter, r *http.Request) {
   235  	c.RequireUsername()
   236  	if c.Err != nil {
   237  		return
   238  	}
   239  
   240  	user, err := c.App.GetUserByUsername(c.Params.Username)
   241  	if err != nil {
   242  		restrictions, err2 := c.App.GetViewUsersRestrictions(c.AppContext.Session().UserId)
   243  		if err2 != nil {
   244  			c.Err = err2
   245  			return
   246  		}
   247  		if restrictions != nil {
   248  			c.SetPermissionError(model.PERMISSION_VIEW_MEMBERS)
   249  			return
   250  		}
   251  		c.Err = err
   252  		return
   253  	}
   254  
   255  	canSee, err := c.App.UserCanSeeOtherUser(c.AppContext.Session().UserId, user.Id)
   256  	if err != nil {
   257  		c.Err = err
   258  		return
   259  	}
   260  
   261  	if !canSee {
   262  		c.SetPermissionError(model.PERMISSION_VIEW_MEMBERS)
   263  		return
   264  	}
   265  
   266  	if c.IsSystemAdmin() || c.AppContext.Session().UserId == user.Id {
   267  		userTermsOfService, err := c.App.GetUserTermsOfService(user.Id)
   268  		if err != nil && err.StatusCode != http.StatusNotFound {
   269  			c.Err = err
   270  			return
   271  		}
   272  
   273  		if userTermsOfService != nil {
   274  			user.TermsOfServiceId = userTermsOfService.TermsOfServiceId
   275  			user.TermsOfServiceCreateAt = userTermsOfService.CreateAt
   276  		}
   277  	}
   278  
   279  	etag := user.Etag(*c.App.Config().PrivacySettings.ShowFullName, *c.App.Config().PrivacySettings.ShowEmailAddress)
   280  
   281  	if c.HandleEtag(etag, "Get User", w, r) {
   282  		return
   283  	}
   284  
   285  	if c.AppContext.Session().UserId == user.Id {
   286  		user.Sanitize(map[string]bool{})
   287  	} else {
   288  		c.App.SanitizeProfile(user, c.IsSystemAdmin())
   289  	}
   290  	w.Header().Set(model.HEADER_ETAG_SERVER, etag)
   291  	w.Write([]byte(user.ToJson()))
   292  }
   293  
   294  func getUserByEmail(c *Context, w http.ResponseWriter, r *http.Request) {
   295  	c.SanitizeEmail()
   296  	if c.Err != nil {
   297  		return
   298  	}
   299  
   300  	sanitizeOptions := c.App.GetSanitizeOptions(c.IsSystemAdmin())
   301  	if !sanitizeOptions["email"] {
   302  		c.Err = model.NewAppError("getUserByEmail", "api.user.get_user_by_email.permissions.app_error", nil, "userId="+c.AppContext.Session().UserId, http.StatusForbidden)
   303  		return
   304  	}
   305  
   306  	user, err := c.App.GetUserByEmail(c.Params.Email)
   307  	if err != nil {
   308  		restrictions, err2 := c.App.GetViewUsersRestrictions(c.AppContext.Session().UserId)
   309  		if err2 != nil {
   310  			c.Err = err2
   311  			return
   312  		}
   313  		if restrictions != nil {
   314  			c.SetPermissionError(model.PERMISSION_VIEW_MEMBERS)
   315  			return
   316  		}
   317  		c.Err = err
   318  		return
   319  	}
   320  
   321  	canSee, err := c.App.UserCanSeeOtherUser(c.AppContext.Session().UserId, user.Id)
   322  	if err != nil {
   323  		c.Err = err
   324  		return
   325  	}
   326  
   327  	if !canSee {
   328  		c.SetPermissionError(model.PERMISSION_VIEW_MEMBERS)
   329  		return
   330  	}
   331  
   332  	etag := user.Etag(*c.App.Config().PrivacySettings.ShowFullName, *c.App.Config().PrivacySettings.ShowEmailAddress)
   333  
   334  	if c.HandleEtag(etag, "Get User", w, r) {
   335  		return
   336  	}
   337  
   338  	c.App.SanitizeProfile(user, c.IsSystemAdmin())
   339  	w.Header().Set(model.HEADER_ETAG_SERVER, etag)
   340  	w.Write([]byte(user.ToJson()))
   341  }
   342  
   343  func getDefaultProfileImage(c *Context, w http.ResponseWriter, r *http.Request) {
   344  	c.RequireUserId()
   345  	if c.Err != nil {
   346  		return
   347  	}
   348  
   349  	canSee, err := c.App.UserCanSeeOtherUser(c.AppContext.Session().UserId, c.Params.UserId)
   350  	if err != nil {
   351  		c.Err = err
   352  		return
   353  	}
   354  
   355  	if !canSee {
   356  		c.SetPermissionError(model.PERMISSION_VIEW_MEMBERS)
   357  		return
   358  	}
   359  
   360  	user, err := c.App.GetUser(c.Params.UserId)
   361  	if err != nil {
   362  		c.Err = err
   363  		return
   364  	}
   365  
   366  	img, err := c.App.GetDefaultProfileImage(user)
   367  	if err != nil {
   368  		c.Err = err
   369  		return
   370  	}
   371  
   372  	w.Header().Set("Cache-Control", fmt.Sprintf("max-age=%v, private", 24*60*60)) // 24 hrs
   373  	w.Header().Set("Content-Type", "image/png")
   374  	w.Write(img)
   375  }
   376  
   377  func getProfileImage(c *Context, w http.ResponseWriter, r *http.Request) {
   378  	c.RequireUserId()
   379  	if c.Err != nil {
   380  		return
   381  	}
   382  
   383  	canSee, err := c.App.UserCanSeeOtherUser(c.AppContext.Session().UserId, c.Params.UserId)
   384  	if err != nil {
   385  		c.Err = err
   386  		return
   387  	}
   388  
   389  	if !canSee {
   390  		c.SetPermissionError(model.PERMISSION_VIEW_MEMBERS)
   391  		return
   392  	}
   393  
   394  	user, err := c.App.GetUser(c.Params.UserId)
   395  	if err != nil {
   396  		c.Err = err
   397  		return
   398  	}
   399  
   400  	etag := strconv.FormatInt(user.LastPictureUpdate, 10)
   401  	if c.HandleEtag(etag, "Get Profile Image", w, r) {
   402  		return
   403  	}
   404  
   405  	img, readFailed, err := c.App.GetProfileImage(user)
   406  	if err != nil {
   407  		c.Err = err
   408  		return
   409  	}
   410  
   411  	if readFailed {
   412  		w.Header().Set("Cache-Control", fmt.Sprintf("max-age=%v, private", 5*60)) // 5 mins
   413  	} else {
   414  		w.Header().Set("Cache-Control", fmt.Sprintf("max-age=%v, private", 24*60*60)) // 24 hrs
   415  		w.Header().Set(model.HEADER_ETAG_SERVER, etag)
   416  	}
   417  
   418  	w.Header().Set("Content-Type", "image/png")
   419  	w.Write(img)
   420  }
   421  
   422  func setProfileImage(c *Context, w http.ResponseWriter, r *http.Request) {
   423  	defer io.Copy(ioutil.Discard, r.Body)
   424  
   425  	c.RequireUserId()
   426  	if c.Err != nil {
   427  		return
   428  	}
   429  
   430  	if !c.App.SessionHasPermissionToUser(*c.AppContext.Session(), c.Params.UserId) {
   431  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
   432  		return
   433  	}
   434  
   435  	if *c.App.Config().FileSettings.DriverName == "" {
   436  		c.Err = model.NewAppError("uploadProfileImage", "api.user.upload_profile_user.storage.app_error", nil, "", http.StatusNotImplemented)
   437  		return
   438  	}
   439  
   440  	if r.ContentLength > *c.App.Config().FileSettings.MaxFileSize {
   441  		c.Err = model.NewAppError("uploadProfileImage", "api.user.upload_profile_user.too_large.app_error", nil, "", http.StatusRequestEntityTooLarge)
   442  		return
   443  	}
   444  
   445  	if err := r.ParseMultipartForm(*c.App.Config().FileSettings.MaxFileSize); err != nil {
   446  		c.Err = model.NewAppError("uploadProfileImage", "api.user.upload_profile_user.parse.app_error", nil, err.Error(), http.StatusInternalServerError)
   447  		return
   448  	}
   449  
   450  	m := r.MultipartForm
   451  	imageArray, ok := m.File["image"]
   452  	if !ok {
   453  		c.Err = model.NewAppError("uploadProfileImage", "api.user.upload_profile_user.no_file.app_error", nil, "", http.StatusBadRequest)
   454  		return
   455  	}
   456  
   457  	if len(imageArray) <= 0 {
   458  		c.Err = model.NewAppError("uploadProfileImage", "api.user.upload_profile_user.array.app_error", nil, "", http.StatusBadRequest)
   459  		return
   460  	}
   461  
   462  	auditRec := c.MakeAuditRecord("setProfileImage", audit.Fail)
   463  	defer c.LogAuditRec(auditRec)
   464  	if imageArray[0] != nil {
   465  		auditRec.AddMeta("filename", imageArray[0].Filename)
   466  	}
   467  
   468  	user, err := c.App.GetUser(c.Params.UserId)
   469  	if err != nil {
   470  		c.SetInvalidUrlParam("user_id")
   471  		return
   472  	}
   473  	auditRec.AddMeta("user", user)
   474  
   475  	if (user.IsLDAPUser() || (user.IsSAMLUser() && *c.App.Config().SamlSettings.EnableSyncWithLdap)) &&
   476  		*c.App.Config().LdapSettings.PictureAttribute != "" {
   477  		c.Err = model.NewAppError(
   478  			"uploadProfileImage", "api.user.upload_profile_user.login_provider_attribute_set.app_error",
   479  			nil, "", http.StatusConflict)
   480  		return
   481  	}
   482  
   483  	imageData := imageArray[0]
   484  	if err := c.App.SetProfileImage(c.Params.UserId, imageData); err != nil {
   485  		c.Err = err
   486  		return
   487  	}
   488  
   489  	auditRec.Success()
   490  	c.LogAudit("")
   491  
   492  	ReturnStatusOK(w)
   493  }
   494  
   495  func setDefaultProfileImage(c *Context, w http.ResponseWriter, r *http.Request) {
   496  	c.RequireUserId()
   497  	if c.Err != nil {
   498  		return
   499  	}
   500  
   501  	if !c.App.SessionHasPermissionToUser(*c.AppContext.Session(), c.Params.UserId) {
   502  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
   503  		return
   504  	}
   505  
   506  	if *c.App.Config().FileSettings.DriverName == "" {
   507  		c.Err = model.NewAppError("setDefaultProfileImage", "api.user.upload_profile_user.storage.app_error", nil, "", http.StatusNotImplemented)
   508  		return
   509  	}
   510  
   511  	auditRec := c.MakeAuditRecord("setDefaultProfileImage", audit.Fail)
   512  	defer c.LogAuditRec(auditRec)
   513  
   514  	user, err := c.App.GetUser(c.Params.UserId)
   515  	if err != nil {
   516  		c.Err = err
   517  		return
   518  	}
   519  	auditRec.AddMeta("user", user)
   520  
   521  	if err := c.App.SetDefaultProfileImage(user); err != nil {
   522  		c.Err = err
   523  		return
   524  	}
   525  
   526  	auditRec.Success()
   527  	c.LogAudit("")
   528  
   529  	ReturnStatusOK(w)
   530  }
   531  
   532  func getTotalUsersStats(c *Context, w http.ResponseWriter, r *http.Request) {
   533  	if c.Err != nil {
   534  		return
   535  	}
   536  
   537  	restrictions, err := c.App.GetViewUsersRestrictions(c.AppContext.Session().UserId)
   538  	if err != nil {
   539  		c.Err = err
   540  		return
   541  	}
   542  
   543  	stats, err := c.App.GetTotalUsersStats(restrictions)
   544  	if err != nil {
   545  		c.Err = err
   546  		return
   547  	}
   548  
   549  	w.Write([]byte(stats.ToJson()))
   550  }
   551  
   552  func getFilteredUsersStats(c *Context, w http.ResponseWriter, r *http.Request) {
   553  	teamID := r.URL.Query().Get("in_team")
   554  	channelID := r.URL.Query().Get("in_channel")
   555  	includeDeleted := r.URL.Query().Get("include_deleted")
   556  	includeBotAccounts := r.URL.Query().Get("include_bots")
   557  	rolesString := r.URL.Query().Get("roles")
   558  	channelRolesString := r.URL.Query().Get("channel_roles")
   559  	teamRolesString := r.URL.Query().Get("team_roles")
   560  
   561  	includeDeletedBool, _ := strconv.ParseBool(includeDeleted)
   562  	includeBotAccountsBool, _ := strconv.ParseBool(includeBotAccounts)
   563  
   564  	roles := []string{}
   565  	var rolesValid bool
   566  	if rolesString != "" {
   567  		roles, rolesValid = model.CleanRoleNames(strings.Split(rolesString, ","))
   568  		if !rolesValid {
   569  			c.SetInvalidParam("roles")
   570  			return
   571  		}
   572  	}
   573  	channelRoles := []string{}
   574  	if channelRolesString != "" && channelID != "" {
   575  		channelRoles, rolesValid = model.CleanRoleNames(strings.Split(channelRolesString, ","))
   576  		if !rolesValid {
   577  			c.SetInvalidParam("channelRoles")
   578  			return
   579  		}
   580  	}
   581  	teamRoles := []string{}
   582  	if teamRolesString != "" && teamID != "" {
   583  		teamRoles, rolesValid = model.CleanRoleNames(strings.Split(teamRolesString, ","))
   584  		if !rolesValid {
   585  			c.SetInvalidParam("teamRoles")
   586  			return
   587  		}
   588  	}
   589  
   590  	options := &model.UserCountOptions{
   591  		IncludeDeleted:     includeDeletedBool,
   592  		IncludeBotAccounts: includeBotAccountsBool,
   593  		TeamId:             teamID,
   594  		ChannelId:          channelID,
   595  		Roles:              roles,
   596  		ChannelRoles:       channelRoles,
   597  		TeamRoles:          teamRoles,
   598  	}
   599  
   600  	if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_USERS) {
   601  		c.SetPermissionError(model.PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_USERS)
   602  		return
   603  	}
   604  
   605  	stats, err := c.App.GetFilteredUsersStats(options)
   606  	if err != nil {
   607  		c.Err = err
   608  		return
   609  	}
   610  
   611  	w.Write([]byte(stats.ToJson()))
   612  }
   613  
   614  func getUsersByGroupChannelIds(c *Context, w http.ResponseWriter, r *http.Request) {
   615  	channelIds := model.ArrayFromJson(r.Body)
   616  
   617  	if len(channelIds) == 0 {
   618  		c.SetInvalidParam("channel_ids")
   619  		return
   620  	}
   621  
   622  	usersByChannelId, err := c.App.GetUsersByGroupChannelIds(c.AppContext, channelIds, c.IsSystemAdmin())
   623  	if err != nil {
   624  		c.Err = err
   625  		return
   626  	}
   627  
   628  	b, _ := json.Marshal(usersByChannelId)
   629  	w.Write(b)
   630  }
   631  
   632  func getUsers(c *Context, w http.ResponseWriter, r *http.Request) {
   633  	inTeamId := r.URL.Query().Get("in_team")
   634  	notInTeamId := r.URL.Query().Get("not_in_team")
   635  	inChannelId := r.URL.Query().Get("in_channel")
   636  	inGroupId := r.URL.Query().Get("in_group")
   637  	notInChannelId := r.URL.Query().Get("not_in_channel")
   638  	groupConstrained := r.URL.Query().Get("group_constrained")
   639  	withoutTeam := r.URL.Query().Get("without_team")
   640  	inactive := r.URL.Query().Get("inactive")
   641  	active := r.URL.Query().Get("active")
   642  	role := r.URL.Query().Get("role")
   643  	sort := r.URL.Query().Get("sort")
   644  	rolesString := r.URL.Query().Get("roles")
   645  	channelRolesString := r.URL.Query().Get("channel_roles")
   646  	teamRolesString := r.URL.Query().Get("team_roles")
   647  
   648  	if notInChannelId != "" && inTeamId == "" {
   649  		c.SetInvalidUrlParam("team_id")
   650  		return
   651  	}
   652  
   653  	if sort != "" && sort != "last_activity_at" && sort != "create_at" && sort != "status" {
   654  		c.SetInvalidUrlParam("sort")
   655  		return
   656  	}
   657  
   658  	// Currently only supports sorting on a team
   659  	// or sort="status" on inChannelId
   660  	if (sort == "last_activity_at" || sort == "create_at") && (inTeamId == "" || notInTeamId != "" || inChannelId != "" || notInChannelId != "" || withoutTeam != "" || inGroupId != "") {
   661  		c.SetInvalidUrlParam("sort")
   662  		return
   663  	}
   664  	if sort == "status" && inChannelId == "" {
   665  		c.SetInvalidUrlParam("sort")
   666  		return
   667  	}
   668  
   669  	withoutTeamBool, _ := strconv.ParseBool(withoutTeam)
   670  	groupConstrainedBool, _ := strconv.ParseBool(groupConstrained)
   671  	inactiveBool, _ := strconv.ParseBool(inactive)
   672  	activeBool, _ := strconv.ParseBool(active)
   673  
   674  	if inactiveBool && activeBool {
   675  		c.SetInvalidUrlParam("inactive")
   676  	}
   677  
   678  	roles := []string{}
   679  	var rolesValid bool
   680  	if rolesString != "" {
   681  		roles, rolesValid = model.CleanRoleNames(strings.Split(rolesString, ","))
   682  		if !rolesValid {
   683  			c.SetInvalidParam("roles")
   684  			return
   685  		}
   686  	}
   687  	channelRoles := []string{}
   688  	if channelRolesString != "" && inChannelId != "" {
   689  		channelRoles, rolesValid = model.CleanRoleNames(strings.Split(channelRolesString, ","))
   690  		if !rolesValid {
   691  			c.SetInvalidParam("channelRoles")
   692  			return
   693  		}
   694  	}
   695  	teamRoles := []string{}
   696  	if teamRolesString != "" && inTeamId != "" {
   697  		teamRoles, rolesValid = model.CleanRoleNames(strings.Split(teamRolesString, ","))
   698  		if !rolesValid {
   699  			c.SetInvalidParam("teamRoles")
   700  			return
   701  		}
   702  	}
   703  
   704  	restrictions, err := c.App.GetViewUsersRestrictions(c.AppContext.Session().UserId)
   705  	if err != nil {
   706  		c.Err = err
   707  		return
   708  	}
   709  
   710  	userGetOptions := &model.UserGetOptions{
   711  		InTeamId:         inTeamId,
   712  		InChannelId:      inChannelId,
   713  		NotInTeamId:      notInTeamId,
   714  		NotInChannelId:   notInChannelId,
   715  		InGroupId:        inGroupId,
   716  		GroupConstrained: groupConstrainedBool,
   717  		WithoutTeam:      withoutTeamBool,
   718  		Inactive:         inactiveBool,
   719  		Active:           activeBool,
   720  		Role:             role,
   721  		Roles:            roles,
   722  		ChannelRoles:     channelRoles,
   723  		TeamRoles:        teamRoles,
   724  		Sort:             sort,
   725  		Page:             c.Params.Page,
   726  		PerPage:          c.Params.PerPage,
   727  		ViewRestrictions: restrictions,
   728  	}
   729  
   730  	var profiles []*model.User
   731  	etag := ""
   732  
   733  	if withoutTeamBool, _ := strconv.ParseBool(withoutTeam); withoutTeamBool {
   734  		// Use a special permission for now
   735  		if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PERMISSION_LIST_USERS_WITHOUT_TEAM) {
   736  			c.SetPermissionError(model.PERMISSION_LIST_USERS_WITHOUT_TEAM)
   737  			return
   738  		}
   739  
   740  		profiles, err = c.App.GetUsersWithoutTeamPage(userGetOptions, c.IsSystemAdmin())
   741  	} else if notInChannelId != "" {
   742  		if !c.App.SessionHasPermissionToChannel(*c.AppContext.Session(), notInChannelId, model.PERMISSION_READ_CHANNEL) {
   743  			c.SetPermissionError(model.PERMISSION_READ_CHANNEL)
   744  			return
   745  		}
   746  
   747  		profiles, err = c.App.GetUsersNotInChannelPage(inTeamId, notInChannelId, groupConstrainedBool, c.Params.Page, c.Params.PerPage, c.IsSystemAdmin(), restrictions)
   748  	} else if notInTeamId != "" {
   749  		if !c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), notInTeamId, model.PERMISSION_VIEW_TEAM) {
   750  			c.SetPermissionError(model.PERMISSION_VIEW_TEAM)
   751  			return
   752  		}
   753  
   754  		etag = c.App.GetUsersNotInTeamEtag(inTeamId, restrictions.Hash())
   755  		if c.HandleEtag(etag, "Get Users Not in Team", w, r) {
   756  			return
   757  		}
   758  
   759  		profiles, err = c.App.GetUsersNotInTeamPage(notInTeamId, groupConstrainedBool, c.Params.Page, c.Params.PerPage, c.IsSystemAdmin(), restrictions)
   760  	} else if inTeamId != "" {
   761  		if !c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), inTeamId, model.PERMISSION_VIEW_TEAM) {
   762  			c.SetPermissionError(model.PERMISSION_VIEW_TEAM)
   763  			return
   764  		}
   765  
   766  		if sort == "last_activity_at" {
   767  			profiles, err = c.App.GetRecentlyActiveUsersForTeamPage(inTeamId, c.Params.Page, c.Params.PerPage, c.IsSystemAdmin(), restrictions)
   768  		} else if sort == "create_at" {
   769  			profiles, err = c.App.GetNewUsersForTeamPage(inTeamId, c.Params.Page, c.Params.PerPage, c.IsSystemAdmin(), restrictions)
   770  		} else {
   771  			etag = c.App.GetUsersInTeamEtag(inTeamId, restrictions.Hash())
   772  			if c.HandleEtag(etag, "Get Users in Team", w, r) {
   773  				return
   774  			}
   775  			profiles, err = c.App.GetUsersInTeamPage(userGetOptions, c.IsSystemAdmin())
   776  		}
   777  	} else if inChannelId != "" {
   778  		if !c.App.SessionHasPermissionToChannel(*c.AppContext.Session(), inChannelId, model.PERMISSION_READ_CHANNEL) {
   779  			c.SetPermissionError(model.PERMISSION_READ_CHANNEL)
   780  			return
   781  		}
   782  		if sort == "status" {
   783  			profiles, err = c.App.GetUsersInChannelPageByStatus(userGetOptions, c.IsSystemAdmin())
   784  		} else {
   785  			profiles, err = c.App.GetUsersInChannelPage(userGetOptions, c.IsSystemAdmin())
   786  		}
   787  	} else if inGroupId != "" {
   788  		if c.App.Srv().License() == nil || !*c.App.Srv().License().Features.LDAPGroups {
   789  			c.Err = model.NewAppError("Api4.getUsersInGroup", "api.ldap_groups.license_error", nil, "", http.StatusNotImplemented)
   790  			return
   791  		}
   792  
   793  		if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_GROUPS) {
   794  			c.SetPermissionError(model.PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_GROUPS)
   795  			return
   796  		}
   797  
   798  		profiles, _, err = c.App.GetGroupMemberUsersPage(inGroupId, c.Params.Page, c.Params.PerPage)
   799  		if err != nil {
   800  			c.Err = err
   801  			return
   802  		}
   803  	} else {
   804  		userGetOptions, err = c.App.RestrictUsersGetByPermissions(c.AppContext.Session().UserId, userGetOptions)
   805  		if err != nil {
   806  			c.Err = err
   807  			return
   808  		}
   809  		profiles, err = c.App.GetUsersPage(userGetOptions, c.IsSystemAdmin())
   810  	}
   811  
   812  	if err != nil {
   813  		c.Err = err
   814  		return
   815  	}
   816  
   817  	if etag != "" {
   818  		w.Header().Set(model.HEADER_ETAG_SERVER, etag)
   819  	}
   820  	c.App.UpdateLastActivityAtIfNeeded(*c.AppContext.Session())
   821  	w.Write([]byte(model.UserListToJson(profiles)))
   822  }
   823  
   824  func getUsersByIds(c *Context, w http.ResponseWriter, r *http.Request) {
   825  	userIds := model.ArrayFromJson(r.Body)
   826  
   827  	if len(userIds) == 0 {
   828  		c.SetInvalidParam("user_ids")
   829  		return
   830  	}
   831  
   832  	sinceString := r.URL.Query().Get("since")
   833  
   834  	options := &store.UserGetByIdsOpts{
   835  		IsAdmin: c.IsSystemAdmin(),
   836  	}
   837  
   838  	if sinceString != "" {
   839  		since, parseError := strconv.ParseInt(sinceString, 10, 64)
   840  		if parseError != nil {
   841  			c.SetInvalidParam("since")
   842  			return
   843  		}
   844  		options.Since = since
   845  	}
   846  
   847  	restrictions, err := c.App.GetViewUsersRestrictions(c.AppContext.Session().UserId)
   848  	if err != nil {
   849  		c.Err = err
   850  		return
   851  	}
   852  	options.ViewRestrictions = restrictions
   853  
   854  	users, err := c.App.GetUsersByIds(userIds, options)
   855  	if err != nil {
   856  		c.Err = err
   857  		return
   858  	}
   859  
   860  	w.Write([]byte(model.UserListToJson(users)))
   861  }
   862  
   863  func getUsersByNames(c *Context, w http.ResponseWriter, r *http.Request) {
   864  	usernames := model.ArrayFromJson(r.Body)
   865  
   866  	if len(usernames) == 0 {
   867  		c.SetInvalidParam("usernames")
   868  		return
   869  	}
   870  
   871  	restrictions, err := c.App.GetViewUsersRestrictions(c.AppContext.Session().UserId)
   872  	if err != nil {
   873  		c.Err = err
   874  		return
   875  	}
   876  
   877  	users, err := c.App.GetUsersByUsernames(usernames, c.IsSystemAdmin(), restrictions)
   878  	if err != nil {
   879  		c.Err = err
   880  		return
   881  	}
   882  
   883  	w.Write([]byte(model.UserListToJson(users)))
   884  }
   885  
   886  func getKnownUsers(c *Context, w http.ResponseWriter, r *http.Request) {
   887  	userIds, err := c.App.GetKnownUsers(c.AppContext.Session().UserId)
   888  	if err != nil {
   889  		c.Err = err
   890  		return
   891  	}
   892  
   893  	data, _ := json.Marshal(userIds)
   894  
   895  	w.Write(data)
   896  }
   897  
   898  func searchUsers(c *Context, w http.ResponseWriter, r *http.Request) {
   899  	props := model.UserSearchFromJson(r.Body)
   900  	if props == nil {
   901  		c.SetInvalidParam("")
   902  		return
   903  	}
   904  
   905  	if props.Term == "" {
   906  		c.SetInvalidParam("term")
   907  		return
   908  	}
   909  
   910  	if props.TeamId == "" && props.NotInChannelId != "" {
   911  		c.SetInvalidParam("team_id")
   912  		return
   913  	}
   914  
   915  	if props.InGroupId != "" {
   916  		if c.App.Srv().License() == nil || !*c.App.Srv().License().Features.LDAPGroups {
   917  			c.Err = model.NewAppError("Api4.searchUsers", "api.ldap_groups.license_error", nil, "", http.StatusNotImplemented)
   918  			return
   919  		}
   920  
   921  		if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PERMISSION_MANAGE_SYSTEM) {
   922  			c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
   923  			return
   924  		}
   925  	}
   926  
   927  	if props.InChannelId != "" && !c.App.SessionHasPermissionToChannel(*c.AppContext.Session(), props.InChannelId, model.PERMISSION_READ_CHANNEL) {
   928  		c.SetPermissionError(model.PERMISSION_READ_CHANNEL)
   929  		return
   930  	}
   931  
   932  	if props.NotInChannelId != "" && !c.App.SessionHasPermissionToChannel(*c.AppContext.Session(), props.NotInChannelId, model.PERMISSION_READ_CHANNEL) {
   933  		c.SetPermissionError(model.PERMISSION_READ_CHANNEL)
   934  		return
   935  	}
   936  
   937  	if props.TeamId != "" && !c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), props.TeamId, model.PERMISSION_VIEW_TEAM) {
   938  		c.SetPermissionError(model.PERMISSION_VIEW_TEAM)
   939  		return
   940  	}
   941  
   942  	if props.NotInTeamId != "" && !c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), props.NotInTeamId, model.PERMISSION_VIEW_TEAM) {
   943  		c.SetPermissionError(model.PERMISSION_VIEW_TEAM)
   944  		return
   945  	}
   946  
   947  	if props.Limit <= 0 || props.Limit > model.USER_SEARCH_MAX_LIMIT {
   948  		c.SetInvalidParam("limit")
   949  		return
   950  	}
   951  
   952  	options := &model.UserSearchOptions{
   953  		IsAdmin:          c.IsSystemAdmin(),
   954  		AllowInactive:    props.AllowInactive,
   955  		GroupConstrained: props.GroupConstrained,
   956  		Limit:            props.Limit,
   957  		Role:             props.Role,
   958  		Roles:            props.Roles,
   959  		ChannelRoles:     props.ChannelRoles,
   960  		TeamRoles:        props.TeamRoles,
   961  	}
   962  
   963  	if c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PERMISSION_MANAGE_SYSTEM) {
   964  		options.AllowEmails = true
   965  		options.AllowFullNames = true
   966  	} else {
   967  		options.AllowEmails = *c.App.Config().PrivacySettings.ShowEmailAddress
   968  		options.AllowFullNames = *c.App.Config().PrivacySettings.ShowFullName
   969  	}
   970  
   971  	options, err := c.App.RestrictUsersSearchByPermissions(c.AppContext.Session().UserId, options)
   972  	if err != nil {
   973  		c.Err = err
   974  		return
   975  	}
   976  
   977  	profiles, err := c.App.SearchUsers(props, options)
   978  	if err != nil {
   979  		c.Err = err
   980  		return
   981  	}
   982  
   983  	w.Write([]byte(model.UserListToJson(profiles)))
   984  }
   985  
   986  func autocompleteUsers(c *Context, w http.ResponseWriter, r *http.Request) {
   987  	channelId := r.URL.Query().Get("in_channel")
   988  	teamId := r.URL.Query().Get("in_team")
   989  	name := r.URL.Query().Get("name")
   990  	limitStr := r.URL.Query().Get("limit")
   991  	limit, _ := strconv.Atoi(limitStr)
   992  	if limitStr == "" {
   993  		limit = model.USER_SEARCH_DEFAULT_LIMIT
   994  	} else if limit > model.USER_SEARCH_MAX_LIMIT {
   995  		limit = model.USER_SEARCH_MAX_LIMIT
   996  	}
   997  
   998  	options := &model.UserSearchOptions{
   999  		IsAdmin: c.IsSystemAdmin(),
  1000  		// Never autocomplete on emails.
  1001  		AllowEmails: false,
  1002  		Limit:       limit,
  1003  	}
  1004  
  1005  	if c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PERMISSION_MANAGE_SYSTEM) {
  1006  		options.AllowFullNames = true
  1007  	} else {
  1008  		options.AllowFullNames = *c.App.Config().PrivacySettings.ShowFullName
  1009  	}
  1010  
  1011  	if channelId != "" {
  1012  		if !c.App.SessionHasPermissionToChannel(*c.AppContext.Session(), channelId, model.PERMISSION_READ_CHANNEL) {
  1013  			c.SetPermissionError(model.PERMISSION_READ_CHANNEL)
  1014  			return
  1015  		}
  1016  	}
  1017  
  1018  	if teamId != "" {
  1019  		if !c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), teamId, model.PERMISSION_VIEW_TEAM) {
  1020  			c.SetPermissionError(model.PERMISSION_VIEW_TEAM)
  1021  			return
  1022  		}
  1023  	}
  1024  
  1025  	var autocomplete model.UserAutocomplete
  1026  
  1027  	var err *model.AppError
  1028  	options, err = c.App.RestrictUsersSearchByPermissions(c.AppContext.Session().UserId, options)
  1029  	if err != nil {
  1030  		c.Err = err
  1031  		return
  1032  	}
  1033  
  1034  	if channelId != "" {
  1035  		// We're using the channelId to search for users inside that channel and the team
  1036  		// to get the not in channel list. Also we want to include the DM and GM users for
  1037  		// that team which could only be obtained having the team id.
  1038  		if teamId == "" {
  1039  			c.Err = model.NewAppError("autocompleteUser",
  1040  				"api.user.autocomplete_users.missing_team_id.app_error",
  1041  				nil,
  1042  				"channelId="+channelId,
  1043  				http.StatusInternalServerError,
  1044  			)
  1045  			return
  1046  		}
  1047  		result, err := c.App.AutocompleteUsersInChannel(teamId, channelId, name, options)
  1048  		if err != nil {
  1049  			c.Err = err
  1050  			return
  1051  		}
  1052  
  1053  		autocomplete.Users = result.InChannel
  1054  		autocomplete.OutOfChannel = result.OutOfChannel
  1055  	} else if teamId != "" {
  1056  		result, err := c.App.AutocompleteUsersInTeam(teamId, name, options)
  1057  		if err != nil {
  1058  			c.Err = err
  1059  			return
  1060  		}
  1061  
  1062  		autocomplete.Users = result.InTeam
  1063  	} else {
  1064  		result, err := c.App.SearchUsersInTeam("", name, options)
  1065  		if err != nil {
  1066  			c.Err = err
  1067  			return
  1068  		}
  1069  		autocomplete.Users = result
  1070  	}
  1071  
  1072  	w.Write([]byte((autocomplete.ToJson())))
  1073  }
  1074  
  1075  func updateUser(c *Context, w http.ResponseWriter, r *http.Request) {
  1076  	c.RequireUserId()
  1077  	if c.Err != nil {
  1078  		return
  1079  	}
  1080  
  1081  	user := model.UserFromJson(r.Body)
  1082  	if user == nil {
  1083  		c.SetInvalidParam("user")
  1084  		return
  1085  	}
  1086  
  1087  	// The user being updated in the payload must be the same one as indicated in the URL.
  1088  	if user.Id != c.Params.UserId {
  1089  		c.SetInvalidParam("user_id")
  1090  		return
  1091  	}
  1092  
  1093  	auditRec := c.MakeAuditRecord("updateUser", audit.Fail)
  1094  	defer c.LogAuditRec(auditRec)
  1095  
  1096  	// Cannot update a system admin unless user making request is a systemadmin also.
  1097  	if user.IsSystemAdmin() && !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PERMISSION_MANAGE_SYSTEM) {
  1098  		c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
  1099  		return
  1100  	}
  1101  
  1102  	if !c.App.SessionHasPermissionToUser(*c.AppContext.Session(), user.Id) {
  1103  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
  1104  		return
  1105  	}
  1106  
  1107  	ouser, err := c.App.GetUser(user.Id)
  1108  	if err != nil {
  1109  		c.Err = err
  1110  		return
  1111  	}
  1112  	auditRec.AddMeta("user", ouser)
  1113  
  1114  	if c.AppContext.Session().IsOAuth {
  1115  		if ouser.Email != user.Email {
  1116  			c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
  1117  			c.Err.DetailedError += ", attempted email update by oauth app"
  1118  			return
  1119  		}
  1120  	}
  1121  
  1122  	// Check that the fields being updated are not set by the login provider
  1123  	conflictField := c.App.CheckProviderAttributes(ouser, user.ToPatch())
  1124  	if conflictField != "" {
  1125  		c.Err = model.NewAppError(
  1126  			"updateUser", "api.user.update_user.login_provider_attribute_set.app_error",
  1127  			map[string]interface{}{"Field": conflictField}, "", http.StatusConflict)
  1128  		return
  1129  	}
  1130  
  1131  	// If eMail update is attempted by the currently logged in user, check if correct password was provided
  1132  	if user.Email != "" && ouser.Email != user.Email && c.AppContext.Session().UserId == c.Params.UserId {
  1133  		err = c.App.DoubleCheckPassword(ouser, user.Password)
  1134  		if err != nil {
  1135  			c.SetInvalidParam("password")
  1136  			return
  1137  		}
  1138  	}
  1139  
  1140  	ruser, err := c.App.UpdateUserAsUser(user, c.IsSystemAdmin())
  1141  	if err != nil {
  1142  		c.Err = err
  1143  		return
  1144  	}
  1145  
  1146  	auditRec.Success()
  1147  	auditRec.AddMeta("update", ruser)
  1148  	c.LogAudit("")
  1149  
  1150  	w.Write([]byte(ruser.ToJson()))
  1151  }
  1152  
  1153  func patchUser(c *Context, w http.ResponseWriter, r *http.Request) {
  1154  	c.RequireUserId()
  1155  	if c.Err != nil {
  1156  		return
  1157  	}
  1158  
  1159  	patch := model.UserPatchFromJson(r.Body)
  1160  	if patch == nil {
  1161  		c.SetInvalidParam("user")
  1162  		return
  1163  	}
  1164  
  1165  	auditRec := c.MakeAuditRecord("patchUser", audit.Fail)
  1166  	defer c.LogAuditRec(auditRec)
  1167  
  1168  	if !c.App.SessionHasPermissionToUser(*c.AppContext.Session(), c.Params.UserId) {
  1169  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
  1170  		return
  1171  	}
  1172  
  1173  	ouser, err := c.App.GetUser(c.Params.UserId)
  1174  	if err != nil {
  1175  		c.SetInvalidParam("user_id")
  1176  		return
  1177  	}
  1178  	auditRec.AddMeta("user", ouser)
  1179  
  1180  	// Cannot update a system admin unless user making request is a systemadmin also
  1181  	if ouser.IsSystemAdmin() && !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PERMISSION_MANAGE_SYSTEM) {
  1182  		c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
  1183  		return
  1184  	}
  1185  
  1186  	if c.AppContext.Session().IsOAuth && patch.Email != nil {
  1187  		if ouser.Email != *patch.Email {
  1188  			c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
  1189  			c.Err.DetailedError += ", attempted email update by oauth app"
  1190  			return
  1191  		}
  1192  	}
  1193  
  1194  	conflictField := c.App.CheckProviderAttributes(ouser, patch)
  1195  	if conflictField != "" {
  1196  		c.Err = model.NewAppError(
  1197  			"patchUser", "api.user.patch_user.login_provider_attribute_set.app_error",
  1198  			map[string]interface{}{"Field": conflictField}, "", http.StatusConflict)
  1199  		return
  1200  	}
  1201  
  1202  	// If eMail update is attempted by the currently logged in user, check if correct password was provided
  1203  	if patch.Email != nil && ouser.Email != *patch.Email && c.AppContext.Session().UserId == c.Params.UserId {
  1204  		if patch.Password == nil {
  1205  			c.SetInvalidParam("password")
  1206  			return
  1207  		}
  1208  
  1209  		if err = c.App.DoubleCheckPassword(ouser, *patch.Password); err != nil {
  1210  			c.Err = err
  1211  			return
  1212  		}
  1213  	}
  1214  
  1215  	ruser, err := c.App.PatchUser(c.Params.UserId, patch, c.IsSystemAdmin())
  1216  	if err != nil {
  1217  		c.Err = err
  1218  		return
  1219  	}
  1220  
  1221  	c.App.SetAutoResponderStatus(ruser, ouser.NotifyProps)
  1222  
  1223  	auditRec.Success()
  1224  	auditRec.AddMeta("patch", ruser)
  1225  	c.LogAudit("")
  1226  
  1227  	w.Write([]byte(ruser.ToJson()))
  1228  }
  1229  
  1230  func deleteUser(c *Context, w http.ResponseWriter, r *http.Request) {
  1231  	c.RequireUserId()
  1232  	if c.Err != nil {
  1233  		return
  1234  	}
  1235  
  1236  	userId := c.Params.UserId
  1237  
  1238  	auditRec := c.MakeAuditRecord("deleteUser", audit.Fail)
  1239  	defer c.LogAuditRec(auditRec)
  1240  
  1241  	if !c.App.SessionHasPermissionToUser(*c.AppContext.Session(), userId) {
  1242  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
  1243  		return
  1244  	}
  1245  
  1246  	// if EnableUserDeactivation flag is disabled the user cannot deactivate himself.
  1247  	if c.Params.UserId == c.AppContext.Session().UserId && !*c.App.Config().TeamSettings.EnableUserDeactivation && !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PERMISSION_MANAGE_SYSTEM) {
  1248  		c.Err = model.NewAppError("deleteUser", "api.user.update_active.not_enable.app_error", nil, "userId="+c.Params.UserId, http.StatusUnauthorized)
  1249  		return
  1250  	}
  1251  
  1252  	user, err := c.App.GetUser(userId)
  1253  	if err != nil {
  1254  		c.Err = err
  1255  		return
  1256  	}
  1257  	auditRec.AddMeta("user", user)
  1258  
  1259  	// Cannot update a system admin unless user making request is a systemadmin also
  1260  	if user.IsSystemAdmin() && !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PERMISSION_MANAGE_SYSTEM) {
  1261  		c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
  1262  		return
  1263  	}
  1264  
  1265  	if c.Params.Permanent {
  1266  		if *c.App.Config().ServiceSettings.EnableAPIUserDeletion {
  1267  			err = c.App.PermanentDeleteUser(c.AppContext, user)
  1268  		} else {
  1269  			err = model.NewAppError("deleteUser", "api.user.delete_user.not_enabled.app_error", nil, "userId="+c.Params.UserId, http.StatusUnauthorized)
  1270  		}
  1271  	} else {
  1272  		_, err = c.App.UpdateActive(c.AppContext, user, false)
  1273  	}
  1274  	if err != nil {
  1275  		c.Err = err
  1276  		return
  1277  	}
  1278  
  1279  	auditRec.Success()
  1280  	ReturnStatusOK(w)
  1281  }
  1282  
  1283  func updateUserRoles(c *Context, w http.ResponseWriter, r *http.Request) {
  1284  	c.RequireUserId()
  1285  	if c.Err != nil {
  1286  		return
  1287  	}
  1288  
  1289  	props := model.MapFromJson(r.Body)
  1290  
  1291  	newRoles := props["roles"]
  1292  	if !model.IsValidUserRoles(newRoles) {
  1293  		c.SetInvalidParam("roles")
  1294  		return
  1295  	}
  1296  
  1297  	// require license feature to assign "new system roles"
  1298  	for _, roleName := range strings.Fields(newRoles) {
  1299  		for _, id := range model.NewSystemRoleIDs {
  1300  			if roleName == id {
  1301  				if license := c.App.Srv().License(); license == nil || !*license.Features.CustomPermissionsSchemes {
  1302  					c.Err = model.NewAppError("updateUserRoles", "api.user.update_user_roles.license.app_error", nil, "", http.StatusBadRequest)
  1303  					return
  1304  				}
  1305  			}
  1306  		}
  1307  	}
  1308  
  1309  	auditRec := c.MakeAuditRecord("updateUserRoles", audit.Fail)
  1310  	defer c.LogAuditRec(auditRec)
  1311  	auditRec.AddMeta("roles", newRoles)
  1312  
  1313  	if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PERMISSION_MANAGE_ROLES) {
  1314  		c.SetPermissionError(model.PERMISSION_MANAGE_ROLES)
  1315  		return
  1316  	}
  1317  
  1318  	user, err := c.App.UpdateUserRoles(c.Params.UserId, newRoles, true)
  1319  	if err != nil {
  1320  		c.Err = err
  1321  		return
  1322  	}
  1323  
  1324  	auditRec.Success()
  1325  	auditRec.AddMeta("user", user)
  1326  	c.LogAudit(fmt.Sprintf("user=%s roles=%s", c.Params.UserId, newRoles))
  1327  
  1328  	ReturnStatusOK(w)
  1329  }
  1330  
  1331  func updateUserActive(c *Context, w http.ResponseWriter, r *http.Request) {
  1332  	c.RequireUserId()
  1333  	if c.Err != nil {
  1334  		return
  1335  	}
  1336  
  1337  	props := model.StringInterfaceFromJson(r.Body)
  1338  
  1339  	active, ok := props["active"].(bool)
  1340  	if !ok {
  1341  		c.SetInvalidParam("active")
  1342  		return
  1343  	}
  1344  
  1345  	auditRec := c.MakeAuditRecord("updateUserActive", audit.Fail)
  1346  	defer c.LogAuditRec(auditRec)
  1347  	auditRec.AddMeta("active", active)
  1348  
  1349  	// true when you're trying to de-activate yourself
  1350  	isSelfDeactive := !active && c.Params.UserId == c.AppContext.Session().UserId
  1351  
  1352  	if !isSelfDeactive && !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_USERS) {
  1353  		c.Err = model.NewAppError("updateUserActive", "api.user.update_active.permissions.app_error", nil, "userId="+c.Params.UserId, http.StatusForbidden)
  1354  		return
  1355  	}
  1356  
  1357  	// if EnableUserDeactivation flag is disabled the user cannot deactivate himself.
  1358  	if isSelfDeactive && !*c.App.Config().TeamSettings.EnableUserDeactivation {
  1359  		c.Err = model.NewAppError("updateUserActive", "api.user.update_active.not_enable.app_error", nil, "userId="+c.Params.UserId, http.StatusUnauthorized)
  1360  		return
  1361  	}
  1362  
  1363  	user, err := c.App.GetUser(c.Params.UserId)
  1364  	if err != nil {
  1365  		c.Err = err
  1366  		return
  1367  	}
  1368  	auditRec.AddMeta("user", user)
  1369  
  1370  	if user.IsSystemAdmin() && !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PERMISSION_MANAGE_SYSTEM) {
  1371  		c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
  1372  		return
  1373  	}
  1374  
  1375  	if active && user.IsGuest() && !*c.App.Config().GuestAccountsSettings.Enable {
  1376  		c.Err = model.NewAppError("updateUserActive", "api.user.update_active.cannot_enable_guest_when_guest_feature_is_disabled.app_error", nil, "userId="+c.Params.UserId, http.StatusUnauthorized)
  1377  		return
  1378  	}
  1379  
  1380  	// if non cloud instances, isOverLimit is false and no error
  1381  	isAtLimit, err := c.App.CheckCloudAccountAtLimit()
  1382  	if err != nil {
  1383  		c.Err = model.NewAppError("updateUserActive", "api.user.update_active.cloud_at_limit_check_error", nil, "userId="+c.Params.UserId, http.StatusInternalServerError)
  1384  		return
  1385  	}
  1386  
  1387  	if active && isAtLimit {
  1388  		c.Err = model.NewAppError("updateUserActive", "api.user.update_active.cloud_at_or_over_limit_check_overcapacity", nil, "userId="+c.Params.UserId, http.StatusBadRequest)
  1389  		return
  1390  	}
  1391  
  1392  	if _, err = c.App.UpdateActive(c.AppContext, user, active); err != nil {
  1393  		c.Err = err
  1394  	}
  1395  
  1396  	auditRec.Success()
  1397  	c.LogAudit(fmt.Sprintf("user_id=%s active=%v", user.Id, active))
  1398  
  1399  	if isSelfDeactive {
  1400  		c.App.Srv().Go(func() {
  1401  			if err = c.App.Srv().EmailService.SendDeactivateAccountEmail(user.Email, user.Locale, c.App.GetSiteURL()); err != nil {
  1402  				c.LogErrorByCode(err)
  1403  			}
  1404  		})
  1405  	}
  1406  
  1407  	message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_USER_ACTIVATION_STATUS_CHANGE, "", "", "", nil)
  1408  	c.App.Publish(message)
  1409  
  1410  	// If activating, run cloud check for limit overages
  1411  	if active {
  1412  		emailErr := c.App.CheckAndSendUserLimitWarningEmails(c.AppContext)
  1413  		if emailErr != nil {
  1414  			c.Err = emailErr
  1415  			return
  1416  		}
  1417  	}
  1418  
  1419  	ReturnStatusOK(w)
  1420  }
  1421  
  1422  func updateUserAuth(c *Context, w http.ResponseWriter, r *http.Request) {
  1423  	if !c.IsSystemAdmin() {
  1424  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
  1425  		return
  1426  	}
  1427  
  1428  	c.RequireUserId()
  1429  	if c.Err != nil {
  1430  		return
  1431  	}
  1432  
  1433  	auditRec := c.MakeAuditRecord("updateUserAuth", audit.Fail)
  1434  	defer c.LogAuditRec(auditRec)
  1435  
  1436  	userAuth := model.UserAuthFromJson(r.Body)
  1437  	if userAuth == nil {
  1438  		c.SetInvalidParam("user")
  1439  		return
  1440  	}
  1441  
  1442  	if userAuth.AuthData == nil || *userAuth.AuthData == "" || userAuth.AuthService == "" {
  1443  		c.Err = model.NewAppError("updateUserAuth", "api.user.update_user_auth.invalid_request", nil, "", http.StatusBadRequest)
  1444  		return
  1445  	}
  1446  
  1447  	if user, err := c.App.GetUser(c.Params.UserId); err == nil {
  1448  		auditRec.AddMeta("user", user)
  1449  	}
  1450  
  1451  	user, err := c.App.UpdateUserAuth(c.Params.UserId, userAuth)
  1452  	if err != nil {
  1453  		c.Err = err
  1454  		return
  1455  	}
  1456  
  1457  	auditRec.Success()
  1458  	auditRec.AddMeta("auth_service", user.AuthService)
  1459  	c.LogAudit(fmt.Sprintf("updated user %s auth to service=%v", c.Params.UserId, user.AuthService))
  1460  
  1461  	w.Write([]byte(user.ToJson()))
  1462  }
  1463  
  1464  // Deprecated: checkUserMfa is deprecated and should not be used anymore, starting with version 6.0 it will be disabled.
  1465  //			   Clients should attempt a login without MFA and will receive a MFA error when it's required.
  1466  func checkUserMfa(c *Context, w http.ResponseWriter, r *http.Request) {
  1467  
  1468  	if *c.App.Config().ServiceSettings.DisableLegacyMFA {
  1469  		http.NotFound(w, r)
  1470  		return
  1471  	}
  1472  
  1473  	props := model.MapFromJson(r.Body)
  1474  
  1475  	loginId := props["login_id"]
  1476  	if loginId == "" {
  1477  		c.SetInvalidParam("login_id")
  1478  		return
  1479  	}
  1480  
  1481  	resp := map[string]interface{}{}
  1482  	resp["mfa_required"] = false
  1483  
  1484  	if !*c.App.Config().ServiceSettings.EnableMultifactorAuthentication {
  1485  		w.Write([]byte(model.StringInterfaceToJson(resp)))
  1486  		return
  1487  	}
  1488  
  1489  	if *c.App.Config().ServiceSettings.ExperimentalEnableHardenedMode {
  1490  		resp["mfa_required"] = true
  1491  	} else if user, err := c.App.GetUserForLogin("", loginId); err == nil {
  1492  		resp["mfa_required"] = user.MfaActive
  1493  	}
  1494  
  1495  	w.Write([]byte(model.StringInterfaceToJson(resp)))
  1496  }
  1497  
  1498  func updateUserMfa(c *Context, w http.ResponseWriter, r *http.Request) {
  1499  	c.RequireUserId()
  1500  	if c.Err != nil {
  1501  		return
  1502  	}
  1503  
  1504  	auditRec := c.MakeAuditRecord("updateUserMfa", audit.Fail)
  1505  	defer c.LogAuditRec(auditRec)
  1506  
  1507  	if c.AppContext.Session().IsOAuth {
  1508  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
  1509  		c.Err.DetailedError += ", attempted access by oauth app"
  1510  		return
  1511  	}
  1512  
  1513  	if !c.App.SessionHasPermissionToUser(*c.AppContext.Session(), c.Params.UserId) {
  1514  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
  1515  		return
  1516  	}
  1517  
  1518  	if user, err := c.App.GetUser(c.Params.UserId); err == nil {
  1519  		auditRec.AddMeta("user", user)
  1520  	}
  1521  
  1522  	props := model.StringInterfaceFromJson(r.Body)
  1523  	activate, ok := props["activate"].(bool)
  1524  	if !ok {
  1525  		c.SetInvalidParam("activate")
  1526  		return
  1527  	}
  1528  
  1529  	code := ""
  1530  	if activate {
  1531  		code, ok = props["code"].(string)
  1532  		if !ok || code == "" {
  1533  			c.SetInvalidParam("code")
  1534  			return
  1535  		}
  1536  	}
  1537  
  1538  	c.LogAudit("attempt")
  1539  
  1540  	if err := c.App.UpdateMfa(activate, c.Params.UserId, code); err != nil {
  1541  		c.Err = err
  1542  		return
  1543  	}
  1544  
  1545  	auditRec.Success()
  1546  	auditRec.AddMeta("activate", activate)
  1547  	c.LogAudit("success - mfa updated")
  1548  
  1549  	ReturnStatusOK(w)
  1550  }
  1551  
  1552  func generateMfaSecret(c *Context, w http.ResponseWriter, r *http.Request) {
  1553  	c.RequireUserId()
  1554  	if c.Err != nil {
  1555  		return
  1556  	}
  1557  
  1558  	if c.AppContext.Session().IsOAuth {
  1559  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
  1560  		c.Err.DetailedError += ", attempted access by oauth app"
  1561  		return
  1562  	}
  1563  
  1564  	if !c.App.SessionHasPermissionToUser(*c.AppContext.Session(), c.Params.UserId) {
  1565  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
  1566  		return
  1567  	}
  1568  
  1569  	secret, err := c.App.GenerateMfaSecret(c.Params.UserId)
  1570  	if err != nil {
  1571  		c.Err = err
  1572  		return
  1573  	}
  1574  
  1575  	w.Header().Set("Cache-Control", "no-cache")
  1576  	w.Header().Set("Pragma", "no-cache")
  1577  	w.Header().Set("Expires", "0")
  1578  	w.Write([]byte(secret.ToJson()))
  1579  }
  1580  
  1581  func updatePassword(c *Context, w http.ResponseWriter, r *http.Request) {
  1582  	c.RequireUserId()
  1583  	if c.Err != nil {
  1584  		return
  1585  	}
  1586  
  1587  	props := model.MapFromJson(r.Body)
  1588  	newPassword := props["new_password"]
  1589  
  1590  	auditRec := c.MakeAuditRecord("updatePassword", audit.Fail)
  1591  	defer c.LogAuditRec(auditRec)
  1592  	c.LogAudit("attempted")
  1593  
  1594  	var canUpdatePassword bool
  1595  	if user, err := c.App.GetUser(c.Params.UserId); err == nil {
  1596  		auditRec.AddMeta("user", user)
  1597  
  1598  		if user.IsSystemAdmin() {
  1599  			canUpdatePassword = c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PERMISSION_MANAGE_SYSTEM)
  1600  		} else {
  1601  			canUpdatePassword = c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_USERS)
  1602  		}
  1603  	}
  1604  
  1605  	var err *model.AppError
  1606  
  1607  	// There are two main update flows depending on whether the provided password
  1608  	// is already hashed or not.
  1609  	if props["already_hashed"] == "true" {
  1610  		if canUpdatePassword {
  1611  			err = c.App.UpdateHashedPasswordByUserId(c.Params.UserId, newPassword)
  1612  		} else if c.Params.UserId == c.AppContext.Session().UserId {
  1613  			err = model.NewAppError("updatePassword", "api.user.update_password.user_and_hashed.app_error", nil, "", http.StatusUnauthorized)
  1614  		} else {
  1615  			err = model.NewAppError("updatePassword", "api.user.update_password.context.app_error", nil, "", http.StatusForbidden)
  1616  		}
  1617  	} else {
  1618  		if c.Params.UserId == c.AppContext.Session().UserId {
  1619  			currentPassword := props["current_password"]
  1620  			if currentPassword == "" {
  1621  				c.SetInvalidParam("current_password")
  1622  				return
  1623  			}
  1624  
  1625  			err = c.App.UpdatePasswordAsUser(c.Params.UserId, currentPassword, newPassword)
  1626  		} else if canUpdatePassword {
  1627  			err = c.App.UpdatePasswordByUserIdSendEmail(c.Params.UserId, newPassword, c.AppContext.T("api.user.reset_password.method"))
  1628  		} else {
  1629  			err = model.NewAppError("updatePassword", "api.user.update_password.context.app_error", nil, "", http.StatusForbidden)
  1630  		}
  1631  	}
  1632  
  1633  	if err != nil {
  1634  		c.LogAudit("failed")
  1635  		c.Err = err
  1636  		return
  1637  	}
  1638  
  1639  	auditRec.Success()
  1640  	c.LogAudit("completed")
  1641  
  1642  	ReturnStatusOK(w)
  1643  }
  1644  
  1645  func resetPassword(c *Context, w http.ResponseWriter, r *http.Request) {
  1646  	props := model.MapFromJson(r.Body)
  1647  
  1648  	token := props["token"]
  1649  	if len(token) != model.TOKEN_SIZE {
  1650  		c.SetInvalidParam("token")
  1651  		return
  1652  	}
  1653  
  1654  	newPassword := props["new_password"]
  1655  
  1656  	auditRec := c.MakeAuditRecord("resetPassword", audit.Fail)
  1657  	defer c.LogAuditRec(auditRec)
  1658  	auditRec.AddMeta("token", token)
  1659  	c.LogAudit("attempt - token=" + token)
  1660  
  1661  	if err := c.App.ResetPasswordFromToken(token, newPassword); err != nil {
  1662  		c.LogAudit("fail - token=" + token)
  1663  		c.Err = err
  1664  		return
  1665  	}
  1666  
  1667  	auditRec.Success()
  1668  	c.LogAudit("success - token=" + token)
  1669  
  1670  	ReturnStatusOK(w)
  1671  }
  1672  
  1673  func sendPasswordReset(c *Context, w http.ResponseWriter, r *http.Request) {
  1674  	props := model.MapFromJson(r.Body)
  1675  
  1676  	email := props["email"]
  1677  	email = strings.ToLower(email)
  1678  	if email == "" {
  1679  		c.SetInvalidParam("email")
  1680  		return
  1681  	}
  1682  
  1683  	auditRec := c.MakeAuditRecord("sendPasswordReset", audit.Fail)
  1684  	defer c.LogAuditRec(auditRec)
  1685  	auditRec.AddMeta("email", email)
  1686  
  1687  	sent, err := c.App.SendPasswordReset(email, c.App.GetSiteURL())
  1688  	if err != nil {
  1689  		if *c.App.Config().ServiceSettings.ExperimentalEnableHardenedMode {
  1690  			ReturnStatusOK(w)
  1691  		} else {
  1692  			c.Err = err
  1693  		}
  1694  		return
  1695  	}
  1696  
  1697  	if sent {
  1698  		auditRec.Success()
  1699  		c.LogAudit("sent=" + email)
  1700  	}
  1701  	ReturnStatusOK(w)
  1702  }
  1703  
  1704  func login(c *Context, w http.ResponseWriter, r *http.Request) {
  1705  	// Mask all sensitive errors, with the exception of the following
  1706  	defer func() {
  1707  		if c.Err == nil {
  1708  			return
  1709  		}
  1710  
  1711  		unmaskedErrors := []string{
  1712  			"mfa.validate_token.authenticate.app_error",
  1713  			"api.user.check_user_mfa.bad_code.app_error",
  1714  			"api.user.login.blank_pwd.app_error",
  1715  			"api.user.login.bot_login_forbidden.app_error",
  1716  			"api.user.login.client_side_cert.certificate.app_error",
  1717  			"api.user.login.inactive.app_error",
  1718  			"api.user.login.not_verified.app_error",
  1719  			"api.user.check_user_login_attempts.too_many.app_error",
  1720  			"app.team.join_user_to_team.max_accounts.app_error",
  1721  			"store.sql_user.save.max_accounts.app_error",
  1722  		}
  1723  
  1724  		maskError := true
  1725  
  1726  		for _, unmaskedError := range unmaskedErrors {
  1727  			if c.Err.Id == unmaskedError {
  1728  				maskError = false
  1729  			}
  1730  		}
  1731  
  1732  		if !maskError {
  1733  			return
  1734  		}
  1735  
  1736  		config := c.App.Config()
  1737  		enableUsername := *config.EmailSettings.EnableSignInWithUsername
  1738  		enableEmail := *config.EmailSettings.EnableSignInWithEmail
  1739  		samlEnabled := *config.SamlSettings.Enable
  1740  		gitlabEnabled := *config.GitLabSettings.Enable
  1741  		openidEnabled := *config.OpenIdSettings.Enable
  1742  		googleEnabled := *config.GoogleSettings.Enable
  1743  		office365Enabled := *config.Office365Settings.Enable
  1744  
  1745  		if samlEnabled || gitlabEnabled || googleEnabled || office365Enabled || openidEnabled {
  1746  			c.Err = model.NewAppError("login", "api.user.login.invalid_credentials_sso", nil, "", http.StatusUnauthorized)
  1747  			return
  1748  		}
  1749  
  1750  		if enableUsername && !enableEmail {
  1751  			c.Err = model.NewAppError("login", "api.user.login.invalid_credentials_username", nil, "", http.StatusUnauthorized)
  1752  			return
  1753  		}
  1754  
  1755  		if !enableUsername && enableEmail {
  1756  			c.Err = model.NewAppError("login", "api.user.login.invalid_credentials_email", nil, "", http.StatusUnauthorized)
  1757  			return
  1758  		}
  1759  
  1760  		c.Err = model.NewAppError("login", "api.user.login.invalid_credentials_email_username", nil, "", http.StatusUnauthorized)
  1761  	}()
  1762  
  1763  	props := model.MapFromJson(r.Body)
  1764  	id := props["id"]
  1765  	loginId := props["login_id"]
  1766  	password := props["password"]
  1767  	mfaToken := props["token"]
  1768  	deviceId := props["device_id"]
  1769  	ldapOnly := props["ldap_only"] == "true"
  1770  
  1771  	if *c.App.Config().ExperimentalSettings.ClientSideCertEnable {
  1772  		if license := c.App.Srv().License(); license == nil || !*license.Features.SAML {
  1773  			c.Err = model.NewAppError("ClientSideCertNotAllowed", "api.user.login.client_side_cert.license.app_error", nil, "", http.StatusBadRequest)
  1774  			return
  1775  		}
  1776  		certPem, certSubject, certEmail := c.App.CheckForClientSideCert(r)
  1777  		mlog.Debug("Client Cert", mlog.String("cert_subject", certSubject), mlog.String("cert_email", certEmail))
  1778  
  1779  		if certPem == "" || certEmail == "" {
  1780  			c.Err = model.NewAppError("ClientSideCertMissing", "api.user.login.client_side_cert.certificate.app_error", nil, "", http.StatusBadRequest)
  1781  			return
  1782  		}
  1783  
  1784  		if *c.App.Config().ExperimentalSettings.ClientSideCertCheck == model.CLIENT_SIDE_CERT_CHECK_PRIMARY_AUTH {
  1785  			loginId = certEmail
  1786  			password = "certificate"
  1787  		}
  1788  	}
  1789  
  1790  	auditRec := c.MakeAuditRecord("login", audit.Fail)
  1791  	defer c.LogAuditRec(auditRec)
  1792  	auditRec.AddMeta("login_id", loginId)
  1793  	auditRec.AddMeta("device_id", deviceId)
  1794  
  1795  	c.LogAuditWithUserId(id, "attempt - login_id="+loginId)
  1796  
  1797  	user, err := c.App.AuthenticateUserForLogin(c.AppContext, id, loginId, password, mfaToken, "", ldapOnly)
  1798  	if err != nil {
  1799  		c.LogAuditWithUserId(id, "failure - login_id="+loginId)
  1800  		c.Err = err
  1801  		return
  1802  	}
  1803  	auditRec.AddMeta("user", user)
  1804  
  1805  	if user.IsGuest() {
  1806  		if c.App.Srv().License() == nil {
  1807  			c.Err = model.NewAppError("login", "api.user.login.guest_accounts.license.error", nil, "", http.StatusUnauthorized)
  1808  			return
  1809  		}
  1810  		if !*c.App.Config().GuestAccountsSettings.Enable {
  1811  			c.Err = model.NewAppError("login", "api.user.login.guest_accounts.disabled.error", nil, "", http.StatusUnauthorized)
  1812  			return
  1813  		}
  1814  	}
  1815  
  1816  	c.LogAuditWithUserId(user.Id, "authenticated")
  1817  
  1818  	err = c.App.DoLogin(c.AppContext, w, r, user, deviceId, false, false, false)
  1819  	if err != nil {
  1820  		c.Err = err
  1821  		return
  1822  	}
  1823  
  1824  	c.LogAuditWithUserId(user.Id, "success")
  1825  
  1826  	if r.Header.Get(model.HEADER_REQUESTED_WITH) == model.HEADER_REQUESTED_WITH_XML {
  1827  		c.App.AttachSessionCookies(c.AppContext, w, r)
  1828  	}
  1829  
  1830  	userTermsOfService, err := c.App.GetUserTermsOfService(user.Id)
  1831  	if err != nil && err.StatusCode != http.StatusNotFound {
  1832  		c.Err = err
  1833  		return
  1834  	}
  1835  
  1836  	if userTermsOfService != nil {
  1837  		user.TermsOfServiceId = userTermsOfService.TermsOfServiceId
  1838  		user.TermsOfServiceCreateAt = userTermsOfService.CreateAt
  1839  	}
  1840  
  1841  	user.Sanitize(map[string]bool{})
  1842  
  1843  	auditRec.Success()
  1844  	w.Write([]byte(user.ToJson()))
  1845  }
  1846  
  1847  func loginCWS(c *Context, w http.ResponseWriter, r *http.Request) {
  1848  	if c.App.Srv().License() == nil || !*c.App.Srv().License().Features.Cloud {
  1849  		c.Err = model.NewAppError("loginCWS", "api.user.login_cws.license.error", nil, "", http.StatusUnauthorized)
  1850  		return
  1851  	}
  1852  	r.ParseForm()
  1853  	var loginID string
  1854  	var token string
  1855  	if len(r.Form) > 0 {
  1856  		for key, value := range r.Form {
  1857  			if key == "login_id" {
  1858  				loginID = value[0]
  1859  			}
  1860  			if key == "cws_token" {
  1861  				token = value[0]
  1862  			}
  1863  		}
  1864  	}
  1865  
  1866  	auditRec := c.MakeAuditRecord("login", audit.Fail)
  1867  	defer c.LogAuditRec(auditRec)
  1868  	auditRec.AddMeta("login_id", loginID)
  1869  	user, err := c.App.AuthenticateUserForLogin(c.AppContext, "", loginID, "", "", token, false)
  1870  	if err != nil {
  1871  		c.LogAuditWithUserId("", "failure - login_id="+loginID)
  1872  		c.LogErrorByCode(err)
  1873  		http.Redirect(w, r, *c.App.Config().ServiceSettings.SiteURL, 302)
  1874  		return
  1875  	}
  1876  	auditRec.AddMeta("user", user)
  1877  	c.LogAuditWithUserId(user.Id, "authenticated")
  1878  	err = c.App.DoLogin(c.AppContext, w, r, user, "", false, false, false)
  1879  	if err != nil {
  1880  		c.LogErrorByCode(err)
  1881  		http.Redirect(w, r, *c.App.Config().ServiceSettings.SiteURL, 302)
  1882  		return
  1883  	}
  1884  	c.LogAuditWithUserId(user.Id, "success")
  1885  	c.App.AttachSessionCookies(c.AppContext, w, r)
  1886  	http.Redirect(w, r, *c.App.Config().ServiceSettings.SiteURL, 302)
  1887  }
  1888  
  1889  func logout(c *Context, w http.ResponseWriter, r *http.Request) {
  1890  	Logout(c, w, r)
  1891  }
  1892  
  1893  func Logout(c *Context, w http.ResponseWriter, r *http.Request) {
  1894  	auditRec := c.MakeAuditRecord("Logout", audit.Fail)
  1895  	defer c.LogAuditRec(auditRec)
  1896  	c.LogAudit("")
  1897  
  1898  	c.RemoveSessionCookie(w, r)
  1899  	if c.AppContext.Session().Id != "" {
  1900  		if err := c.App.RevokeSessionById(c.AppContext.Session().Id); err != nil {
  1901  			c.Err = err
  1902  			return
  1903  		}
  1904  	}
  1905  
  1906  	auditRec.Success()
  1907  	ReturnStatusOK(w)
  1908  }
  1909  
  1910  func getSessions(c *Context, w http.ResponseWriter, r *http.Request) {
  1911  	c.RequireUserId()
  1912  	if c.Err != nil {
  1913  		return
  1914  	}
  1915  
  1916  	if !c.App.SessionHasPermissionToUser(*c.AppContext.Session(), c.Params.UserId) {
  1917  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
  1918  		return
  1919  	}
  1920  
  1921  	sessions, err := c.App.GetSessions(c.Params.UserId)
  1922  	if err != nil {
  1923  		c.Err = err
  1924  		return
  1925  	}
  1926  
  1927  	for _, session := range sessions {
  1928  		session.Sanitize()
  1929  	}
  1930  
  1931  	w.Write([]byte(model.SessionsToJson(sessions)))
  1932  }
  1933  
  1934  func revokeSession(c *Context, w http.ResponseWriter, r *http.Request) {
  1935  	c.RequireUserId()
  1936  	if c.Err != nil {
  1937  		return
  1938  	}
  1939  
  1940  	auditRec := c.MakeAuditRecord("revokeSession", audit.Fail)
  1941  	defer c.LogAuditRec(auditRec)
  1942  
  1943  	if !c.App.SessionHasPermissionToUser(*c.AppContext.Session(), c.Params.UserId) {
  1944  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
  1945  		return
  1946  	}
  1947  
  1948  	props := model.MapFromJson(r.Body)
  1949  	sessionId := props["session_id"]
  1950  	if sessionId == "" {
  1951  		c.SetInvalidParam("session_id")
  1952  		return
  1953  	}
  1954  
  1955  	session, err := c.App.GetSessionById(sessionId)
  1956  	if err != nil {
  1957  		c.Err = err
  1958  		return
  1959  	}
  1960  	auditRec.AddMeta("session", session)
  1961  
  1962  	if session.UserId != c.Params.UserId {
  1963  		c.SetInvalidUrlParam("user_id")
  1964  		return
  1965  	}
  1966  
  1967  	if err := c.App.RevokeSession(session); err != nil {
  1968  		c.Err = err
  1969  		return
  1970  	}
  1971  
  1972  	auditRec.Success()
  1973  	c.LogAudit("")
  1974  
  1975  	ReturnStatusOK(w)
  1976  }
  1977  
  1978  func revokeAllSessionsForUser(c *Context, w http.ResponseWriter, r *http.Request) {
  1979  	c.RequireUserId()
  1980  	if c.Err != nil {
  1981  		return
  1982  	}
  1983  
  1984  	auditRec := c.MakeAuditRecord("revokeAllSessionsForUser", audit.Fail)
  1985  	defer c.LogAuditRec(auditRec)
  1986  	auditRec.AddMeta("user_id", c.Params.UserId)
  1987  
  1988  	if !c.App.SessionHasPermissionToUser(*c.AppContext.Session(), c.Params.UserId) {
  1989  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
  1990  		return
  1991  	}
  1992  
  1993  	if err := c.App.RevokeAllSessions(c.Params.UserId); err != nil {
  1994  		c.Err = err
  1995  		return
  1996  	}
  1997  
  1998  	auditRec.Success()
  1999  	c.LogAudit("")
  2000  
  2001  	ReturnStatusOK(w)
  2002  }
  2003  
  2004  func revokeAllSessionsAllUsers(c *Context, w http.ResponseWriter, r *http.Request) {
  2005  	if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PERMISSION_MANAGE_SYSTEM) {
  2006  		c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
  2007  		return
  2008  	}
  2009  
  2010  	auditRec := c.MakeAuditRecord("revokeAllSessionsAllUsers", audit.Fail)
  2011  	defer c.LogAuditRec(auditRec)
  2012  
  2013  	if err := c.App.RevokeSessionsFromAllUsers(); err != nil {
  2014  		c.Err = err
  2015  		return
  2016  	}
  2017  
  2018  	auditRec.Success()
  2019  	c.LogAudit("")
  2020  
  2021  	ReturnStatusOK(w)
  2022  }
  2023  
  2024  func attachDeviceId(c *Context, w http.ResponseWriter, r *http.Request) {
  2025  	props := model.MapFromJson(r.Body)
  2026  
  2027  	deviceId := props["device_id"]
  2028  	if deviceId == "" {
  2029  		c.SetInvalidParam("device_id")
  2030  		return
  2031  	}
  2032  
  2033  	auditRec := c.MakeAuditRecord("attachDeviceId", audit.Fail)
  2034  	defer c.LogAuditRec(auditRec)
  2035  	auditRec.AddMeta("device_id", deviceId)
  2036  
  2037  	// A special case where we logout of all other sessions with the same device id
  2038  	if err := c.App.RevokeSessionsForDeviceId(c.AppContext.Session().UserId, deviceId, c.AppContext.Session().Id); err != nil {
  2039  		c.Err = err
  2040  		return
  2041  	}
  2042  
  2043  	c.App.ClearSessionCacheForUser(c.AppContext.Session().UserId)
  2044  	c.App.SetSessionExpireInDays(c.AppContext.Session(), *c.App.Config().ServiceSettings.SessionLengthMobileInDays)
  2045  
  2046  	maxAge := *c.App.Config().ServiceSettings.SessionLengthMobileInDays * 60 * 60 * 24
  2047  
  2048  	secure := false
  2049  	if app.GetProtocol(r) == "https" {
  2050  		secure = true
  2051  	}
  2052  
  2053  	subpath, _ := utils.GetSubpathFromConfig(c.App.Config())
  2054  
  2055  	expiresAt := time.Unix(model.GetMillis()/1000+int64(maxAge), 0)
  2056  	sessionCookie := &http.Cookie{
  2057  		Name:     model.SESSION_COOKIE_TOKEN,
  2058  		Value:    c.AppContext.Session().Token,
  2059  		Path:     subpath,
  2060  		MaxAge:   maxAge,
  2061  		Expires:  expiresAt,
  2062  		HttpOnly: true,
  2063  		Domain:   c.App.GetCookieDomain(),
  2064  		Secure:   secure,
  2065  	}
  2066  
  2067  	http.SetCookie(w, sessionCookie)
  2068  
  2069  	if err := c.App.AttachDeviceId(c.AppContext.Session().Id, deviceId, c.AppContext.Session().ExpiresAt); err != nil {
  2070  		c.Err = err
  2071  		return
  2072  	}
  2073  
  2074  	auditRec.Success()
  2075  	c.LogAudit("")
  2076  
  2077  	ReturnStatusOK(w)
  2078  }
  2079  
  2080  func getUserAudits(c *Context, w http.ResponseWriter, r *http.Request) {
  2081  	c.RequireUserId()
  2082  	if c.Err != nil {
  2083  		return
  2084  	}
  2085  
  2086  	auditRec := c.MakeAuditRecord("getUserAudits", audit.Fail)
  2087  	defer c.LogAuditRec(auditRec)
  2088  
  2089  	if user, err := c.App.GetUser(c.Params.UserId); err == nil {
  2090  		auditRec.AddMeta("user", user)
  2091  	}
  2092  
  2093  	if !c.App.SessionHasPermissionToUser(*c.AppContext.Session(), c.Params.UserId) {
  2094  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
  2095  		return
  2096  	}
  2097  
  2098  	audits, err := c.App.GetAuditsPage(c.Params.UserId, c.Params.Page, c.Params.PerPage)
  2099  	if err != nil {
  2100  		c.Err = err
  2101  		return
  2102  	}
  2103  
  2104  	auditRec.Success()
  2105  	auditRec.AddMeta("page", c.Params.Page)
  2106  	auditRec.AddMeta("audits_per_page", c.Params.LogsPerPage)
  2107  
  2108  	w.Write([]byte(audits.ToJson()))
  2109  }
  2110  
  2111  func verifyUserEmail(c *Context, w http.ResponseWriter, r *http.Request) {
  2112  	props := model.MapFromJson(r.Body)
  2113  
  2114  	token := props["token"]
  2115  	if len(token) != model.TOKEN_SIZE {
  2116  		c.SetInvalidParam("token")
  2117  		return
  2118  	}
  2119  
  2120  	auditRec := c.MakeAuditRecord("verifyUserEmail", audit.Fail)
  2121  	defer c.LogAuditRec(auditRec)
  2122  
  2123  	if err := c.App.VerifyEmailFromToken(token); err != nil {
  2124  		c.Err = model.NewAppError("verifyUserEmail", "api.user.verify_email.bad_link.app_error", nil, err.Error(), http.StatusBadRequest)
  2125  		return
  2126  	}
  2127  
  2128  	auditRec.Success()
  2129  	c.LogAudit("Email Verified")
  2130  
  2131  	ReturnStatusOK(w)
  2132  }
  2133  
  2134  func sendVerificationEmail(c *Context, w http.ResponseWriter, r *http.Request) {
  2135  	props := model.MapFromJson(r.Body)
  2136  
  2137  	email := props["email"]
  2138  	email = strings.ToLower(email)
  2139  	if email == "" {
  2140  		c.SetInvalidParam("email")
  2141  		return
  2142  	}
  2143  	redirect := r.URL.Query().Get("r")
  2144  
  2145  	auditRec := c.MakeAuditRecord("sendVerificationEmail", audit.Fail)
  2146  	defer c.LogAuditRec(auditRec)
  2147  	auditRec.AddMeta("email", email)
  2148  
  2149  	user, err := c.App.GetUserForLogin("", email)
  2150  	if err != nil {
  2151  		// Don't want to leak whether the email is valid or not
  2152  		ReturnStatusOK(w)
  2153  		return
  2154  	}
  2155  	auditRec.AddMeta("user", user)
  2156  
  2157  	if err = c.App.SendEmailVerification(user, user.Email, redirect); err != nil {
  2158  		// Don't want to leak whether the email is valid or not
  2159  		c.LogErrorByCode(err)
  2160  		ReturnStatusOK(w)
  2161  		return
  2162  	}
  2163  
  2164  	auditRec.Success()
  2165  	ReturnStatusOK(w)
  2166  }
  2167  
  2168  func switchAccountType(c *Context, w http.ResponseWriter, r *http.Request) {
  2169  	switchRequest := model.SwitchRequestFromJson(r.Body)
  2170  	if switchRequest == nil {
  2171  		c.SetInvalidParam("switch_request")
  2172  		return
  2173  	}
  2174  
  2175  	auditRec := c.MakeAuditRecord("switchAccountType", audit.Fail)
  2176  	defer c.LogAuditRec(auditRec)
  2177  	auditRec.AddMeta("email", switchRequest.Email)
  2178  	auditRec.AddMeta("new_service", switchRequest.NewService)
  2179  	auditRec.AddMeta("old_service", switchRequest.CurrentService)
  2180  
  2181  	link := ""
  2182  	var err *model.AppError
  2183  
  2184  	if switchRequest.EmailToOAuth() {
  2185  		link, err = c.App.SwitchEmailToOAuth(w, r, switchRequest.Email, switchRequest.Password, switchRequest.MfaCode, switchRequest.NewService)
  2186  	} else if switchRequest.OAuthToEmail() {
  2187  		c.SessionRequired()
  2188  		if c.Err != nil {
  2189  			return
  2190  		}
  2191  
  2192  		link, err = c.App.SwitchOAuthToEmail(switchRequest.Email, switchRequest.NewPassword, c.AppContext.Session().UserId)
  2193  	} else if switchRequest.EmailToLdap() {
  2194  		link, err = c.App.SwitchEmailToLdap(switchRequest.Email, switchRequest.Password, switchRequest.MfaCode, switchRequest.LdapLoginId, switchRequest.NewPassword)
  2195  	} else if switchRequest.LdapToEmail() {
  2196  		link, err = c.App.SwitchLdapToEmail(switchRequest.Password, switchRequest.MfaCode, switchRequest.Email, switchRequest.NewPassword)
  2197  	} else {
  2198  		c.SetInvalidParam("switch_request")
  2199  		return
  2200  	}
  2201  
  2202  	if err != nil {
  2203  		c.Err = err
  2204  		return
  2205  	}
  2206  
  2207  	auditRec.Success()
  2208  	c.LogAudit("success")
  2209  
  2210  	w.Write([]byte(model.MapToJson(map[string]string{"follow_link": link})))
  2211  }
  2212  
  2213  func createUserAccessToken(c *Context, w http.ResponseWriter, r *http.Request) {
  2214  	c.RequireUserId()
  2215  	if c.Err != nil {
  2216  		return
  2217  	}
  2218  
  2219  	auditRec := c.MakeAuditRecord("createUserAccessToken", audit.Fail)
  2220  	defer c.LogAuditRec(auditRec)
  2221  
  2222  	if user, err := c.App.GetUser(c.Params.UserId); err == nil {
  2223  		auditRec.AddMeta("user", user)
  2224  	}
  2225  
  2226  	if c.AppContext.Session().IsOAuth {
  2227  		c.SetPermissionError(model.PERMISSION_CREATE_USER_ACCESS_TOKEN)
  2228  		c.Err.DetailedError += ", attempted access by oauth app"
  2229  		return
  2230  	}
  2231  
  2232  	accessToken := model.UserAccessTokenFromJson(r.Body)
  2233  	if accessToken == nil {
  2234  		c.SetInvalidParam("user_access_token")
  2235  		return
  2236  	}
  2237  
  2238  	if accessToken.Description == "" {
  2239  		c.SetInvalidParam("description")
  2240  		return
  2241  	}
  2242  
  2243  	c.LogAudit("")
  2244  
  2245  	if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PERMISSION_CREATE_USER_ACCESS_TOKEN) {
  2246  		c.SetPermissionError(model.PERMISSION_CREATE_USER_ACCESS_TOKEN)
  2247  		return
  2248  	}
  2249  
  2250  	if !c.App.SessionHasPermissionToUserOrBot(*c.AppContext.Session(), c.Params.UserId) {
  2251  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
  2252  		return
  2253  	}
  2254  
  2255  	accessToken.UserId = c.Params.UserId
  2256  	accessToken.Token = ""
  2257  
  2258  	accessToken, err := c.App.CreateUserAccessToken(accessToken)
  2259  	if err != nil {
  2260  		c.Err = err
  2261  		return
  2262  	}
  2263  
  2264  	auditRec.Success()
  2265  	auditRec.AddMeta("token_id", accessToken.Id)
  2266  	c.LogAudit("success - token_id=" + accessToken.Id)
  2267  
  2268  	w.Write([]byte(accessToken.ToJson()))
  2269  }
  2270  
  2271  func searchUserAccessTokens(c *Context, w http.ResponseWriter, r *http.Request) {
  2272  	if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PERMISSION_MANAGE_SYSTEM) {
  2273  		c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
  2274  		return
  2275  	}
  2276  	props := model.UserAccessTokenSearchFromJson(r.Body)
  2277  	if props == nil {
  2278  		c.SetInvalidParam("user_access_token_search")
  2279  		return
  2280  	}
  2281  
  2282  	if props.Term == "" {
  2283  		c.SetInvalidParam("term")
  2284  		return
  2285  	}
  2286  
  2287  	accessTokens, err := c.App.SearchUserAccessTokens(props.Term)
  2288  	if err != nil {
  2289  		c.Err = err
  2290  		return
  2291  	}
  2292  
  2293  	w.Write([]byte(model.UserAccessTokenListToJson(accessTokens)))
  2294  }
  2295  
  2296  func getUserAccessTokens(c *Context, w http.ResponseWriter, r *http.Request) {
  2297  	if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PERMISSION_MANAGE_SYSTEM) {
  2298  		c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
  2299  		return
  2300  	}
  2301  
  2302  	accessTokens, err := c.App.GetUserAccessTokens(c.Params.Page, c.Params.PerPage)
  2303  	if err != nil {
  2304  		c.Err = err
  2305  		return
  2306  	}
  2307  
  2308  	w.Write([]byte(model.UserAccessTokenListToJson(accessTokens)))
  2309  }
  2310  
  2311  func getUserAccessTokensForUser(c *Context, w http.ResponseWriter, r *http.Request) {
  2312  	c.RequireUserId()
  2313  	if c.Err != nil {
  2314  		return
  2315  	}
  2316  
  2317  	if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PERMISSION_READ_USER_ACCESS_TOKEN) {
  2318  		c.SetPermissionError(model.PERMISSION_READ_USER_ACCESS_TOKEN)
  2319  		return
  2320  	}
  2321  
  2322  	if !c.App.SessionHasPermissionToUserOrBot(*c.AppContext.Session(), c.Params.UserId) {
  2323  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
  2324  		return
  2325  	}
  2326  
  2327  	accessTokens, err := c.App.GetUserAccessTokensForUser(c.Params.UserId, c.Params.Page, c.Params.PerPage)
  2328  	if err != nil {
  2329  		c.Err = err
  2330  		return
  2331  	}
  2332  
  2333  	w.Write([]byte(model.UserAccessTokenListToJson(accessTokens)))
  2334  }
  2335  
  2336  func getUserAccessToken(c *Context, w http.ResponseWriter, r *http.Request) {
  2337  	c.RequireTokenId()
  2338  	if c.Err != nil {
  2339  		return
  2340  	}
  2341  
  2342  	if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PERMISSION_READ_USER_ACCESS_TOKEN) {
  2343  		c.SetPermissionError(model.PERMISSION_READ_USER_ACCESS_TOKEN)
  2344  		return
  2345  	}
  2346  
  2347  	accessToken, err := c.App.GetUserAccessToken(c.Params.TokenId, true)
  2348  	if err != nil {
  2349  		c.Err = err
  2350  		return
  2351  	}
  2352  
  2353  	if !c.App.SessionHasPermissionToUserOrBot(*c.AppContext.Session(), accessToken.UserId) {
  2354  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
  2355  		return
  2356  	}
  2357  
  2358  	w.Write([]byte(accessToken.ToJson()))
  2359  }
  2360  
  2361  func revokeUserAccessToken(c *Context, w http.ResponseWriter, r *http.Request) {
  2362  	props := model.MapFromJson(r.Body)
  2363  
  2364  	tokenId := props["token_id"]
  2365  	if tokenId == "" {
  2366  		c.SetInvalidParam("token_id")
  2367  	}
  2368  
  2369  	auditRec := c.MakeAuditRecord("revokeUserAccessToken", audit.Fail)
  2370  	defer c.LogAuditRec(auditRec)
  2371  	auditRec.AddMeta("token_id", tokenId)
  2372  	c.LogAudit("")
  2373  
  2374  	if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PERMISSION_REVOKE_USER_ACCESS_TOKEN) {
  2375  		c.SetPermissionError(model.PERMISSION_REVOKE_USER_ACCESS_TOKEN)
  2376  		return
  2377  	}
  2378  
  2379  	accessToken, err := c.App.GetUserAccessToken(tokenId, false)
  2380  	if err != nil {
  2381  		c.Err = err
  2382  		return
  2383  	}
  2384  
  2385  	if user, errGet := c.App.GetUser(accessToken.UserId); errGet == nil {
  2386  		auditRec.AddMeta("user", user)
  2387  	}
  2388  
  2389  	if !c.App.SessionHasPermissionToUserOrBot(*c.AppContext.Session(), accessToken.UserId) {
  2390  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
  2391  		return
  2392  	}
  2393  
  2394  	if err = c.App.RevokeUserAccessToken(accessToken); err != nil {
  2395  		c.Err = err
  2396  		return
  2397  	}
  2398  
  2399  	auditRec.Success()
  2400  	c.LogAudit("success - token_id=" + accessToken.Id)
  2401  
  2402  	ReturnStatusOK(w)
  2403  }
  2404  
  2405  func disableUserAccessToken(c *Context, w http.ResponseWriter, r *http.Request) {
  2406  	props := model.MapFromJson(r.Body)
  2407  	tokenId := props["token_id"]
  2408  
  2409  	if tokenId == "" {
  2410  		c.SetInvalidParam("token_id")
  2411  	}
  2412  
  2413  	auditRec := c.MakeAuditRecord("disableUserAccessToken", audit.Fail)
  2414  	defer c.LogAuditRec(auditRec)
  2415  	auditRec.AddMeta("token_id", tokenId)
  2416  	c.LogAudit("")
  2417  
  2418  	// No separate permission for this action for now
  2419  	if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PERMISSION_REVOKE_USER_ACCESS_TOKEN) {
  2420  		c.SetPermissionError(model.PERMISSION_REVOKE_USER_ACCESS_TOKEN)
  2421  		return
  2422  	}
  2423  
  2424  	accessToken, err := c.App.GetUserAccessToken(tokenId, false)
  2425  	if err != nil {
  2426  		c.Err = err
  2427  		return
  2428  	}
  2429  
  2430  	if user, errGet := c.App.GetUser(accessToken.UserId); errGet == nil {
  2431  		auditRec.AddMeta("user", user)
  2432  	}
  2433  
  2434  	if !c.App.SessionHasPermissionToUserOrBot(*c.AppContext.Session(), accessToken.UserId) {
  2435  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
  2436  		return
  2437  	}
  2438  
  2439  	if err = c.App.DisableUserAccessToken(accessToken); err != nil {
  2440  		c.Err = err
  2441  		return
  2442  	}
  2443  
  2444  	auditRec.Success()
  2445  	c.LogAudit("success - token_id=" + accessToken.Id)
  2446  
  2447  	ReturnStatusOK(w)
  2448  }
  2449  
  2450  func enableUserAccessToken(c *Context, w http.ResponseWriter, r *http.Request) {
  2451  	props := model.MapFromJson(r.Body)
  2452  
  2453  	tokenId := props["token_id"]
  2454  	if tokenId == "" {
  2455  		c.SetInvalidParam("token_id")
  2456  	}
  2457  
  2458  	auditRec := c.MakeAuditRecord("enableUserAccessToken", audit.Fail)
  2459  	defer c.LogAuditRec(auditRec)
  2460  	auditRec.AddMeta("token_id", tokenId)
  2461  	c.LogAudit("")
  2462  
  2463  	// No separate permission for this action for now
  2464  	if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PERMISSION_CREATE_USER_ACCESS_TOKEN) {
  2465  		c.SetPermissionError(model.PERMISSION_CREATE_USER_ACCESS_TOKEN)
  2466  		return
  2467  	}
  2468  
  2469  	accessToken, err := c.App.GetUserAccessToken(tokenId, false)
  2470  	if err != nil {
  2471  		c.Err = err
  2472  		return
  2473  	}
  2474  
  2475  	if user, errGet := c.App.GetUser(accessToken.UserId); errGet == nil {
  2476  		auditRec.AddMeta("user", user)
  2477  	}
  2478  
  2479  	if !c.App.SessionHasPermissionToUserOrBot(*c.AppContext.Session(), accessToken.UserId) {
  2480  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
  2481  		return
  2482  	}
  2483  
  2484  	if err = c.App.EnableUserAccessToken(accessToken); err != nil {
  2485  		c.Err = err
  2486  		return
  2487  	}
  2488  
  2489  	auditRec.Success()
  2490  	c.LogAudit("success - token_id=" + accessToken.Id)
  2491  
  2492  	ReturnStatusOK(w)
  2493  }
  2494  
  2495  func saveUserTermsOfService(c *Context, w http.ResponseWriter, r *http.Request) {
  2496  	props := model.StringInterfaceFromJson(r.Body)
  2497  
  2498  	userId := c.AppContext.Session().UserId
  2499  	termsOfServiceId, ok := props["termsOfServiceId"].(string)
  2500  	if !ok {
  2501  		c.SetInvalidParam("termsOfServiceId")
  2502  		return
  2503  	}
  2504  	accepted, ok := props["accepted"].(bool)
  2505  	if !ok {
  2506  		c.SetInvalidParam("accepted")
  2507  		return
  2508  	}
  2509  
  2510  	auditRec := c.MakeAuditRecord("saveUserTermsOfService", audit.Fail)
  2511  	defer c.LogAuditRec(auditRec)
  2512  	auditRec.AddMeta("terms_id", termsOfServiceId)
  2513  	auditRec.AddMeta("accepted", accepted)
  2514  
  2515  	if user, err := c.App.GetUser(userId); err == nil {
  2516  		auditRec.AddMeta("user", user)
  2517  	}
  2518  
  2519  	if _, err := c.App.GetTermsOfService(termsOfServiceId); err != nil {
  2520  		c.Err = err
  2521  		return
  2522  	}
  2523  
  2524  	if err := c.App.SaveUserTermsOfService(userId, termsOfServiceId, accepted); err != nil {
  2525  		c.Err = err
  2526  		return
  2527  	}
  2528  
  2529  	auditRec.Success()
  2530  	c.LogAudit("TermsOfServiceId=" + termsOfServiceId + ", accepted=" + strconv.FormatBool(accepted))
  2531  
  2532  	ReturnStatusOK(w)
  2533  }
  2534  
  2535  func getUserTermsOfService(c *Context, w http.ResponseWriter, r *http.Request) {
  2536  	userId := c.AppContext.Session().UserId
  2537  	result, err := c.App.GetUserTermsOfService(userId)
  2538  	if err != nil {
  2539  		c.Err = err
  2540  		return
  2541  	}
  2542  	w.Write([]byte(result.ToJson()))
  2543  }
  2544  
  2545  func promoteGuestToUser(c *Context, w http.ResponseWriter, r *http.Request) {
  2546  	c.RequireUserId()
  2547  	if c.Err != nil {
  2548  		return
  2549  	}
  2550  
  2551  	auditRec := c.MakeAuditRecord("promoteGuestToUser", audit.Fail)
  2552  	defer c.LogAuditRec(auditRec)
  2553  
  2554  	if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PERMISSION_PROMOTE_GUEST) {
  2555  		c.SetPermissionError(model.PERMISSION_PROMOTE_GUEST)
  2556  		return
  2557  	}
  2558  
  2559  	user, err := c.App.GetUser(c.Params.UserId)
  2560  	if err != nil {
  2561  		c.Err = err
  2562  		return
  2563  	}
  2564  	auditRec.AddMeta("user", user)
  2565  
  2566  	if !user.IsGuest() {
  2567  		c.Err = model.NewAppError("Api4.promoteGuestToUser", "api.user.promote_guest_to_user.no_guest.app_error", nil, "", http.StatusNotImplemented)
  2568  		return
  2569  	}
  2570  
  2571  	if err := c.App.PromoteGuestToUser(c.AppContext, user, c.AppContext.Session().UserId); err != nil {
  2572  		c.Err = err
  2573  		return
  2574  	}
  2575  
  2576  	auditRec.Success()
  2577  	ReturnStatusOK(w)
  2578  }
  2579  
  2580  func demoteUserToGuest(c *Context, w http.ResponseWriter, r *http.Request) {
  2581  	c.RequireUserId()
  2582  	if c.Err != nil {
  2583  		return
  2584  	}
  2585  
  2586  	if c.App.Srv().License() == nil {
  2587  		c.Err = model.NewAppError("Api4.demoteUserToGuest", "api.team.demote_user_to_guest.license.error", nil, "", http.StatusNotImplemented)
  2588  		return
  2589  	}
  2590  
  2591  	if !*c.App.Config().GuestAccountsSettings.Enable {
  2592  		c.Err = model.NewAppError("Api4.demoteUserToGuest", "api.team.demote_user_to_guest.disabled.error", nil, "", http.StatusNotImplemented)
  2593  		return
  2594  	}
  2595  
  2596  	auditRec := c.MakeAuditRecord("demoteUserToGuest", audit.Fail)
  2597  	defer c.LogAuditRec(auditRec)
  2598  
  2599  	if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PERMISSION_DEMOTE_TO_GUEST) {
  2600  		c.SetPermissionError(model.PERMISSION_DEMOTE_TO_GUEST)
  2601  		return
  2602  	}
  2603  
  2604  	user, err := c.App.GetUser(c.Params.UserId)
  2605  	if err != nil {
  2606  		c.Err = err
  2607  		return
  2608  	}
  2609  
  2610  	if user.IsSystemAdmin() && !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PERMISSION_MANAGE_SYSTEM) {
  2611  		c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
  2612  		return
  2613  	}
  2614  
  2615  	auditRec.AddMeta("user", user)
  2616  
  2617  	if user.IsGuest() {
  2618  		c.Err = model.NewAppError("Api4.demoteUserToGuest", "api.user.demote_user_to_guest.already_guest.app_error", nil, "", http.StatusNotImplemented)
  2619  		return
  2620  	}
  2621  
  2622  	if err := c.App.DemoteUserToGuest(user); err != nil {
  2623  		c.Err = err
  2624  		return
  2625  	}
  2626  
  2627  	auditRec.Success()
  2628  	ReturnStatusOK(w)
  2629  }
  2630  
  2631  func publishUserTyping(c *Context, w http.ResponseWriter, r *http.Request) {
  2632  	c.RequireUserId()
  2633  	if c.Err != nil {
  2634  		return
  2635  	}
  2636  
  2637  	typingRequest := model.TypingRequestFromJson(r.Body)
  2638  	if typingRequest == nil {
  2639  		c.SetInvalidParam("typing_request")
  2640  		return
  2641  	}
  2642  
  2643  	if c.Params.UserId != c.AppContext.Session().UserId && !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PERMISSION_MANAGE_SYSTEM) {
  2644  		c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
  2645  		return
  2646  	}
  2647  
  2648  	if !c.App.HasPermissionToChannel(c.Params.UserId, typingRequest.ChannelId, model.PERMISSION_CREATE_POST) {
  2649  		c.SetPermissionError(model.PERMISSION_CREATE_POST)
  2650  		return
  2651  	}
  2652  
  2653  	if err := c.App.PublishUserTyping(c.Params.UserId, typingRequest.ChannelId, typingRequest.ParentId); err != nil {
  2654  		c.Err = err
  2655  		return
  2656  	}
  2657  
  2658  	ReturnStatusOK(w)
  2659  }
  2660  
  2661  func verifyUserEmailWithoutToken(c *Context, w http.ResponseWriter, r *http.Request) {
  2662  	c.RequireUserId()
  2663  	if c.Err != nil {
  2664  		return
  2665  	}
  2666  
  2667  	user, err := c.App.GetUser(c.Params.UserId)
  2668  	if err != nil {
  2669  		c.Err = err
  2670  		return
  2671  	}
  2672  
  2673  	auditRec := c.MakeAuditRecord("verifyUserEmailWithoutToken", audit.Fail)
  2674  	defer c.LogAuditRec(auditRec)
  2675  	auditRec.AddMeta("user_id", user.Id)
  2676  
  2677  	if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PERMISSION_MANAGE_SYSTEM) {
  2678  		c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
  2679  		return
  2680  	}
  2681  
  2682  	if err := c.App.VerifyUserEmail(user.Id, user.Email); err != nil {
  2683  		c.Err = err
  2684  		return
  2685  	}
  2686  
  2687  	auditRec.Success()
  2688  	c.LogAudit("user verified")
  2689  
  2690  	w.Write([]byte(user.ToJson()))
  2691  }
  2692  
  2693  func convertUserToBot(c *Context, w http.ResponseWriter, r *http.Request) {
  2694  	c.RequireUserId()
  2695  	if c.Err != nil {
  2696  		return
  2697  	}
  2698  
  2699  	user, err := c.App.GetUser(c.Params.UserId)
  2700  	if err != nil {
  2701  		c.Err = err
  2702  		return
  2703  	}
  2704  
  2705  	auditRec := c.MakeAuditRecord("convertUserToBot", audit.Fail)
  2706  	defer c.LogAuditRec(auditRec)
  2707  	auditRec.AddMeta("user", user)
  2708  
  2709  	if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PERMISSION_MANAGE_SYSTEM) {
  2710  		c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
  2711  		return
  2712  	}
  2713  
  2714  	bot, err := c.App.ConvertUserToBot(user)
  2715  	if err != nil {
  2716  		c.Err = err
  2717  		return
  2718  	}
  2719  
  2720  	auditRec.Success()
  2721  	auditRec.AddMeta("convertedTo", bot)
  2722  
  2723  	w.Write(bot.ToJson())
  2724  }
  2725  
  2726  func getUploadsForUser(c *Context, w http.ResponseWriter, r *http.Request) {
  2727  	c.RequireUserId()
  2728  	if c.Err != nil {
  2729  		return
  2730  	}
  2731  
  2732  	if c.Params.UserId != c.AppContext.Session().UserId {
  2733  		c.Err = model.NewAppError("getUploadsForUser", "api.user.get_uploads_for_user.forbidden.app_error", nil, "", http.StatusForbidden)
  2734  		return
  2735  	}
  2736  
  2737  	uss, err := c.App.GetUploadSessionsForUser(c.Params.UserId)
  2738  	if err != nil {
  2739  		c.Err = err
  2740  		return
  2741  	}
  2742  
  2743  	w.Write([]byte(model.UploadSessionsToJson(uss)))
  2744  }
  2745  
  2746  func migrateAuthToLDAP(c *Context, w http.ResponseWriter, r *http.Request) {
  2747  	props := model.StringInterfaceFromJson(r.Body)
  2748  	from, ok := props["from"].(string)
  2749  	if !ok {
  2750  		c.SetInvalidParam("from")
  2751  		return
  2752  	}
  2753  	if from == "" || (from != "email" && from != "gitlab" && from != "saml" && from != "google" && from != "office365") {
  2754  		c.SetInvalidParam("from")
  2755  		return
  2756  	}
  2757  
  2758  	force, ok := props["force"].(bool)
  2759  	if !ok {
  2760  		c.SetInvalidParam("force")
  2761  		return
  2762  	}
  2763  
  2764  	matchField, ok := props["match_field"].(string)
  2765  	if !ok {
  2766  		c.SetInvalidParam("match_field")
  2767  		return
  2768  	}
  2769  
  2770  	auditRec := c.MakeAuditRecord("migrateAuthToLdap", audit.Fail)
  2771  	defer c.LogAuditRec(auditRec)
  2772  	auditRec.AddMeta("from", from)
  2773  	auditRec.AddMeta("match_field", matchField)
  2774  	auditRec.AddMeta("force", force)
  2775  
  2776  	if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PERMISSION_MANAGE_SYSTEM) {
  2777  		c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
  2778  		return
  2779  	}
  2780  
  2781  	if c.App.Srv().License() == nil || !*c.App.Srv().License().Features.LDAP {
  2782  		c.Err = model.NewAppError("api.migrateAuthToLDAP", "api.admin.ldap.not_available.app_error", nil, "", http.StatusNotImplemented)
  2783  		return
  2784  	}
  2785  
  2786  	// Email auth in Mattermost system is represented by ""
  2787  	if from == "email" {
  2788  		from = ""
  2789  	}
  2790  
  2791  	if migrate := c.App.AccountMigration(); migrate != nil {
  2792  		if err := migrate.MigrateToLdap(from, matchField, force, false); err != nil {
  2793  			c.Err = model.NewAppError("api.migrateAuthToLdap", "api.migrate_to_saml.error", nil, err.Error(), http.StatusInternalServerError)
  2794  			return
  2795  		}
  2796  	} else {
  2797  		c.Err = model.NewAppError("api.migrateAuthToLdap", "api.admin.ldap.not_available.app_error", nil, "", http.StatusNotImplemented)
  2798  		return
  2799  	}
  2800  
  2801  	auditRec.Success()
  2802  	ReturnStatusOK(w)
  2803  }
  2804  
  2805  func migrateAuthToSaml(c *Context, w http.ResponseWriter, r *http.Request) {
  2806  	props := model.StringInterfaceFromJson(r.Body)
  2807  	from, ok := props["from"].(string)
  2808  	if !ok {
  2809  		c.SetInvalidParam("from")
  2810  		return
  2811  	}
  2812  	if from == "" || (from != "email" && from != "gitlab" && from != "ldap" && from != "google" && from != "office365") {
  2813  		c.SetInvalidParam("from")
  2814  		return
  2815  	}
  2816  
  2817  	auto, ok := props["auto"].(bool)
  2818  	if !ok {
  2819  		c.SetInvalidParam("auto")
  2820  		return
  2821  	}
  2822  	matches, ok := props["matches"].(map[string]interface{})
  2823  	if !ok {
  2824  		c.SetInvalidParam("matches")
  2825  		return
  2826  	}
  2827  	usersMap := model.MapFromJson(strings.NewReader(model.StringInterfaceToJson(matches)))
  2828  
  2829  	auditRec := c.MakeAuditRecord("migrateAuthToSaml", audit.Fail)
  2830  	defer c.LogAuditRec(auditRec)
  2831  	auditRec.AddMeta("from", from)
  2832  	auditRec.AddMeta("matches", matches)
  2833  	auditRec.AddMeta("auto", auto)
  2834  
  2835  	if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PERMISSION_MANAGE_SYSTEM) {
  2836  		c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
  2837  		return
  2838  	}
  2839  
  2840  	if c.App.Srv().License() == nil || !*c.App.Srv().License().Features.SAML {
  2841  		c.Err = model.NewAppError("api.migrateAuthToSaml", "api.admin.saml.not_available.app_error", nil, "", http.StatusNotImplemented)
  2842  		return
  2843  	}
  2844  
  2845  	// Email auth in Mattermost system is represented by ""
  2846  	if from == "email" {
  2847  		from = ""
  2848  	}
  2849  
  2850  	if migrate := c.App.AccountMigration(); migrate != nil {
  2851  		if err := migrate.MigrateToSaml(from, usersMap, auto, false); err != nil {
  2852  			c.Err = model.NewAppError("api.migrateAuthToSaml", "api.migrate_to_saml.error", nil, err.Error(), http.StatusInternalServerError)
  2853  			return
  2854  		}
  2855  	} else {
  2856  		c.Err = model.NewAppError("api.migrateAuthToSaml", "api.admin.saml.not_available.app_error", nil, "", http.StatusNotImplemented)
  2857  		return
  2858  	}
  2859  
  2860  	auditRec.Success()
  2861  	ReturnStatusOK(w)
  2862  }
  2863  
  2864  func getThreadForUser(c *Context, w http.ResponseWriter, r *http.Request) {
  2865  	c.RequireUserId().RequireTeamId().RequireThreadId()
  2866  	if c.Err != nil {
  2867  		return
  2868  	}
  2869  	if !c.App.SessionHasPermissionToUser(*c.AppContext.Session(), c.Params.UserId) {
  2870  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
  2871  		return
  2872  	}
  2873  	extendedStr := r.URL.Query().Get("extended")
  2874  	extended, _ := strconv.ParseBool(extendedStr)
  2875  
  2876  	threadMembership, err := c.App.GetThreadMembershipForUser(c.Params.UserId, c.Params.ThreadId)
  2877  	if err != nil {
  2878  		c.Err = err
  2879  		return
  2880  	}
  2881  
  2882  	thread, err := c.App.GetThreadForUser(c.Params.TeamId, threadMembership, extended)
  2883  	if err != nil {
  2884  		c.Err = err
  2885  		return
  2886  	}
  2887  
  2888  	w.Write([]byte(thread.ToJson()))
  2889  }
  2890  
  2891  func getThreadsForUser(c *Context, w http.ResponseWriter, r *http.Request) {
  2892  	c.RequireUserId().RequireTeamId()
  2893  	if c.Err != nil {
  2894  		return
  2895  	}
  2896  
  2897  	if !c.App.SessionHasPermissionToUser(*c.AppContext.Session(), c.Params.UserId) {
  2898  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
  2899  		return
  2900  	}
  2901  
  2902  	options := model.GetUserThreadsOpts{
  2903  		Since:    0,
  2904  		Before:   "",
  2905  		After:    "",
  2906  		PageSize: 30,
  2907  		Unread:   false,
  2908  		Extended: false,
  2909  		Deleted:  false,
  2910  	}
  2911  
  2912  	sinceString := r.URL.Query().Get("since")
  2913  	if sinceString != "" {
  2914  		since, parseError := strconv.ParseUint(sinceString, 10, 64)
  2915  		if parseError != nil {
  2916  			c.SetInvalidParam("since")
  2917  			return
  2918  		}
  2919  		options.Since = since
  2920  	}
  2921  
  2922  	options.Before = r.URL.Query().Get("before")
  2923  	options.After = r.URL.Query().Get("after")
  2924  	// parameters are mutually exclusive
  2925  	if options.Before != "" && options.After != "" {
  2926  		c.Err = model.NewAppError("api.getThreadsForUser", "api.getThreadsForUser.bad_params", nil, "", http.StatusBadRequest)
  2927  		return
  2928  	}
  2929  	pageSizeString := r.URL.Query().Get("pageSize")
  2930  	if pageSizeString != "" {
  2931  		pageSize, parseError := strconv.ParseUint(pageSizeString, 10, 64)
  2932  		if parseError != nil {
  2933  			c.SetInvalidParam("pageSize")
  2934  			return
  2935  		}
  2936  		options.PageSize = pageSize
  2937  	}
  2938  
  2939  	deletedStr := r.URL.Query().Get("deleted")
  2940  	unreadStr := r.URL.Query().Get("unread")
  2941  	extendedStr := r.URL.Query().Get("extended")
  2942  
  2943  	options.Deleted, _ = strconv.ParseBool(deletedStr)
  2944  	options.Unread, _ = strconv.ParseBool(unreadStr)
  2945  	options.Extended, _ = strconv.ParseBool(extendedStr)
  2946  
  2947  	threads, err := c.App.GetThreadsForUser(c.Params.UserId, c.Params.TeamId, options)
  2948  	if err != nil {
  2949  		c.Err = err
  2950  		return
  2951  	}
  2952  
  2953  	w.Write([]byte(threads.ToJson()))
  2954  }
  2955  
  2956  func updateReadStateThreadByUser(c *Context, w http.ResponseWriter, r *http.Request) {
  2957  	c.RequireUserId().RequireThreadId().RequireTimestamp().RequireTeamId()
  2958  	if c.Err != nil {
  2959  		return
  2960  	}
  2961  
  2962  	auditRec := c.MakeAuditRecord("updateReadStateThreadByUser", audit.Fail)
  2963  	defer c.LogAuditRec(auditRec)
  2964  	auditRec.AddMeta("user_id", c.Params.UserId)
  2965  	auditRec.AddMeta("thread_id", c.Params.ThreadId)
  2966  	auditRec.AddMeta("team_id", c.Params.TeamId)
  2967  	auditRec.AddMeta("timestamp", c.Params.Timestamp)
  2968  	if !c.App.SessionHasPermissionToUser(*c.AppContext.Session(), c.Params.UserId) {
  2969  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
  2970  		return
  2971  	}
  2972  
  2973  	thread, err := c.App.UpdateThreadReadForUser(c.Params.UserId, c.Params.TeamId, c.Params.ThreadId, c.Params.Timestamp)
  2974  	if err != nil {
  2975  		c.Err = err
  2976  		return
  2977  	}
  2978  
  2979  	w.Write([]byte(thread.ToJson()))
  2980  
  2981  	auditRec.Success()
  2982  }
  2983  
  2984  func unfollowThreadByUser(c *Context, w http.ResponseWriter, r *http.Request) {
  2985  	c.RequireUserId().RequireThreadId().RequireTeamId()
  2986  	if c.Err != nil {
  2987  		return
  2988  	}
  2989  
  2990  	auditRec := c.MakeAuditRecord("unfollowThreadByUser", audit.Fail)
  2991  	defer c.LogAuditRec(auditRec)
  2992  	auditRec.AddMeta("user_id", c.Params.UserId)
  2993  	auditRec.AddMeta("thread_id", c.Params.ThreadId)
  2994  	auditRec.AddMeta("team_id", c.Params.TeamId)
  2995  
  2996  	if !c.App.SessionHasPermissionToUser(*c.AppContext.Session(), c.Params.UserId) {
  2997  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
  2998  		return
  2999  	}
  3000  
  3001  	err := c.App.UpdateThreadFollowForUser(c.Params.UserId, c.Params.TeamId, c.Params.ThreadId, false)
  3002  	if err != nil {
  3003  		c.Err = err
  3004  		return
  3005  	}
  3006  
  3007  	ReturnStatusOK(w)
  3008  
  3009  	auditRec.Success()
  3010  }
  3011  
  3012  func followThreadByUser(c *Context, w http.ResponseWriter, r *http.Request) {
  3013  	c.RequireUserId().RequireThreadId().RequireTeamId()
  3014  	if c.Err != nil {
  3015  		return
  3016  	}
  3017  
  3018  	auditRec := c.MakeAuditRecord("followThreadByUser", audit.Fail)
  3019  	defer c.LogAuditRec(auditRec)
  3020  	auditRec.AddMeta("user_id", c.Params.UserId)
  3021  	auditRec.AddMeta("thread_id", c.Params.ThreadId)
  3022  	auditRec.AddMeta("team_id", c.Params.TeamId)
  3023  
  3024  	if !c.App.SessionHasPermissionToUser(*c.AppContext.Session(), c.Params.UserId) {
  3025  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
  3026  		return
  3027  	}
  3028  
  3029  	err := c.App.UpdateThreadFollowForUser(c.Params.UserId, c.Params.TeamId, c.Params.ThreadId, true)
  3030  	if err != nil {
  3031  		c.Err = err
  3032  		return
  3033  	}
  3034  
  3035  	ReturnStatusOK(w)
  3036  	auditRec.Success()
  3037  }
  3038  
  3039  func updateReadStateAllThreadsByUser(c *Context, w http.ResponseWriter, r *http.Request) {
  3040  	c.RequireUserId().RequireTeamId()
  3041  	if c.Err != nil {
  3042  		return
  3043  	}
  3044  
  3045  	auditRec := c.MakeAuditRecord("updateReadStateAllThreadsByUser", audit.Fail)
  3046  	defer c.LogAuditRec(auditRec)
  3047  	auditRec.AddMeta("user_id", c.Params.UserId)
  3048  	auditRec.AddMeta("team_id", c.Params.TeamId)
  3049  
  3050  	if !c.App.SessionHasPermissionToUser(*c.AppContext.Session(), c.Params.UserId) {
  3051  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
  3052  		return
  3053  	}
  3054  
  3055  	err := c.App.UpdateThreadsReadForUser(c.Params.UserId, c.Params.TeamId)
  3056  	if err != nil {
  3057  		c.Err = err
  3058  		return
  3059  	}
  3060  
  3061  	ReturnStatusOK(w)
  3062  	auditRec.Success()
  3063  }