github.com/nhannv/mattermost-server@v5.11.1+incompatible/api4/user.go (about)

     1  // Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
     2  // See License.txt for license information.
     3  
     4  package api4
     5  
     6  import (
     7  	"fmt"
     8  	"io"
     9  	"io/ioutil"
    10  	"net/http"
    11  	"strconv"
    12  	"time"
    13  
    14  	"github.com/mattermost/mattermost-server/app"
    15  	"github.com/mattermost/mattermost-server/mlog"
    16  	"github.com/mattermost/mattermost-server/model"
    17  )
    18  
    19  func (api *API) InitUser() {
    20  	api.BaseRoutes.Users.Handle("", api.ApiHandler(createUser)).Methods("POST")
    21  	api.BaseRoutes.Users.Handle("", api.ApiSessionRequired(getUsers)).Methods("GET")
    22  	api.BaseRoutes.Users.Handle("/ids", api.ApiSessionRequired(getUsersByIds)).Methods("POST")
    23  	api.BaseRoutes.Users.Handle("/usernames", api.ApiSessionRequired(getUsersByNames)).Methods("POST")
    24  	api.BaseRoutes.Users.Handle("/search", api.ApiSessionRequired(searchUsers)).Methods("POST")
    25  	api.BaseRoutes.Users.Handle("/autocomplete", api.ApiSessionRequired(autocompleteUsers)).Methods("GET")
    26  	api.BaseRoutes.Users.Handle("/stats", api.ApiSessionRequired(getTotalUsersStats)).Methods("GET")
    27  
    28  	api.BaseRoutes.User.Handle("", api.ApiSessionRequired(getUser)).Methods("GET")
    29  	api.BaseRoutes.User.Handle("/image/default", api.ApiSessionRequiredTrustRequester(getDefaultProfileImage)).Methods("GET")
    30  	api.BaseRoutes.User.Handle("/image", api.ApiSessionRequiredTrustRequester(getProfileImage)).Methods("GET")
    31  	api.BaseRoutes.User.Handle("/image", api.ApiSessionRequired(setProfileImage)).Methods("POST")
    32  	api.BaseRoutes.User.Handle("/image", api.ApiSessionRequired(setDefaultProfileImage)).Methods("DELETE")
    33  	api.BaseRoutes.User.Handle("", api.ApiSessionRequired(updateUser)).Methods("PUT")
    34  	api.BaseRoutes.User.Handle("/patch", api.ApiSessionRequired(patchUser)).Methods("PUT")
    35  	api.BaseRoutes.User.Handle("", api.ApiSessionRequired(deleteUser)).Methods("DELETE")
    36  	api.BaseRoutes.User.Handle("/roles", api.ApiSessionRequired(updateUserRoles)).Methods("PUT")
    37  	api.BaseRoutes.User.Handle("/active", api.ApiSessionRequired(updateUserActive)).Methods("PUT")
    38  	api.BaseRoutes.User.Handle("/password", api.ApiSessionRequired(updatePassword)).Methods("PUT")
    39  	api.BaseRoutes.Users.Handle("/password/reset", api.ApiHandler(resetPassword)).Methods("POST")
    40  	api.BaseRoutes.Users.Handle("/password/reset/send", api.ApiHandler(sendPasswordReset)).Methods("POST")
    41  	api.BaseRoutes.Users.Handle("/email/verify", api.ApiHandler(verifyUserEmail)).Methods("POST")
    42  	api.BaseRoutes.Users.Handle("/email/verify/send", api.ApiHandler(sendVerificationEmail)).Methods("POST")
    43  	api.BaseRoutes.User.Handle("/terms_of_service", api.ApiSessionRequired(saveUserTermsOfService)).Methods("POST")
    44  	api.BaseRoutes.User.Handle("/terms_of_service", api.ApiSessionRequired(getUserTermsOfService)).Methods("GET")
    45  
    46  	api.BaseRoutes.User.Handle("/auth", api.ApiSessionRequiredTrustRequester(updateUserAuth)).Methods("PUT")
    47  
    48  	api.BaseRoutes.Users.Handle("/mfa", api.ApiHandler(checkUserMfa)).Methods("POST")
    49  	api.BaseRoutes.User.Handle("/mfa", api.ApiSessionRequiredMfa(updateUserMfa)).Methods("PUT")
    50  	api.BaseRoutes.User.Handle("/mfa/generate", api.ApiSessionRequiredMfa(generateMfaSecret)).Methods("POST")
    51  
    52  	api.BaseRoutes.Users.Handle("/login", api.ApiHandler(login)).Methods("POST")
    53  	api.BaseRoutes.Users.Handle("/login/switch", api.ApiHandler(switchAccountType)).Methods("POST")
    54  	api.BaseRoutes.Users.Handle("/logout", api.ApiHandler(logout)).Methods("POST")
    55  
    56  	api.BaseRoutes.UserByUsername.Handle("", api.ApiSessionRequired(getUserByUsername)).Methods("GET")
    57  	api.BaseRoutes.UserByEmail.Handle("", api.ApiSessionRequired(getUserByEmail)).Methods("GET")
    58  
    59  	api.BaseRoutes.User.Handle("/sessions", api.ApiSessionRequired(getSessions)).Methods("GET")
    60  	api.BaseRoutes.User.Handle("/sessions/revoke", api.ApiSessionRequired(revokeSession)).Methods("POST")
    61  	api.BaseRoutes.User.Handle("/sessions/revoke/all", api.ApiSessionRequired(revokeAllSessionsForUser)).Methods("POST")
    62  	api.BaseRoutes.Users.Handle("/sessions/device", api.ApiSessionRequired(attachDeviceId)).Methods("PUT")
    63  	api.BaseRoutes.User.Handle("/audits", api.ApiSessionRequired(getUserAudits)).Methods("GET")
    64  
    65  	api.BaseRoutes.User.Handle("/tokens", api.ApiSessionRequired(createUserAccessToken)).Methods("POST")
    66  	api.BaseRoutes.User.Handle("/tokens", api.ApiSessionRequired(getUserAccessTokensForUser)).Methods("GET")
    67  	api.BaseRoutes.Users.Handle("/tokens", api.ApiSessionRequired(getUserAccessTokens)).Methods("GET")
    68  	api.BaseRoutes.Users.Handle("/tokens/search", api.ApiSessionRequired(searchUserAccessTokens)).Methods("POST")
    69  	api.BaseRoutes.Users.Handle("/tokens/{token_id:[A-Za-z0-9]+}", api.ApiSessionRequired(getUserAccessToken)).Methods("GET")
    70  	api.BaseRoutes.Users.Handle("/tokens/revoke", api.ApiSessionRequired(revokeUserAccessToken)).Methods("POST")
    71  	api.BaseRoutes.Users.Handle("/tokens/disable", api.ApiSessionRequired(disableUserAccessToken)).Methods("POST")
    72  	api.BaseRoutes.Users.Handle("/tokens/enable", api.ApiSessionRequired(enableUserAccessToken)).Methods("POST")
    73  }
    74  
    75  func createUser(c *Context, w http.ResponseWriter, r *http.Request) {
    76  	user := model.UserFromJson(r.Body)
    77  	if user == nil {
    78  		c.SetInvalidParam("user")
    79  		return
    80  	}
    81  
    82  	tokenId := r.URL.Query().Get("t")
    83  	inviteId := r.URL.Query().Get("iid")
    84  
    85  	// No permission check required
    86  
    87  	var ruser *model.User
    88  	var err *model.AppError
    89  	if len(tokenId) > 0 {
    90  		ruser, err = c.App.CreateUserWithToken(user, tokenId)
    91  	} else if len(inviteId) > 0 {
    92  		ruser, err = c.App.CreateUserWithInviteId(user, inviteId)
    93  	} else if c.IsSystemAdmin() {
    94  		ruser, err = c.App.CreateUserAsAdmin(user)
    95  	} else {
    96  		ruser, err = c.App.CreateUserFromSignup(user)
    97  	}
    98  
    99  	if err != nil {
   100  		c.Err = err
   101  		return
   102  	}
   103  
   104  	w.WriteHeader(http.StatusCreated)
   105  	w.Write([]byte(ruser.ToJson()))
   106  }
   107  
   108  func getUser(c *Context, w http.ResponseWriter, r *http.Request) {
   109  	c.RequireUserId()
   110  	if c.Err != nil {
   111  		return
   112  	}
   113  
   114  	// No permission check required
   115  
   116  	user, err := c.App.GetUser(c.Params.UserId)
   117  	if err != nil {
   118  		c.Err = err
   119  		return
   120  	}
   121  
   122  	if c.IsSystemAdmin() || c.App.Session.UserId == user.Id {
   123  		userTermsOfService, err := c.App.GetUserTermsOfService(user.Id)
   124  		if err != nil && err.StatusCode != http.StatusNotFound {
   125  			c.Err = err
   126  			return
   127  		}
   128  
   129  		if userTermsOfService != nil {
   130  			user.TermsOfServiceId = userTermsOfService.TermsOfServiceId
   131  			user.TermsOfServiceCreateAt = userTermsOfService.CreateAt
   132  		}
   133  	}
   134  
   135  	etag := user.Etag(*c.App.Config().PrivacySettings.ShowFullName, *c.App.Config().PrivacySettings.ShowEmailAddress)
   136  
   137  	if c.HandleEtag(etag, "Get User", w, r) {
   138  		return
   139  	}
   140  
   141  	if c.App.Session.UserId == user.Id {
   142  		user.Sanitize(map[string]bool{})
   143  	} else {
   144  		c.App.SanitizeProfile(user, c.IsSystemAdmin())
   145  	}
   146  	c.App.UpdateLastActivityAtIfNeeded(c.App.Session)
   147  	w.Header().Set(model.HEADER_ETAG_SERVER, etag)
   148  	w.Write([]byte(user.ToJson()))
   149  }
   150  
   151  func getUserByUsername(c *Context, w http.ResponseWriter, r *http.Request) {
   152  	c.RequireUsername()
   153  	if c.Err != nil {
   154  		return
   155  	}
   156  
   157  	// No permission check required
   158  
   159  	user, err := c.App.GetUserByUsername(c.Params.Username)
   160  	if err != nil {
   161  		c.Err = err
   162  		return
   163  	}
   164  
   165  	if c.IsSystemAdmin() || c.App.Session.UserId == user.Id {
   166  		userTermsOfService, err := c.App.GetUserTermsOfService(user.Id)
   167  		if err != nil && err.StatusCode != http.StatusNotFound {
   168  			c.Err = err
   169  			return
   170  		}
   171  
   172  		if userTermsOfService != nil {
   173  			user.TermsOfServiceId = userTermsOfService.TermsOfServiceId
   174  			user.TermsOfServiceCreateAt = userTermsOfService.CreateAt
   175  		}
   176  	}
   177  
   178  	etag := user.Etag(*c.App.Config().PrivacySettings.ShowFullName, *c.App.Config().PrivacySettings.ShowEmailAddress)
   179  
   180  	if c.HandleEtag(etag, "Get User", w, r) {
   181  		return
   182  	}
   183  
   184  	if c.App.Session.UserId == user.Id {
   185  		user.Sanitize(map[string]bool{})
   186  	} else {
   187  		c.App.SanitizeProfile(user, c.IsSystemAdmin())
   188  	}
   189  	w.Header().Set(model.HEADER_ETAG_SERVER, etag)
   190  	w.Write([]byte(user.ToJson()))
   191  }
   192  
   193  func getUserByEmail(c *Context, w http.ResponseWriter, r *http.Request) {
   194  	c.RequireEmail()
   195  	if c.Err != nil {
   196  		return
   197  	}
   198  
   199  	// No permission check required, but still prevent users who can't see another user's email address from using this
   200  
   201  	sanitizeOptions := c.App.GetSanitizeOptions(c.IsSystemAdmin())
   202  	if !sanitizeOptions["email"] {
   203  		c.Err = model.NewAppError("getUserByEmail", "api.user.get_user_by_email.permissions.app_error", nil, "userId="+c.App.Session.UserId, http.StatusForbidden)
   204  		return
   205  	}
   206  
   207  	user, err := c.App.GetUserByEmail(c.Params.Email)
   208  	if err != nil {
   209  		c.Err = err
   210  		return
   211  	}
   212  
   213  	etag := user.Etag(*c.App.Config().PrivacySettings.ShowFullName, *c.App.Config().PrivacySettings.ShowEmailAddress)
   214  
   215  	if c.HandleEtag(etag, "Get User", w, r) {
   216  		return
   217  	}
   218  
   219  	c.App.SanitizeProfile(user, c.IsSystemAdmin())
   220  	w.Header().Set(model.HEADER_ETAG_SERVER, etag)
   221  	w.Write([]byte(user.ToJson()))
   222  }
   223  
   224  func getDefaultProfileImage(c *Context, w http.ResponseWriter, r *http.Request) {
   225  	c.RequireUserId()
   226  	if c.Err != nil {
   227  		return
   228  	}
   229  
   230  	users, err := c.App.GetUsersByIds([]string{c.Params.UserId}, c.IsSystemAdmin())
   231  	if err != nil {
   232  		c.Err = err
   233  		return
   234  	}
   235  
   236  	if len(users) == 0 {
   237  		c.Err = model.NewAppError("getProfileImage", "api.user.get_profile_image.not_found.app_error", nil, "", http.StatusNotFound)
   238  		return
   239  	}
   240  
   241  	user := users[0]
   242  	img, err := c.App.GetDefaultProfileImage(user)
   243  	if err != nil {
   244  		c.Err = err
   245  		return
   246  	}
   247  
   248  	w.Header().Set("Cache-Control", fmt.Sprintf("max-age=%v, public", 24*60*60)) // 24 hrs
   249  	w.Header().Set("Content-Type", "image/png")
   250  	w.Write(img)
   251  }
   252  
   253  func getProfileImage(c *Context, w http.ResponseWriter, r *http.Request) {
   254  	c.RequireUserId()
   255  	if c.Err != nil {
   256  		return
   257  	}
   258  
   259  	users, err := c.App.GetUsersByIds([]string{c.Params.UserId}, c.IsSystemAdmin())
   260  	if err != nil {
   261  		c.Err = err
   262  		return
   263  	}
   264  
   265  	if len(users) == 0 {
   266  		c.Err = model.NewAppError("getProfileImage", "api.user.get_profile_image.not_found.app_error", nil, "", http.StatusNotFound)
   267  		return
   268  	}
   269  
   270  	user := users[0]
   271  	etag := strconv.FormatInt(user.LastPictureUpdate, 10)
   272  	if c.HandleEtag(etag, "Get Profile Image", w, r) {
   273  		return
   274  	}
   275  
   276  	img, readFailed, err := c.App.GetProfileImage(user)
   277  	if err != nil {
   278  		c.Err = err
   279  		return
   280  	}
   281  
   282  	if readFailed {
   283  		w.Header().Set("Cache-Control", fmt.Sprintf("max-age=%v, public", 5*60)) // 5 mins
   284  	} else {
   285  		w.Header().Set("Cache-Control", fmt.Sprintf("max-age=%v, public", 24*60*60)) // 24 hrs
   286  		w.Header().Set(model.HEADER_ETAG_SERVER, etag)
   287  	}
   288  
   289  	w.Header().Set("Content-Type", "image/png")
   290  	w.Write(img)
   291  }
   292  
   293  func setProfileImage(c *Context, w http.ResponseWriter, r *http.Request) {
   294  	defer io.Copy(ioutil.Discard, r.Body)
   295  
   296  	c.RequireUserId()
   297  	if c.Err != nil {
   298  		return
   299  	}
   300  
   301  	if !c.App.SessionHasPermissionToUser(c.App.Session, c.Params.UserId) {
   302  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
   303  		return
   304  	}
   305  
   306  	if len(*c.App.Config().FileSettings.DriverName) == 0 {
   307  		c.Err = model.NewAppError("uploadProfileImage", "api.user.upload_profile_user.storage.app_error", nil, "", http.StatusNotImplemented)
   308  		return
   309  	}
   310  
   311  	if r.ContentLength > *c.App.Config().FileSettings.MaxFileSize {
   312  		c.Err = model.NewAppError("uploadProfileImage", "api.user.upload_profile_user.too_large.app_error", nil, "", http.StatusRequestEntityTooLarge)
   313  		return
   314  	}
   315  
   316  	if err := r.ParseMultipartForm(*c.App.Config().FileSettings.MaxFileSize); err != nil {
   317  		c.Err = model.NewAppError("uploadProfileImage", "api.user.upload_profile_user.parse.app_error", nil, err.Error(), http.StatusInternalServerError)
   318  		return
   319  	}
   320  
   321  	m := r.MultipartForm
   322  	imageArray, ok := m.File["image"]
   323  	if !ok {
   324  		c.Err = model.NewAppError("uploadProfileImage", "api.user.upload_profile_user.no_file.app_error", nil, "", http.StatusBadRequest)
   325  		return
   326  	}
   327  
   328  	if len(imageArray) <= 0 {
   329  		c.Err = model.NewAppError("uploadProfileImage", "api.user.upload_profile_user.array.app_error", nil, "", http.StatusBadRequest)
   330  		return
   331  	}
   332  
   333  	imageData := imageArray[0]
   334  	if err := c.App.SetProfileImage(c.Params.UserId, imageData); err != nil {
   335  		c.Err = err
   336  		return
   337  	}
   338  
   339  	c.LogAudit("")
   340  	ReturnStatusOK(w)
   341  }
   342  
   343  func setDefaultProfileImage(c *Context, w http.ResponseWriter, r *http.Request) {
   344  	c.RequireUserId()
   345  	if c.Err != nil {
   346  		return
   347  	}
   348  
   349  	if !c.App.SessionHasPermissionToUser(c.App.Session, c.Params.UserId) {
   350  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
   351  		return
   352  	}
   353  
   354  	if len(*c.App.Config().FileSettings.DriverName) == 0 {
   355  		c.Err = model.NewAppError("setDefaultProfileImage", "api.user.upload_profile_user.storage.app_error", nil, "", http.StatusNotImplemented)
   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  	if err := c.App.SetDefaultProfileImage(user); err != nil {
   366  		c.Err = err
   367  		return
   368  	}
   369  
   370  	c.LogAudit("")
   371  	ReturnStatusOK(w)
   372  }
   373  
   374  func getTotalUsersStats(c *Context, w http.ResponseWriter, r *http.Request) {
   375  	if c.Err != nil {
   376  		return
   377  	}
   378  
   379  	stats, err := c.App.GetTotalUsersStats()
   380  	if err != nil {
   381  		c.Err = err
   382  		return
   383  	}
   384  
   385  	w.Write([]byte(stats.ToJson()))
   386  }
   387  
   388  func getUsers(c *Context, w http.ResponseWriter, r *http.Request) {
   389  	inTeamId := r.URL.Query().Get("in_team")
   390  	notInTeamId := r.URL.Query().Get("not_in_team")
   391  	inChannelId := r.URL.Query().Get("in_channel")
   392  	notInChannelId := r.URL.Query().Get("not_in_channel")
   393  	withoutTeam := r.URL.Query().Get("without_team")
   394  	inactive := r.URL.Query().Get("inactive")
   395  	role := r.URL.Query().Get("role")
   396  	sort := r.URL.Query().Get("sort")
   397  
   398  	if len(notInChannelId) > 0 && len(inTeamId) == 0 {
   399  		c.SetInvalidUrlParam("team_id")
   400  		return
   401  	}
   402  
   403  	if sort != "" && sort != "last_activity_at" && sort != "create_at" && sort != "status" {
   404  		c.SetInvalidUrlParam("sort")
   405  		return
   406  	}
   407  
   408  	// Currently only supports sorting on a team
   409  	// or sort="status" on inChannelId
   410  	if (sort == "last_activity_at" || sort == "create_at") && (inTeamId == "" || notInTeamId != "" || inChannelId != "" || notInChannelId != "" || withoutTeam != "") {
   411  		c.SetInvalidUrlParam("sort")
   412  		return
   413  	}
   414  	if sort == "status" && inChannelId == "" {
   415  		c.SetInvalidUrlParam("sort")
   416  		return
   417  	}
   418  
   419  	withoutTeamBool, _ := strconv.ParseBool(withoutTeam)
   420  	inactiveBool, _ := strconv.ParseBool(inactive)
   421  
   422  	userGetOptions := &model.UserGetOptions{
   423  		InTeamId:       inTeamId,
   424  		InChannelId:    inChannelId,
   425  		NotInTeamId:    notInTeamId,
   426  		NotInChannelId: notInChannelId,
   427  		WithoutTeam:    withoutTeamBool,
   428  		Inactive:       inactiveBool,
   429  		Role:           role,
   430  		Sort:           sort,
   431  		Page:           c.Params.Page,
   432  		PerPage:        c.Params.PerPage,
   433  	}
   434  
   435  	var profiles []*model.User
   436  	var err *model.AppError
   437  	etag := ""
   438  
   439  	if withoutTeamBool, _ := strconv.ParseBool(withoutTeam); withoutTeamBool {
   440  		// Use a special permission for now
   441  		if !c.App.SessionHasPermissionTo(c.App.Session, model.PERMISSION_LIST_USERS_WITHOUT_TEAM) {
   442  			c.SetPermissionError(model.PERMISSION_LIST_USERS_WITHOUT_TEAM)
   443  			return
   444  		}
   445  
   446  		profiles, err = c.App.GetUsersWithoutTeamPage(c.Params.Page, c.Params.PerPage, c.IsSystemAdmin())
   447  	} else if len(notInChannelId) > 0 {
   448  		if !c.App.SessionHasPermissionToChannel(c.App.Session, notInChannelId, model.PERMISSION_READ_CHANNEL) {
   449  			c.SetPermissionError(model.PERMISSION_READ_CHANNEL)
   450  			return
   451  		}
   452  
   453  		profiles, err = c.App.GetUsersNotInChannelPage(inTeamId, notInChannelId, c.Params.Page, c.Params.PerPage, c.IsSystemAdmin())
   454  	} else if len(notInTeamId) > 0 {
   455  		if !c.App.SessionHasPermissionToTeam(c.App.Session, notInTeamId, model.PERMISSION_VIEW_TEAM) {
   456  			c.SetPermissionError(model.PERMISSION_VIEW_TEAM)
   457  			return
   458  		}
   459  
   460  		etag = c.App.GetUsersNotInTeamEtag(inTeamId)
   461  		if c.HandleEtag(etag, "Get Users Not in Team", w, r) {
   462  			return
   463  		}
   464  
   465  		profiles, err = c.App.GetUsersNotInTeamPage(notInTeamId, c.Params.Page, c.Params.PerPage, c.IsSystemAdmin())
   466  	} else if len(inTeamId) > 0 {
   467  		if !c.App.SessionHasPermissionToTeam(c.App.Session, inTeamId, model.PERMISSION_VIEW_TEAM) {
   468  			c.SetPermissionError(model.PERMISSION_VIEW_TEAM)
   469  			return
   470  		}
   471  
   472  		if sort == "last_activity_at" {
   473  			profiles, err = c.App.GetRecentlyActiveUsersForTeamPage(inTeamId, c.Params.Page, c.Params.PerPage, c.IsSystemAdmin())
   474  		} else if sort == "create_at" {
   475  			profiles, err = c.App.GetNewUsersForTeamPage(inTeamId, c.Params.Page, c.Params.PerPage, c.IsSystemAdmin())
   476  		} else {
   477  			etag = c.App.GetUsersInTeamEtag(inTeamId)
   478  			if c.HandleEtag(etag, "Get Users in Team", w, r) {
   479  				return
   480  			}
   481  			profiles, err = c.App.GetUsersInTeamPage(userGetOptions, c.IsSystemAdmin())
   482  		}
   483  	} else if len(inChannelId) > 0 {
   484  		if !c.App.SessionHasPermissionToChannel(c.App.Session, inChannelId, model.PERMISSION_READ_CHANNEL) {
   485  			c.SetPermissionError(model.PERMISSION_READ_CHANNEL)
   486  			return
   487  		}
   488  		if sort == "status" {
   489  			profiles, err = c.App.GetUsersInChannelPageByStatus(inChannelId, c.Params.Page, c.Params.PerPage, c.IsSystemAdmin())
   490  		} else {
   491  			profiles, err = c.App.GetUsersInChannelPage(inChannelId, c.Params.Page, c.Params.PerPage, c.IsSystemAdmin())
   492  		}
   493  	} else {
   494  		// No permission check required
   495  
   496  		etag = c.App.GetUsersEtag()
   497  		if c.HandleEtag(etag, "Get Users", w, r) {
   498  			return
   499  		}
   500  		profiles, err = c.App.GetUsersPage(userGetOptions, c.IsSystemAdmin())
   501  	}
   502  
   503  	if err != nil {
   504  		c.Err = err
   505  		return
   506  	}
   507  
   508  	if len(etag) > 0 {
   509  		w.Header().Set(model.HEADER_ETAG_SERVER, etag)
   510  	}
   511  	c.App.UpdateLastActivityAtIfNeeded(c.App.Session)
   512  	w.Write([]byte(model.UserListToJson(profiles)))
   513  }
   514  
   515  func getUsersByIds(c *Context, w http.ResponseWriter, r *http.Request) {
   516  	userIds := model.ArrayFromJson(r.Body)
   517  
   518  	if len(userIds) == 0 {
   519  		c.SetInvalidParam("user_ids")
   520  		return
   521  	}
   522  
   523  	// No permission check required
   524  
   525  	users, err := c.App.GetUsersByIds(userIds, c.IsSystemAdmin())
   526  	if err != nil {
   527  		c.Err = err
   528  		return
   529  	}
   530  
   531  	w.Write([]byte(model.UserListToJson(users)))
   532  }
   533  
   534  func getUsersByNames(c *Context, w http.ResponseWriter, r *http.Request) {
   535  	usernames := model.ArrayFromJson(r.Body)
   536  
   537  	if len(usernames) == 0 {
   538  		c.SetInvalidParam("usernames")
   539  		return
   540  	}
   541  
   542  	// No permission check required
   543  
   544  	users, err := c.App.GetUsersByUsernames(usernames, c.IsSystemAdmin())
   545  	if err != nil {
   546  		c.Err = err
   547  		return
   548  	}
   549  
   550  	w.Write([]byte(model.UserListToJson(users)))
   551  }
   552  
   553  func searchUsers(c *Context, w http.ResponseWriter, r *http.Request) {
   554  	props := model.UserSearchFromJson(r.Body)
   555  	if props == nil {
   556  		c.SetInvalidParam("")
   557  		return
   558  	}
   559  
   560  	if len(props.Term) == 0 {
   561  		c.SetInvalidParam("term")
   562  		return
   563  	}
   564  
   565  	if props.TeamId == "" && props.NotInChannelId != "" {
   566  		c.SetInvalidParam("team_id")
   567  		return
   568  	}
   569  
   570  	if props.InChannelId != "" && !c.App.SessionHasPermissionToChannel(c.App.Session, props.InChannelId, model.PERMISSION_READ_CHANNEL) {
   571  		c.SetPermissionError(model.PERMISSION_READ_CHANNEL)
   572  		return
   573  	}
   574  
   575  	if props.NotInChannelId != "" && !c.App.SessionHasPermissionToChannel(c.App.Session, props.NotInChannelId, model.PERMISSION_READ_CHANNEL) {
   576  		c.SetPermissionError(model.PERMISSION_READ_CHANNEL)
   577  		return
   578  	}
   579  
   580  	if props.TeamId != "" && !c.App.SessionHasPermissionToTeam(c.App.Session, props.TeamId, model.PERMISSION_VIEW_TEAM) {
   581  		c.SetPermissionError(model.PERMISSION_VIEW_TEAM)
   582  		return
   583  	}
   584  
   585  	if props.NotInTeamId != "" && !c.App.SessionHasPermissionToTeam(c.App.Session, props.NotInTeamId, model.PERMISSION_VIEW_TEAM) {
   586  		c.SetPermissionError(model.PERMISSION_VIEW_TEAM)
   587  		return
   588  	}
   589  
   590  	if props.Limit <= 0 || props.Limit > model.USER_SEARCH_MAX_LIMIT {
   591  		c.SetInvalidParam("limit")
   592  		return
   593  	}
   594  
   595  	options := &model.UserSearchOptions{
   596  		IsAdmin:       c.IsSystemAdmin(),
   597  		AllowInactive: props.AllowInactive,
   598  		Limit:         props.Limit,
   599  		Role:          props.Role,
   600  	}
   601  
   602  	if c.App.SessionHasPermissionTo(c.App.Session, model.PERMISSION_MANAGE_SYSTEM) {
   603  		options.AllowEmails = true
   604  		options.AllowFullNames = true
   605  	} else {
   606  		options.AllowEmails = *c.App.Config().PrivacySettings.ShowEmailAddress
   607  		options.AllowFullNames = *c.App.Config().PrivacySettings.ShowFullName
   608  	}
   609  
   610  	profiles, err := c.App.SearchUsers(props, options)
   611  	if err != nil {
   612  		c.Err = err
   613  		return
   614  	}
   615  
   616  	w.Write([]byte(model.UserListToJson(profiles)))
   617  }
   618  
   619  func autocompleteUsers(c *Context, w http.ResponseWriter, r *http.Request) {
   620  	channelId := r.URL.Query().Get("in_channel")
   621  	teamId := r.URL.Query().Get("in_team")
   622  	name := r.URL.Query().Get("name")
   623  	limitStr := r.URL.Query().Get("limit")
   624  	limit, _ := strconv.Atoi(limitStr)
   625  	if limitStr == "" {
   626  		limit = model.USER_SEARCH_DEFAULT_LIMIT
   627  	} else if limit > model.USER_SEARCH_MAX_LIMIT {
   628  		limit = model.USER_SEARCH_MAX_LIMIT
   629  	}
   630  
   631  	options := &model.UserSearchOptions{
   632  		IsAdmin: c.IsSystemAdmin(),
   633  		// Never autocomplete on emails.
   634  		AllowEmails: false,
   635  		Limit:       limit,
   636  	}
   637  
   638  	if c.App.SessionHasPermissionTo(c.App.Session, model.PERMISSION_MANAGE_SYSTEM) {
   639  		options.AllowFullNames = true
   640  	} else {
   641  		options.AllowFullNames = *c.App.Config().PrivacySettings.ShowFullName
   642  	}
   643  
   644  	if len(channelId) > 0 {
   645  		if !c.App.SessionHasPermissionToChannel(c.App.Session, channelId, model.PERMISSION_READ_CHANNEL) {
   646  			c.SetPermissionError(model.PERMISSION_READ_CHANNEL)
   647  			return
   648  		}
   649  	}
   650  
   651  	if len(teamId) > 0 {
   652  		if !c.App.SessionHasPermissionToTeam(c.App.Session, teamId, model.PERMISSION_VIEW_TEAM) {
   653  			c.SetPermissionError(model.PERMISSION_VIEW_TEAM)
   654  			return
   655  		}
   656  	}
   657  
   658  	var autocomplete model.UserAutocomplete
   659  
   660  	if len(channelId) > 0 {
   661  		// Applying the provided teamId here is useful for DMs and GMs which don't belong
   662  		// to a team. Applying it when the channel does belong to a team makes less sense,
   663  		// but the permissions are checked above regardless.
   664  		result, err := c.App.AutocompleteUsersInChannel(teamId, channelId, name, options)
   665  		if err != nil {
   666  			c.Err = err
   667  			return
   668  		}
   669  
   670  		autocomplete.Users = result.InChannel
   671  		autocomplete.OutOfChannel = result.OutOfChannel
   672  	} else if len(teamId) > 0 {
   673  		result, err := c.App.AutocompleteUsersInTeam(teamId, name, options)
   674  		if err != nil {
   675  			c.Err = err
   676  			return
   677  		}
   678  
   679  		autocomplete.Users = result.InTeam
   680  	} else {
   681  		// No permission check required
   682  		result, err := c.App.SearchUsersInTeam("", name, options)
   683  		if err != nil {
   684  			c.Err = err
   685  			return
   686  		}
   687  		autocomplete.Users = result
   688  	}
   689  
   690  	w.Write([]byte((autocomplete.ToJson())))
   691  }
   692  
   693  func updateUser(c *Context, w http.ResponseWriter, r *http.Request) {
   694  	c.RequireUserId()
   695  	if c.Err != nil {
   696  		return
   697  	}
   698  
   699  	user := model.UserFromJson(r.Body)
   700  	if user == nil {
   701  		c.SetInvalidParam("user")
   702  		return
   703  	}
   704  
   705  	// The user being updated in the payload must be the same one as indicated in the URL.
   706  	if user.Id != c.Params.UserId {
   707  		c.SetInvalidParam("user_id")
   708  		return
   709  	}
   710  
   711  	if !c.App.SessionHasPermissionToUser(c.App.Session, user.Id) {
   712  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
   713  		return
   714  	}
   715  
   716  	ouser, err := c.App.GetUser(user.Id)
   717  	if err != nil {
   718  		c.Err = err
   719  		return
   720  	}
   721  
   722  	if c.App.Session.IsOAuth {
   723  		if ouser.Email != user.Email {
   724  			c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
   725  			c.Err.DetailedError += ", attempted email update by oauth app"
   726  			return
   727  		}
   728  	}
   729  
   730  	// If eMail update is attempted by the currently logged in user, check if correct password was provided
   731  	if user.Email != "" && ouser.Email != user.Email && c.App.Session.UserId == c.Params.UserId {
   732  		err = c.App.DoubleCheckPassword(ouser, user.Password)
   733  		if err != nil {
   734  			c.SetInvalidParam("password")
   735  			return
   736  		}
   737  	}
   738  
   739  	ruser, err := c.App.UpdateUserAsUser(user, c.IsSystemAdmin())
   740  	if err != nil {
   741  		c.Err = err
   742  		return
   743  	}
   744  
   745  	c.LogAudit("")
   746  	w.Write([]byte(ruser.ToJson()))
   747  }
   748  
   749  func patchUser(c *Context, w http.ResponseWriter, r *http.Request) {
   750  	c.RequireUserId()
   751  	if c.Err != nil {
   752  		return
   753  	}
   754  
   755  	patch := model.UserPatchFromJson(r.Body)
   756  	if patch == nil {
   757  		c.SetInvalidParam("user")
   758  		return
   759  	}
   760  
   761  	if !c.App.SessionHasPermissionToUser(c.App.Session, c.Params.UserId) {
   762  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
   763  		return
   764  	}
   765  
   766  	ouser, err := c.App.GetUser(c.Params.UserId)
   767  	if err != nil {
   768  		c.SetInvalidParam("user_id")
   769  		return
   770  	}
   771  
   772  	if c.App.Session.IsOAuth && patch.Email != nil {
   773  		if err != nil {
   774  			c.Err = err
   775  			return
   776  		}
   777  
   778  		if ouser.Email != *patch.Email {
   779  			c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
   780  			c.Err.DetailedError += ", attempted email update by oauth app"
   781  			return
   782  		}
   783  	}
   784  
   785  	// If eMail update is attempted by the currently logged in user, check if correct password was provided
   786  	if patch.Email != nil && ouser.Email != *patch.Email && c.App.Session.UserId == c.Params.UserId {
   787  		if patch.Password == nil {
   788  			c.SetInvalidParam("password")
   789  			return
   790  		}
   791  
   792  		if err = c.App.DoubleCheckPassword(ouser, *patch.Password); err != nil {
   793  			c.Err = err
   794  			return
   795  		}
   796  	}
   797  
   798  	ruser, err := c.App.PatchUser(c.Params.UserId, patch, c.IsSystemAdmin())
   799  	if err != nil {
   800  		c.Err = err
   801  		return
   802  	}
   803  
   804  	c.App.SetAutoResponderStatus(ruser, ouser.NotifyProps)
   805  	c.LogAudit("")
   806  	w.Write([]byte(ruser.ToJson()))
   807  }
   808  
   809  func deleteUser(c *Context, w http.ResponseWriter, r *http.Request) {
   810  	c.RequireUserId()
   811  	if c.Err != nil {
   812  		return
   813  	}
   814  
   815  	userId := c.Params.UserId
   816  
   817  	if !c.App.SessionHasPermissionToUser(c.App.Session, userId) {
   818  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
   819  		return
   820  	}
   821  
   822  	// if EnableUserDeactivation flag is disabled the user cannot deactivate himself.
   823  	if c.Params.UserId == c.App.Session.UserId && !*c.App.Config().TeamSettings.EnableUserDeactivation && !c.App.SessionHasPermissionTo(c.App.Session, model.PERMISSION_MANAGE_SYSTEM) {
   824  		c.Err = model.NewAppError("deleteUser", "api.user.update_active.not_enable.app_error", nil, "userId="+c.Params.UserId, http.StatusUnauthorized)
   825  		return
   826  	}
   827  
   828  	user, err := c.App.GetUser(userId)
   829  	if err != nil {
   830  		c.Err = err
   831  		return
   832  	}
   833  
   834  	if _, err = c.App.UpdateActive(user, false); err != nil {
   835  		c.Err = err
   836  		return
   837  	}
   838  
   839  	ReturnStatusOK(w)
   840  }
   841  
   842  func updateUserRoles(c *Context, w http.ResponseWriter, r *http.Request) {
   843  	c.RequireUserId()
   844  	if c.Err != nil {
   845  		return
   846  	}
   847  
   848  	props := model.MapFromJson(r.Body)
   849  
   850  	newRoles := props["roles"]
   851  	if !model.IsValidUserRoles(newRoles) {
   852  		c.SetInvalidParam("roles")
   853  		return
   854  	}
   855  
   856  	if !c.App.SessionHasPermissionTo(c.App.Session, model.PERMISSION_MANAGE_ROLES) {
   857  		c.SetPermissionError(model.PERMISSION_MANAGE_ROLES)
   858  		return
   859  	}
   860  
   861  	if _, err := c.App.UpdateUserRoles(c.Params.UserId, newRoles, true); err != nil {
   862  		c.Err = err
   863  		return
   864  	}
   865  
   866  	c.LogAudit(fmt.Sprintf("user=%s roles=%s", c.Params.UserId, newRoles))
   867  	ReturnStatusOK(w)
   868  }
   869  
   870  func updateUserActive(c *Context, w http.ResponseWriter, r *http.Request) {
   871  	c.RequireUserId()
   872  	if c.Err != nil {
   873  		return
   874  	}
   875  
   876  	props := model.StringInterfaceFromJson(r.Body)
   877  
   878  	active, ok := props["active"].(bool)
   879  	if !ok {
   880  		c.SetInvalidParam("active")
   881  		return
   882  	}
   883  
   884  	// true when you're trying to de-activate yourself
   885  	isSelfDeactive := !active && c.Params.UserId == c.App.Session.UserId
   886  
   887  	if !isSelfDeactive && !c.App.SessionHasPermissionTo(c.App.Session, model.PERMISSION_MANAGE_SYSTEM) {
   888  		c.Err = model.NewAppError("updateUserActive", "api.user.update_active.permissions.app_error", nil, "userId="+c.Params.UserId, http.StatusForbidden)
   889  		return
   890  	}
   891  
   892  	// if EnableUserDeactivation flag is disabled the user cannot deactivate himself.
   893  	if isSelfDeactive && !*c.App.Config().TeamSettings.EnableUserDeactivation {
   894  		c.Err = model.NewAppError("updateUserActive", "api.user.update_active.not_enable.app_error", nil, "userId="+c.Params.UserId, http.StatusUnauthorized)
   895  		return
   896  	}
   897  
   898  	user, err := c.App.GetUser(c.Params.UserId)
   899  	if err != nil {
   900  		c.Err = err
   901  		return
   902  	}
   903  
   904  	if _, err = c.App.UpdateActive(user, active); err != nil {
   905  		c.Err = err
   906  	}
   907  
   908  	c.LogAudit(fmt.Sprintf("user_id=%s active=%v", user.Id, active))
   909  	if isSelfDeactive {
   910  		c.App.Srv.Go(func() {
   911  			if err = c.App.SendDeactivateAccountEmail(user.Email, user.Locale, c.App.GetSiteURL()); err != nil {
   912  				mlog.Error(err.Error())
   913  			}
   914  		})
   915  	}
   916  	ReturnStatusOK(w)
   917  }
   918  
   919  func updateUserAuth(c *Context, w http.ResponseWriter, r *http.Request) {
   920  	if !c.IsSystemAdmin() {
   921  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
   922  		return
   923  	}
   924  
   925  	c.RequireUserId()
   926  	if c.Err != nil {
   927  		return
   928  	}
   929  
   930  	userAuth := model.UserAuthFromJson(r.Body)
   931  	if userAuth == nil {
   932  		c.SetInvalidParam("user")
   933  		return
   934  	}
   935  
   936  	user, err := c.App.UpdateUserAuth(c.Params.UserId, userAuth)
   937  	if err != nil {
   938  		c.Err = err
   939  		return
   940  	}
   941  
   942  	c.LogAudit(fmt.Sprintf("updated user %s auth to service=%v", c.Params.UserId, user.AuthService))
   943  	w.Write([]byte(user.ToJson()))
   944  }
   945  
   946  // Deprecated: checkUserMfa is deprecated and should not be used anymore, starting with version 6.0 it will be disabled.
   947  //			   Clients should attempt a login without MFA and will receive a MFA error when it's required.
   948  func checkUserMfa(c *Context, w http.ResponseWriter, r *http.Request) {
   949  
   950  	if *c.App.Config().ServiceSettings.DisableLegacyMFA {
   951  		http.NotFound(w, r)
   952  		return
   953  	}
   954  
   955  	props := model.MapFromJson(r.Body)
   956  
   957  	loginId := props["login_id"]
   958  	if len(loginId) == 0 {
   959  		c.SetInvalidParam("login_id")
   960  		return
   961  	}
   962  
   963  	resp := map[string]interface{}{}
   964  	resp["mfa_required"] = false
   965  
   966  	if !*c.App.Config().ServiceSettings.EnableMultifactorAuthentication {
   967  		w.Write([]byte(model.StringInterfaceToJson(resp)))
   968  		return
   969  	}
   970  
   971  	if *c.App.Config().ServiceSettings.ExperimentalEnableHardenedMode {
   972  		resp["mfa_required"] = true
   973  	} else if user, err := c.App.GetUserForLogin("", loginId); err == nil {
   974  		resp["mfa_required"] = user.MfaActive
   975  	}
   976  
   977  	w.Write([]byte(model.StringInterfaceToJson(resp)))
   978  }
   979  
   980  func updateUserMfa(c *Context, w http.ResponseWriter, r *http.Request) {
   981  	c.RequireUserId()
   982  	if c.Err != nil {
   983  		return
   984  	}
   985  
   986  	if c.App.Session.IsOAuth {
   987  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
   988  		c.Err.DetailedError += ", attempted access by oauth app"
   989  		return
   990  	}
   991  
   992  	if !c.App.SessionHasPermissionToUser(c.App.Session, c.Params.UserId) {
   993  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
   994  		return
   995  	}
   996  
   997  	props := model.StringInterfaceFromJson(r.Body)
   998  	activate, ok := props["activate"].(bool)
   999  	if !ok {
  1000  		c.SetInvalidParam("activate")
  1001  		return
  1002  	}
  1003  
  1004  	code := ""
  1005  	if activate {
  1006  		code, ok = props["code"].(string)
  1007  		if !ok || len(code) == 0 {
  1008  			c.SetInvalidParam("code")
  1009  			return
  1010  		}
  1011  	}
  1012  
  1013  	c.LogAudit("attempt")
  1014  
  1015  	if err := c.App.UpdateMfa(activate, c.Params.UserId, code); err != nil {
  1016  		c.Err = err
  1017  		return
  1018  	}
  1019  
  1020  	c.LogAudit("success - mfa updated")
  1021  	ReturnStatusOK(w)
  1022  }
  1023  
  1024  func generateMfaSecret(c *Context, w http.ResponseWriter, r *http.Request) {
  1025  	c.RequireUserId()
  1026  	if c.Err != nil {
  1027  		return
  1028  	}
  1029  
  1030  	if c.App.Session.IsOAuth {
  1031  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
  1032  		c.Err.DetailedError += ", attempted access by oauth app"
  1033  		return
  1034  	}
  1035  
  1036  	if !c.App.SessionHasPermissionToUser(c.App.Session, c.Params.UserId) {
  1037  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
  1038  		return
  1039  	}
  1040  
  1041  	secret, err := c.App.GenerateMfaSecret(c.Params.UserId)
  1042  	if err != nil {
  1043  		c.Err = err
  1044  		return
  1045  	}
  1046  
  1047  	w.Header().Set("Cache-Control", "no-cache")
  1048  	w.Header().Set("Pragma", "no-cache")
  1049  	w.Header().Set("Expires", "0")
  1050  	w.Write([]byte(secret.ToJson()))
  1051  }
  1052  
  1053  func updatePassword(c *Context, w http.ResponseWriter, r *http.Request) {
  1054  	c.RequireUserId()
  1055  	if c.Err != nil {
  1056  		return
  1057  	}
  1058  
  1059  	props := model.MapFromJson(r.Body)
  1060  	newPassword := props["new_password"]
  1061  
  1062  	c.LogAudit("attempted")
  1063  
  1064  	var err *model.AppError
  1065  	if c.Params.UserId == c.App.Session.UserId {
  1066  		currentPassword := props["current_password"]
  1067  		if len(currentPassword) <= 0 {
  1068  			c.SetInvalidParam("current_password")
  1069  			return
  1070  		}
  1071  
  1072  		err = c.App.UpdatePasswordAsUser(c.Params.UserId, currentPassword, newPassword)
  1073  	} else if c.App.SessionHasPermissionTo(c.App.Session, model.PERMISSION_MANAGE_SYSTEM) {
  1074  		err = c.App.UpdatePasswordByUserIdSendEmail(c.Params.UserId, newPassword, c.App.T("api.user.reset_password.method"))
  1075  	} else {
  1076  		err = model.NewAppError("updatePassword", "api.user.update_password.context.app_error", nil, "", http.StatusForbidden)
  1077  	}
  1078  
  1079  	if err != nil {
  1080  		c.LogAudit("failed")
  1081  		c.Err = err
  1082  		return
  1083  	}
  1084  
  1085  	c.LogAudit("completed")
  1086  	ReturnStatusOK(w)
  1087  }
  1088  
  1089  func resetPassword(c *Context, w http.ResponseWriter, r *http.Request) {
  1090  	props := model.MapFromJson(r.Body)
  1091  
  1092  	token := props["token"]
  1093  	if len(token) != model.TOKEN_SIZE {
  1094  		c.SetInvalidParam("token")
  1095  		return
  1096  	}
  1097  
  1098  	newPassword := props["new_password"]
  1099  
  1100  	c.LogAudit("attempt - token=" + token)
  1101  
  1102  	if err := c.App.ResetPasswordFromToken(token, newPassword); err != nil {
  1103  		c.LogAudit("fail - token=" + token)
  1104  		c.Err = err
  1105  		return
  1106  	}
  1107  
  1108  	c.LogAudit("success - token=" + token)
  1109  
  1110  	ReturnStatusOK(w)
  1111  }
  1112  
  1113  func sendPasswordReset(c *Context, w http.ResponseWriter, r *http.Request) {
  1114  	props := model.MapFromJson(r.Body)
  1115  
  1116  	email := props["email"]
  1117  	if len(email) == 0 {
  1118  		c.SetInvalidParam("email")
  1119  		return
  1120  	}
  1121  
  1122  	sent, err := c.App.SendPasswordReset(email, c.App.GetSiteURL())
  1123  	if err != nil {
  1124  		if *c.App.Config().ServiceSettings.ExperimentalEnableHardenedMode {
  1125  			ReturnStatusOK(w)
  1126  		} else {
  1127  			c.Err = err
  1128  		}
  1129  		return
  1130  	}
  1131  
  1132  	if sent {
  1133  		c.LogAudit("sent=" + email)
  1134  	}
  1135  
  1136  	ReturnStatusOK(w)
  1137  }
  1138  
  1139  func login(c *Context, w http.ResponseWriter, r *http.Request) {
  1140  	// For hardened mode, translate all login errors to generic. MFA error being an exception, since it's required for
  1141  	// the login flow itself.
  1142  	defer func() {
  1143  		if *c.App.Config().ServiceSettings.ExperimentalEnableHardenedMode && c.Err != nil && c.Err.Id != "mfa.validate_token.authenticate.app_error" {
  1144  			c.Err = model.NewAppError("login", "api.user.login.invalid_credentials", nil, "", http.StatusUnauthorized)
  1145  		}
  1146  	}()
  1147  
  1148  	props := model.MapFromJson(r.Body)
  1149  
  1150  	id := props["id"]
  1151  	loginId := props["login_id"]
  1152  	password := props["password"]
  1153  	mfaToken := props["token"]
  1154  	deviceId := props["device_id"]
  1155  	ldapOnly := props["ldap_only"] == "true"
  1156  
  1157  	if *c.App.Config().ExperimentalSettings.ClientSideCertEnable {
  1158  		if license := c.App.License(); license == nil || !*license.Features.SAML {
  1159  			c.Err = model.NewAppError("ClientSideCertNotAllowed", "api.user.login.client_side_cert.license.app_error", nil, "", http.StatusBadRequest)
  1160  			return
  1161  		}
  1162  		certPem, certSubject, certEmail := c.App.CheckForClientSideCert(r)
  1163  		mlog.Debug("Client Cert", mlog.String("cert_subject", certSubject), mlog.String("cert_email", certEmail))
  1164  
  1165  		if len(certPem) == 0 || len(certEmail) == 0 {
  1166  			c.Err = model.NewAppError("ClientSideCertMissing", "api.user.login.client_side_cert.certificate.app_error", nil, "", http.StatusBadRequest)
  1167  			return
  1168  		}
  1169  
  1170  		if *c.App.Config().ExperimentalSettings.ClientSideCertCheck == model.CLIENT_SIDE_CERT_CHECK_PRIMARY_AUTH {
  1171  			loginId = certEmail
  1172  			password = "certificate"
  1173  		}
  1174  	}
  1175  
  1176  	c.LogAuditWithUserId(id, "attempt - login_id="+loginId)
  1177  	user, err := c.App.AuthenticateUserForLogin(id, loginId, password, mfaToken, ldapOnly)
  1178  
  1179  	if err != nil {
  1180  		c.LogAuditWithUserId(id, "failure - login_id="+loginId)
  1181  		c.Err = err
  1182  		return
  1183  	}
  1184  
  1185  	c.LogAuditWithUserId(user.Id, "authenticated")
  1186  
  1187  	session, err := c.App.DoLogin(w, r, user, deviceId)
  1188  	if err != nil {
  1189  		c.Err = err
  1190  		return
  1191  	}
  1192  
  1193  	c.LogAuditWithUserId(user.Id, "success")
  1194  
  1195  	if r.Header.Get(model.HEADER_REQUESTED_WITH) == model.HEADER_REQUESTED_WITH_XML {
  1196  		c.App.AttachSessionCookies(w, r, session)
  1197  	}
  1198  
  1199  	userTermsOfService, err := c.App.GetUserTermsOfService(user.Id)
  1200  	if err != nil && err.StatusCode != http.StatusNotFound {
  1201  		c.Err = err
  1202  		return
  1203  	}
  1204  
  1205  	if userTermsOfService != nil {
  1206  		user.TermsOfServiceId = userTermsOfService.TermsOfServiceId
  1207  		user.TermsOfServiceCreateAt = userTermsOfService.CreateAt
  1208  	}
  1209  
  1210  	c.App.Session = *session
  1211  
  1212  	user.Sanitize(map[string]bool{})
  1213  
  1214  	w.Write([]byte(user.ToJson()))
  1215  }
  1216  
  1217  func logout(c *Context, w http.ResponseWriter, r *http.Request) {
  1218  	Logout(c, w, r)
  1219  }
  1220  
  1221  func Logout(c *Context, w http.ResponseWriter, r *http.Request) {
  1222  	c.LogAudit("")
  1223  	c.RemoveSessionCookie(w, r)
  1224  	if c.App.Session.Id != "" {
  1225  		if err := c.App.RevokeSessionById(c.App.Session.Id); err != nil {
  1226  			c.Err = err
  1227  			return
  1228  		}
  1229  	}
  1230  
  1231  	ReturnStatusOK(w)
  1232  }
  1233  
  1234  func getSessions(c *Context, w http.ResponseWriter, r *http.Request) {
  1235  	c.RequireUserId()
  1236  	if c.Err != nil {
  1237  		return
  1238  	}
  1239  
  1240  	if !c.App.SessionHasPermissionToUser(c.App.Session, c.Params.UserId) {
  1241  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
  1242  		return
  1243  	}
  1244  
  1245  	sessions, err := c.App.GetSessions(c.Params.UserId)
  1246  	if err != nil {
  1247  		c.Err = err
  1248  		return
  1249  	}
  1250  
  1251  	for _, session := range sessions {
  1252  		session.Sanitize()
  1253  	}
  1254  
  1255  	w.Write([]byte(model.SessionsToJson(sessions)))
  1256  }
  1257  
  1258  func revokeSession(c *Context, w http.ResponseWriter, r *http.Request) {
  1259  	c.RequireUserId()
  1260  	if c.Err != nil {
  1261  		return
  1262  	}
  1263  
  1264  	if !c.App.SessionHasPermissionToUser(c.App.Session, c.Params.UserId) {
  1265  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
  1266  		return
  1267  	}
  1268  
  1269  	props := model.MapFromJson(r.Body)
  1270  	sessionId := props["session_id"]
  1271  	if sessionId == "" {
  1272  		c.SetInvalidParam("session_id")
  1273  		return
  1274  	}
  1275  
  1276  	session, err := c.App.GetSessionById(sessionId)
  1277  	if err != nil {
  1278  		c.Err = err
  1279  		return
  1280  	}
  1281  
  1282  	if session.UserId != c.Params.UserId {
  1283  		c.SetInvalidUrlParam("user_id")
  1284  		return
  1285  	}
  1286  
  1287  	if err := c.App.RevokeSession(session); err != nil {
  1288  		c.Err = err
  1289  		return
  1290  	}
  1291  
  1292  	ReturnStatusOK(w)
  1293  }
  1294  
  1295  func revokeAllSessionsForUser(c *Context, w http.ResponseWriter, r *http.Request) {
  1296  	c.RequireUserId()
  1297  	if c.Err != nil {
  1298  		return
  1299  	}
  1300  
  1301  	if !c.App.SessionHasPermissionToUser(c.App.Session, c.Params.UserId) {
  1302  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
  1303  		return
  1304  	}
  1305  
  1306  	if err := c.App.RevokeAllSessions(c.Params.UserId); err != nil {
  1307  		c.Err = err
  1308  		return
  1309  	}
  1310  
  1311  	ReturnStatusOK(w)
  1312  }
  1313  
  1314  func attachDeviceId(c *Context, w http.ResponseWriter, r *http.Request) {
  1315  	props := model.MapFromJson(r.Body)
  1316  
  1317  	deviceId := props["device_id"]
  1318  	if len(deviceId) == 0 {
  1319  		c.SetInvalidParam("device_id")
  1320  		return
  1321  	}
  1322  
  1323  	// A special case where we logout of all other sessions with the same device id
  1324  	if err := c.App.RevokeSessionsForDeviceId(c.App.Session.UserId, deviceId, c.App.Session.Id); err != nil {
  1325  		c.Err = err
  1326  		return
  1327  	}
  1328  
  1329  	c.App.ClearSessionCacheForUser(c.App.Session.UserId)
  1330  	c.App.Session.SetExpireInDays(*c.App.Config().ServiceSettings.SessionLengthMobileInDays)
  1331  
  1332  	maxAge := *c.App.Config().ServiceSettings.SessionLengthMobileInDays * 60 * 60 * 24
  1333  
  1334  	secure := false
  1335  	if app.GetProtocol(r) == "https" {
  1336  		secure = true
  1337  	}
  1338  
  1339  	expiresAt := time.Unix(model.GetMillis()/1000+int64(maxAge), 0)
  1340  	sessionCookie := &http.Cookie{
  1341  		Name:     model.SESSION_COOKIE_TOKEN,
  1342  		Value:    c.App.Session.Token,
  1343  		Path:     "/",
  1344  		MaxAge:   maxAge,
  1345  		Expires:  expiresAt,
  1346  		HttpOnly: true,
  1347  		Domain:   c.App.GetCookieDomain(),
  1348  		Secure:   secure,
  1349  	}
  1350  
  1351  	http.SetCookie(w, sessionCookie)
  1352  
  1353  	if err := c.App.AttachDeviceId(c.App.Session.Id, deviceId, c.App.Session.ExpiresAt); err != nil {
  1354  		c.Err = err
  1355  		return
  1356  	}
  1357  
  1358  	c.LogAudit("")
  1359  	ReturnStatusOK(w)
  1360  }
  1361  
  1362  func getUserAudits(c *Context, w http.ResponseWriter, r *http.Request) {
  1363  	c.RequireUserId()
  1364  	if c.Err != nil {
  1365  		return
  1366  	}
  1367  
  1368  	if !c.App.SessionHasPermissionToUser(c.App.Session, c.Params.UserId) {
  1369  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
  1370  		return
  1371  	}
  1372  
  1373  	audits, err := c.App.GetAuditsPage(c.Params.UserId, c.Params.Page, c.Params.PerPage)
  1374  	if err != nil {
  1375  		c.Err = err
  1376  		return
  1377  	}
  1378  
  1379  	w.Write([]byte(audits.ToJson()))
  1380  }
  1381  
  1382  func verifyUserEmail(c *Context, w http.ResponseWriter, r *http.Request) {
  1383  	props := model.MapFromJson(r.Body)
  1384  
  1385  	token := props["token"]
  1386  	if len(token) != model.TOKEN_SIZE {
  1387  		c.SetInvalidParam("token")
  1388  		return
  1389  	}
  1390  
  1391  	if err := c.App.VerifyEmailFromToken(token); err != nil {
  1392  		c.Err = model.NewAppError("verifyUserEmail", "api.user.verify_email.bad_link.app_error", nil, err.Error(), http.StatusBadRequest)
  1393  		return
  1394  	}
  1395  
  1396  	c.LogAudit("Email Verified")
  1397  	ReturnStatusOK(w)
  1398  }
  1399  
  1400  func sendVerificationEmail(c *Context, w http.ResponseWriter, r *http.Request) {
  1401  	props := model.MapFromJson(r.Body)
  1402  
  1403  	email := props["email"]
  1404  	if len(email) == 0 {
  1405  		c.SetInvalidParam("email")
  1406  		return
  1407  	}
  1408  
  1409  	user, err := c.App.GetUserForLogin("", email)
  1410  	if err != nil {
  1411  		// Don't want to leak whether the email is valid or not
  1412  		ReturnStatusOK(w)
  1413  		return
  1414  	}
  1415  
  1416  	if err = c.App.SendEmailVerification(user, user.Email); err != nil {
  1417  		// Don't want to leak whether the email is valid or not
  1418  		mlog.Error(err.Error())
  1419  		ReturnStatusOK(w)
  1420  		return
  1421  	}
  1422  
  1423  	ReturnStatusOK(w)
  1424  }
  1425  
  1426  func switchAccountType(c *Context, w http.ResponseWriter, r *http.Request) {
  1427  	switchRequest := model.SwitchRequestFromJson(r.Body)
  1428  	if switchRequest == nil {
  1429  		c.SetInvalidParam("switch_request")
  1430  		return
  1431  	}
  1432  
  1433  	link := ""
  1434  	var err *model.AppError
  1435  
  1436  	if switchRequest.EmailToOAuth() {
  1437  		link, err = c.App.SwitchEmailToOAuth(w, r, switchRequest.Email, switchRequest.Password, switchRequest.MfaCode, switchRequest.NewService)
  1438  	} else if switchRequest.OAuthToEmail() {
  1439  		c.SessionRequired()
  1440  		if c.Err != nil {
  1441  			return
  1442  		}
  1443  
  1444  		link, err = c.App.SwitchOAuthToEmail(switchRequest.Email, switchRequest.NewPassword, c.App.Session.UserId)
  1445  	} else if switchRequest.EmailToLdap() {
  1446  		link, err = c.App.SwitchEmailToLdap(switchRequest.Email, switchRequest.Password, switchRequest.MfaCode, switchRequest.LdapLoginId, switchRequest.NewPassword)
  1447  	} else if switchRequest.LdapToEmail() {
  1448  		link, err = c.App.SwitchLdapToEmail(switchRequest.Password, switchRequest.MfaCode, switchRequest.Email, switchRequest.NewPassword)
  1449  	} else {
  1450  		c.SetInvalidParam("switch_request")
  1451  		return
  1452  	}
  1453  
  1454  	if err != nil {
  1455  		c.Err = err
  1456  		return
  1457  	}
  1458  
  1459  	c.LogAudit("success")
  1460  	w.Write([]byte(model.MapToJson(map[string]string{"follow_link": link})))
  1461  }
  1462  
  1463  func createUserAccessToken(c *Context, w http.ResponseWriter, r *http.Request) {
  1464  	c.RequireUserId()
  1465  	if c.Err != nil {
  1466  		return
  1467  	}
  1468  
  1469  	if c.App.Session.IsOAuth {
  1470  		c.SetPermissionError(model.PERMISSION_CREATE_USER_ACCESS_TOKEN)
  1471  		c.Err.DetailedError += ", attempted access by oauth app"
  1472  		return
  1473  	}
  1474  
  1475  	accessToken := model.UserAccessTokenFromJson(r.Body)
  1476  	if accessToken == nil {
  1477  		c.SetInvalidParam("user_access_token")
  1478  		return
  1479  	}
  1480  
  1481  	if accessToken.Description == "" {
  1482  		c.SetInvalidParam("description")
  1483  		return
  1484  	}
  1485  
  1486  	c.LogAudit("")
  1487  
  1488  	if !c.App.SessionHasPermissionTo(c.App.Session, model.PERMISSION_CREATE_USER_ACCESS_TOKEN) {
  1489  		c.SetPermissionError(model.PERMISSION_CREATE_USER_ACCESS_TOKEN)
  1490  		return
  1491  	}
  1492  
  1493  	if !c.App.SessionHasPermissionToUserOrBot(c.App.Session, c.Params.UserId) {
  1494  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
  1495  		return
  1496  	}
  1497  
  1498  	accessToken.UserId = c.Params.UserId
  1499  	accessToken.Token = ""
  1500  
  1501  	accessToken, err := c.App.CreateUserAccessToken(accessToken)
  1502  	if err != nil {
  1503  		c.Err = err
  1504  		return
  1505  	}
  1506  
  1507  	c.LogAudit("success - token_id=" + accessToken.Id)
  1508  	w.Write([]byte(accessToken.ToJson()))
  1509  }
  1510  
  1511  func searchUserAccessTokens(c *Context, w http.ResponseWriter, r *http.Request) {
  1512  	if !c.App.SessionHasPermissionTo(c.App.Session, model.PERMISSION_MANAGE_SYSTEM) {
  1513  		c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
  1514  		return
  1515  	}
  1516  	props := model.UserAccessTokenSearchFromJson(r.Body)
  1517  	if props == nil {
  1518  		c.SetInvalidParam("user_access_token_search")
  1519  		return
  1520  	}
  1521  
  1522  	if len(props.Term) == 0 {
  1523  		c.SetInvalidParam("term")
  1524  		return
  1525  	}
  1526  
  1527  	accessTokens, err := c.App.SearchUserAccessTokens(props.Term)
  1528  	if err != nil {
  1529  		c.Err = err
  1530  		return
  1531  	}
  1532  
  1533  	w.Write([]byte(model.UserAccessTokenListToJson(accessTokens)))
  1534  }
  1535  
  1536  func getUserAccessTokens(c *Context, w http.ResponseWriter, r *http.Request) {
  1537  	if !c.App.SessionHasPermissionTo(c.App.Session, model.PERMISSION_MANAGE_SYSTEM) {
  1538  		c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
  1539  		return
  1540  	}
  1541  
  1542  	accessTokens, err := c.App.GetUserAccessTokens(c.Params.Page, c.Params.PerPage)
  1543  	if err != nil {
  1544  		c.Err = err
  1545  		return
  1546  	}
  1547  
  1548  	w.Write([]byte(model.UserAccessTokenListToJson(accessTokens)))
  1549  }
  1550  
  1551  func getUserAccessTokensForUser(c *Context, w http.ResponseWriter, r *http.Request) {
  1552  	c.RequireUserId()
  1553  	if c.Err != nil {
  1554  		return
  1555  	}
  1556  
  1557  	if !c.App.SessionHasPermissionTo(c.App.Session, model.PERMISSION_READ_USER_ACCESS_TOKEN) {
  1558  		c.SetPermissionError(model.PERMISSION_READ_USER_ACCESS_TOKEN)
  1559  		return
  1560  	}
  1561  
  1562  	if !c.App.SessionHasPermissionToUserOrBot(c.App.Session, c.Params.UserId) {
  1563  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
  1564  		return
  1565  	}
  1566  
  1567  	accessTokens, err := c.App.GetUserAccessTokensForUser(c.Params.UserId, c.Params.Page, c.Params.PerPage)
  1568  	if err != nil {
  1569  		c.Err = err
  1570  		return
  1571  	}
  1572  
  1573  	w.Write([]byte(model.UserAccessTokenListToJson(accessTokens)))
  1574  }
  1575  
  1576  func getUserAccessToken(c *Context, w http.ResponseWriter, r *http.Request) {
  1577  	c.RequireTokenId()
  1578  	if c.Err != nil {
  1579  		return
  1580  	}
  1581  
  1582  	if !c.App.SessionHasPermissionTo(c.App.Session, model.PERMISSION_READ_USER_ACCESS_TOKEN) {
  1583  		c.SetPermissionError(model.PERMISSION_READ_USER_ACCESS_TOKEN)
  1584  		return
  1585  	}
  1586  
  1587  	accessToken, err := c.App.GetUserAccessToken(c.Params.TokenId, true)
  1588  	if err != nil {
  1589  		c.Err = err
  1590  		return
  1591  	}
  1592  
  1593  	if !c.App.SessionHasPermissionToUserOrBot(c.App.Session, accessToken.UserId) {
  1594  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
  1595  		return
  1596  	}
  1597  
  1598  	w.Write([]byte(accessToken.ToJson()))
  1599  }
  1600  
  1601  func revokeUserAccessToken(c *Context, w http.ResponseWriter, r *http.Request) {
  1602  	props := model.MapFromJson(r.Body)
  1603  
  1604  	tokenId := props["token_id"]
  1605  	if tokenId == "" {
  1606  		c.SetInvalidParam("token_id")
  1607  	}
  1608  
  1609  	c.LogAudit("")
  1610  
  1611  	if !c.App.SessionHasPermissionTo(c.App.Session, model.PERMISSION_REVOKE_USER_ACCESS_TOKEN) {
  1612  		c.SetPermissionError(model.PERMISSION_REVOKE_USER_ACCESS_TOKEN)
  1613  		return
  1614  	}
  1615  
  1616  	accessToken, err := c.App.GetUserAccessToken(tokenId, false)
  1617  	if err != nil {
  1618  		c.Err = err
  1619  		return
  1620  	}
  1621  
  1622  	if !c.App.SessionHasPermissionToUserOrBot(c.App.Session, accessToken.UserId) {
  1623  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
  1624  		return
  1625  	}
  1626  
  1627  	if err = c.App.RevokeUserAccessToken(accessToken); err != nil {
  1628  		c.Err = err
  1629  		return
  1630  	}
  1631  
  1632  	c.LogAudit("success - token_id=" + accessToken.Id)
  1633  	ReturnStatusOK(w)
  1634  }
  1635  
  1636  func disableUserAccessToken(c *Context, w http.ResponseWriter, r *http.Request) {
  1637  	props := model.MapFromJson(r.Body)
  1638  	tokenId := props["token_id"]
  1639  
  1640  	if tokenId == "" {
  1641  		c.SetInvalidParam("token_id")
  1642  	}
  1643  
  1644  	c.LogAudit("")
  1645  
  1646  	// No separate permission for this action for now
  1647  	if !c.App.SessionHasPermissionTo(c.App.Session, model.PERMISSION_REVOKE_USER_ACCESS_TOKEN) {
  1648  		c.SetPermissionError(model.PERMISSION_REVOKE_USER_ACCESS_TOKEN)
  1649  		return
  1650  	}
  1651  
  1652  	accessToken, err := c.App.GetUserAccessToken(tokenId, false)
  1653  	if err != nil {
  1654  		c.Err = err
  1655  		return
  1656  	}
  1657  
  1658  	if !c.App.SessionHasPermissionToUserOrBot(c.App.Session, accessToken.UserId) {
  1659  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
  1660  		return
  1661  	}
  1662  
  1663  	if err = c.App.DisableUserAccessToken(accessToken); err != nil {
  1664  		c.Err = err
  1665  		return
  1666  	}
  1667  
  1668  	c.LogAudit("success - token_id=" + accessToken.Id)
  1669  	ReturnStatusOK(w)
  1670  }
  1671  
  1672  func enableUserAccessToken(c *Context, w http.ResponseWriter, r *http.Request) {
  1673  	props := model.MapFromJson(r.Body)
  1674  
  1675  	tokenId := props["token_id"]
  1676  	if tokenId == "" {
  1677  		c.SetInvalidParam("token_id")
  1678  	}
  1679  
  1680  	c.LogAudit("")
  1681  
  1682  	// No separate permission for this action for now
  1683  	if !c.App.SessionHasPermissionTo(c.App.Session, model.PERMISSION_CREATE_USER_ACCESS_TOKEN) {
  1684  		c.SetPermissionError(model.PERMISSION_CREATE_USER_ACCESS_TOKEN)
  1685  		return
  1686  	}
  1687  
  1688  	accessToken, err := c.App.GetUserAccessToken(tokenId, false)
  1689  	if err != nil {
  1690  		c.Err = err
  1691  		return
  1692  	}
  1693  
  1694  	if !c.App.SessionHasPermissionToUserOrBot(c.App.Session, accessToken.UserId) {
  1695  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
  1696  		return
  1697  	}
  1698  
  1699  	if err = c.App.EnableUserAccessToken(accessToken); err != nil {
  1700  		c.Err = err
  1701  		return
  1702  	}
  1703  
  1704  	c.LogAudit("success - token_id=" + accessToken.Id)
  1705  	ReturnStatusOK(w)
  1706  }
  1707  
  1708  func saveUserTermsOfService(c *Context, w http.ResponseWriter, r *http.Request) {
  1709  	props := model.StringInterfaceFromJson(r.Body)
  1710  
  1711  	userId := c.App.Session.UserId
  1712  	termsOfServiceId := props["termsOfServiceId"].(string)
  1713  	accepted := props["accepted"].(bool)
  1714  
  1715  	if _, err := c.App.GetTermsOfService(termsOfServiceId); err != nil {
  1716  		c.Err = err
  1717  		return
  1718  	}
  1719  
  1720  	if err := c.App.SaveUserTermsOfService(userId, termsOfServiceId, accepted); err != nil {
  1721  		c.Err = err
  1722  		return
  1723  	}
  1724  
  1725  	c.LogAudit("TermsOfServiceId=" + termsOfServiceId + ", accepted=" + strconv.FormatBool(accepted))
  1726  	ReturnStatusOK(w)
  1727  }
  1728  
  1729  func getUserTermsOfService(c *Context, w http.ResponseWriter, r *http.Request) {
  1730  	userId := c.App.Session.UserId
  1731  	result, err := c.App.GetUserTermsOfService(userId)
  1732  	if err != nil {
  1733  		c.Err = err
  1734  		return
  1735  	}
  1736  	w.Write([]byte(result.ToJson()))
  1737  }