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