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