github.com/qichengzx/mattermost-server@v4.5.1-0.20180604164826-2c75247c97d0+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  	if c.Session.IsOAuth {
   568  		ouser, err := c.App.GetUser(user.Id)
   569  		if err != nil {
   570  			c.Err = err
   571  			return
   572  		}
   573  
   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 ruser, err := c.App.UpdateUserAsUser(user, c.IsSystemAdmin()); err != nil {
   582  		c.Err = err
   583  		return
   584  	} else {
   585  		c.LogAudit("")
   586  		w.Write([]byte(ruser.ToJson()))
   587  	}
   588  }
   589  
   590  func patchUser(c *Context, w http.ResponseWriter, r *http.Request) {
   591  	c.RequireUserId()
   592  	if c.Err != nil {
   593  		return
   594  	}
   595  
   596  	patch := model.UserPatchFromJson(r.Body)
   597  	if patch == nil {
   598  		c.SetInvalidParam("user")
   599  		return
   600  	}
   601  
   602  	if !c.App.SessionHasPermissionToUser(c.Session, c.Params.UserId) {
   603  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
   604  		return
   605  	}
   606  
   607  	ouser, err := c.App.GetUser(c.Params.UserId)
   608  	if err != nil {
   609  		c.SetInvalidParam("user_id")
   610  		return
   611  	}
   612  
   613  	if c.Session.IsOAuth && patch.Email != nil {
   614  		if err != nil {
   615  			c.Err = err
   616  			return
   617  		}
   618  
   619  		if ouser.Email != *patch.Email {
   620  			c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
   621  			c.Err.DetailedError += ", attempted email update by oauth app"
   622  			return
   623  		}
   624  	}
   625  
   626  	if ruser, err := c.App.PatchUser(c.Params.UserId, patch, c.IsSystemAdmin()); err != nil {
   627  		c.Err = err
   628  		return
   629  	} else {
   630  		c.App.SetAutoResponderStatus(ruser, ouser.NotifyProps)
   631  		c.LogAudit("")
   632  		w.Write([]byte(ruser.ToJson()))
   633  	}
   634  }
   635  
   636  func deleteUser(c *Context, w http.ResponseWriter, r *http.Request) {
   637  	c.RequireUserId()
   638  	if c.Err != nil {
   639  		return
   640  	}
   641  
   642  	userId := c.Params.UserId
   643  
   644  	if !c.App.SessionHasPermissionToUser(c.Session, userId) {
   645  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
   646  		return
   647  	}
   648  
   649  	var user *model.User
   650  	var err *model.AppError
   651  
   652  	if user, err = c.App.GetUser(userId); err != nil {
   653  		c.Err = err
   654  		return
   655  	}
   656  
   657  	if _, err := c.App.UpdateActive(user, false); err != nil {
   658  		c.Err = err
   659  		return
   660  	}
   661  
   662  	ReturnStatusOK(w)
   663  }
   664  
   665  func updateUserRoles(c *Context, w http.ResponseWriter, r *http.Request) {
   666  	c.RequireUserId()
   667  	if c.Err != nil {
   668  		return
   669  	}
   670  
   671  	props := model.MapFromJson(r.Body)
   672  
   673  	newRoles := props["roles"]
   674  	if !model.IsValidUserRoles(newRoles) {
   675  		c.SetInvalidParam("roles")
   676  		return
   677  	}
   678  
   679  	if !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_ROLES) {
   680  		c.SetPermissionError(model.PERMISSION_MANAGE_ROLES)
   681  		return
   682  	}
   683  
   684  	if _, err := c.App.UpdateUserRoles(c.Params.UserId, newRoles, true); err != nil {
   685  		c.Err = err
   686  		return
   687  	} else {
   688  		c.LogAuditWithUserId(c.Params.UserId, "roles="+newRoles)
   689  	}
   690  
   691  	ReturnStatusOK(w)
   692  }
   693  
   694  func updateUserActive(c *Context, w http.ResponseWriter, r *http.Request) {
   695  	c.RequireUserId()
   696  	if c.Err != nil {
   697  		return
   698  	}
   699  
   700  	props := model.StringInterfaceFromJson(r.Body)
   701  
   702  	active, ok := props["active"].(bool)
   703  	if !ok {
   704  		c.SetInvalidParam("active")
   705  		return
   706  	}
   707  
   708  	// true when you're trying to de-activate yourself
   709  	isSelfDeactive := !active && c.Params.UserId == c.Session.UserId
   710  
   711  	if !isSelfDeactive && !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM) {
   712  		c.Err = model.NewAppError("updateUserActive", "api.user.update_active.permissions.app_error", nil, "userId="+c.Params.UserId, http.StatusForbidden)
   713  		return
   714  	}
   715  
   716  	// if EnableUserDeactivation flag is disabled the user cannot deactivate himself.
   717  	if isSelfDeactive && !*c.App.GetConfig().TeamSettings.EnableUserDeactivation {
   718  		c.Err = model.NewAppError("updateUserActive", "api.user.update_active.not_enable.app_error", nil, "userId="+c.Params.UserId, http.StatusUnauthorized)
   719  		return
   720  	}
   721  
   722  	var user *model.User
   723  	var err *model.AppError
   724  
   725  	if user, err = c.App.GetUser(c.Params.UserId); err != nil {
   726  		c.Err = err
   727  		return
   728  	}
   729  
   730  	if _, err := c.App.UpdateActive(user, active); err != nil {
   731  		c.Err = err
   732  	} else {
   733  		c.LogAuditWithUserId(user.Id, fmt.Sprintf("active=%v", active))
   734  		if isSelfDeactive {
   735  			c.App.Go(func() {
   736  				if err = c.App.SendDeactivateAccountEmail(user.Email, user.Locale, c.App.GetSiteURL()); err != nil {
   737  					mlog.Error(err.Error())
   738  				}
   739  			})
   740  		}
   741  		ReturnStatusOK(w)
   742  	}
   743  }
   744  
   745  func updateUserAuth(c *Context, w http.ResponseWriter, r *http.Request) {
   746  	if !c.IsSystemAdmin() {
   747  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
   748  		return
   749  	}
   750  
   751  	c.RequireUserId()
   752  	if c.Err != nil {
   753  		return
   754  	}
   755  
   756  	userAuth := model.UserAuthFromJson(r.Body)
   757  	if userAuth == nil {
   758  		c.SetInvalidParam("user")
   759  		return
   760  	}
   761  
   762  	if user, err := c.App.UpdateUserAuth(c.Params.UserId, userAuth); err != nil {
   763  		c.Err = err
   764  	} else {
   765  		c.LogAuditWithUserId(c.Params.UserId, fmt.Sprintf("updated user auth to service=%v", user.AuthService))
   766  		w.Write([]byte(user.ToJson()))
   767  	}
   768  }
   769  
   770  func checkUserMfa(c *Context, w http.ResponseWriter, r *http.Request) {
   771  	props := model.MapFromJson(r.Body)
   772  
   773  	loginId := props["login_id"]
   774  	if len(loginId) == 0 {
   775  		c.SetInvalidParam("login_id")
   776  		return
   777  	}
   778  
   779  	resp := map[string]interface{}{}
   780  	resp["mfa_required"] = false
   781  
   782  	if license := c.App.License(); license == nil || !*license.Features.MFA || !*c.App.Config().ServiceSettings.EnableMultifactorAuthentication {
   783  		w.Write([]byte(model.StringInterfaceToJson(resp)))
   784  		return
   785  	}
   786  
   787  	if *c.App.Config().ServiceSettings.ExperimentalEnableHardenedMode {
   788  		resp["mfa_required"] = true
   789  	} else if user, err := c.App.GetUserForLogin("", loginId); err == nil {
   790  		resp["mfa_required"] = user.MfaActive
   791  	}
   792  
   793  	w.Write([]byte(model.StringInterfaceToJson(resp)))
   794  }
   795  
   796  func updateUserMfa(c *Context, w http.ResponseWriter, r *http.Request) {
   797  	c.RequireUserId()
   798  	if c.Err != nil {
   799  		return
   800  	}
   801  
   802  	if c.Session.IsOAuth {
   803  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
   804  		c.Err.DetailedError += ", attempted access by oauth app"
   805  		return
   806  	}
   807  
   808  	if !c.App.SessionHasPermissionToUser(c.Session, c.Params.UserId) {
   809  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
   810  		return
   811  	}
   812  
   813  	props := model.StringInterfaceFromJson(r.Body)
   814  
   815  	activate, ok := props["activate"].(bool)
   816  	if !ok {
   817  		c.SetInvalidParam("activate")
   818  		return
   819  	}
   820  
   821  	code := ""
   822  	if activate {
   823  		code, ok = props["code"].(string)
   824  		if !ok || len(code) == 0 {
   825  			c.SetInvalidParam("code")
   826  			return
   827  		}
   828  	}
   829  
   830  	c.LogAudit("attempt")
   831  
   832  	if err := c.App.UpdateMfa(activate, c.Params.UserId, code); err != nil {
   833  		c.Err = err
   834  		return
   835  	}
   836  
   837  	c.LogAudit("success - mfa updated")
   838  	ReturnStatusOK(w)
   839  }
   840  
   841  func generateMfaSecret(c *Context, w http.ResponseWriter, r *http.Request) {
   842  	c.RequireUserId()
   843  	if c.Err != nil {
   844  		return
   845  	}
   846  
   847  	if c.Session.IsOAuth {
   848  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
   849  		c.Err.DetailedError += ", attempted access by oauth app"
   850  		return
   851  	}
   852  
   853  	if !c.App.SessionHasPermissionToUser(c.Session, c.Params.UserId) {
   854  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
   855  		return
   856  	}
   857  
   858  	secret, err := c.App.GenerateMfaSecret(c.Params.UserId)
   859  	if err != nil {
   860  		c.Err = err
   861  		return
   862  	}
   863  
   864  	w.Header().Set("Cache-Control", "no-cache")
   865  	w.Header().Set("Pragma", "no-cache")
   866  	w.Header().Set("Expires", "0")
   867  	w.Write([]byte(secret.ToJson()))
   868  }
   869  
   870  func updatePassword(c *Context, w http.ResponseWriter, r *http.Request) {
   871  	c.RequireUserId()
   872  	if c.Err != nil {
   873  		return
   874  	}
   875  
   876  	props := model.MapFromJson(r.Body)
   877  
   878  	newPassword := props["new_password"]
   879  
   880  	c.LogAudit("attempted")
   881  
   882  	var err *model.AppError
   883  	if c.Params.UserId == c.Session.UserId {
   884  		currentPassword := props["current_password"]
   885  		if len(currentPassword) <= 0 {
   886  			c.SetInvalidParam("current_password")
   887  			return
   888  		}
   889  
   890  		err = c.App.UpdatePasswordAsUser(c.Params.UserId, currentPassword, newPassword)
   891  	} else if c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM) {
   892  		err = c.App.UpdatePasswordByUserIdSendEmail(c.Params.UserId, newPassword, c.T("api.user.reset_password.method"))
   893  	} else {
   894  		err = model.NewAppError("updatePassword", "api.user.update_password.context.app_error", nil, "", http.StatusForbidden)
   895  	}
   896  
   897  	if err != nil {
   898  		c.LogAudit("failed")
   899  		c.Err = err
   900  		return
   901  	} else {
   902  		c.LogAudit("completed")
   903  		ReturnStatusOK(w)
   904  	}
   905  }
   906  
   907  func resetPassword(c *Context, w http.ResponseWriter, r *http.Request) {
   908  	props := model.MapFromJson(r.Body)
   909  
   910  	token := props["token"]
   911  	if len(token) != model.TOKEN_SIZE {
   912  		c.SetInvalidParam("token")
   913  		return
   914  	}
   915  
   916  	newPassword := props["new_password"]
   917  
   918  	c.LogAudit("attempt - token=" + token)
   919  
   920  	if err := c.App.ResetPasswordFromToken(token, newPassword); err != nil {
   921  		c.LogAudit("fail - token=" + token)
   922  		c.Err = err
   923  		return
   924  	}
   925  
   926  	c.LogAudit("success - token=" + token)
   927  
   928  	ReturnStatusOK(w)
   929  }
   930  
   931  func sendPasswordReset(c *Context, w http.ResponseWriter, r *http.Request) {
   932  	props := model.MapFromJson(r.Body)
   933  
   934  	email := props["email"]
   935  	if len(email) == 0 {
   936  		c.SetInvalidParam("email")
   937  		return
   938  	}
   939  
   940  	if sent, err := c.App.SendPasswordReset(email, c.App.GetSiteURL()); err != nil {
   941  		if *c.App.Config().ServiceSettings.ExperimentalEnableHardenedMode {
   942  			ReturnStatusOK(w)
   943  		} else {
   944  			c.Err = err
   945  		}
   946  		return
   947  	} else if sent {
   948  		c.LogAudit("sent=" + email)
   949  	}
   950  
   951  	ReturnStatusOK(w)
   952  }
   953  
   954  func login(c *Context, w http.ResponseWriter, r *http.Request) {
   955  	// For hardened mode, translate all login errors to generic.
   956  	defer func() {
   957  		if *c.App.Config().ServiceSettings.ExperimentalEnableHardenedMode && c.Err != nil {
   958  			c.Err = model.NewAppError("login", "api.user.login.invalid_credentials", nil, "", http.StatusUnauthorized)
   959  		}
   960  	}()
   961  
   962  	props := model.MapFromJson(r.Body)
   963  
   964  	id := props["id"]
   965  	loginId := props["login_id"]
   966  	password := props["password"]
   967  	mfaToken := props["token"]
   968  	deviceId := props["device_id"]
   969  	ldapOnly := props["ldap_only"] == "true"
   970  
   971  	c.LogAuditWithUserId(id, "attempt - login_id="+loginId)
   972  	user, err := c.App.AuthenticateUserForLogin(id, loginId, password, mfaToken, ldapOnly)
   973  	if err != nil {
   974  		c.LogAuditWithUserId(id, "failure - login_id="+loginId)
   975  		c.Err = err
   976  		return
   977  	}
   978  
   979  	c.LogAuditWithUserId(user.Id, "authenticated")
   980  
   981  	var session *model.Session
   982  	session, err = c.App.DoLogin(w, r, user, deviceId)
   983  	if err != nil {
   984  		c.Err = err
   985  		return
   986  	}
   987  
   988  	c.LogAuditWithUserId(user.Id, "success")
   989  
   990  	c.Session = *session
   991  
   992  	user.Sanitize(map[string]bool{})
   993  
   994  	w.Write([]byte(user.ToJson()))
   995  }
   996  
   997  func logout(c *Context, w http.ResponseWriter, r *http.Request) {
   998  	Logout(c, w, r)
   999  }
  1000  
  1001  func Logout(c *Context, w http.ResponseWriter, r *http.Request) {
  1002  	c.LogAudit("")
  1003  	c.RemoveSessionCookie(w, r)
  1004  	if c.Session.Id != "" {
  1005  		if err := c.App.RevokeSessionById(c.Session.Id); err != nil {
  1006  			c.Err = err
  1007  			return
  1008  		}
  1009  	}
  1010  
  1011  	ReturnStatusOK(w)
  1012  }
  1013  
  1014  func getSessions(c *Context, w http.ResponseWriter, r *http.Request) {
  1015  	c.RequireUserId()
  1016  	if c.Err != nil {
  1017  		return
  1018  	}
  1019  
  1020  	if !c.App.SessionHasPermissionToUser(c.Session, c.Params.UserId) {
  1021  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
  1022  		return
  1023  	}
  1024  
  1025  	if sessions, err := c.App.GetSessions(c.Params.UserId); err != nil {
  1026  		c.Err = err
  1027  		return
  1028  	} else {
  1029  		for _, session := range sessions {
  1030  			session.Sanitize()
  1031  		}
  1032  
  1033  		w.Write([]byte(model.SessionsToJson(sessions)))
  1034  		return
  1035  	}
  1036  }
  1037  
  1038  func revokeSession(c *Context, w http.ResponseWriter, r *http.Request) {
  1039  	c.RequireUserId()
  1040  	if c.Err != nil {
  1041  		return
  1042  	}
  1043  
  1044  	if !c.App.SessionHasPermissionToUser(c.Session, c.Params.UserId) {
  1045  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
  1046  		return
  1047  	}
  1048  
  1049  	props := model.MapFromJson(r.Body)
  1050  	sessionId := props["session_id"]
  1051  
  1052  	if sessionId == "" {
  1053  		c.SetInvalidParam("session_id")
  1054  		return
  1055  	}
  1056  
  1057  	var session *model.Session
  1058  	var err *model.AppError
  1059  	if session, err = c.App.GetSessionById(sessionId); err != nil {
  1060  		c.Err = err
  1061  		return
  1062  	}
  1063  
  1064  	if session.UserId != c.Params.UserId {
  1065  		c.SetInvalidUrlParam("user_id")
  1066  		return
  1067  	}
  1068  
  1069  	if err := c.App.RevokeSession(session); err != nil {
  1070  		c.Err = err
  1071  		return
  1072  	}
  1073  
  1074  	ReturnStatusOK(w)
  1075  }
  1076  
  1077  func revokeAllSessionsForUser(c *Context, w http.ResponseWriter, r *http.Request) {
  1078  	c.RequireUserId()
  1079  	if c.Err != nil {
  1080  		return
  1081  	}
  1082  
  1083  	if !c.App.SessionHasPermissionToUser(c.Session, c.Params.UserId) {
  1084  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
  1085  		return
  1086  	}
  1087  
  1088  	if err := c.App.RevokeAllSessions(c.Params.UserId); err != nil {
  1089  		c.Err = err
  1090  		return
  1091  	}
  1092  
  1093  	ReturnStatusOK(w)
  1094  }
  1095  
  1096  func attachDeviceId(c *Context, w http.ResponseWriter, r *http.Request) {
  1097  	props := model.MapFromJson(r.Body)
  1098  
  1099  	deviceId := props["device_id"]
  1100  	if len(deviceId) == 0 {
  1101  		c.SetInvalidParam("device_id")
  1102  		return
  1103  	}
  1104  
  1105  	// A special case where we logout of all other sessions with the same device id
  1106  	if err := c.App.RevokeSessionsForDeviceId(c.Session.UserId, deviceId, c.Session.Id); err != nil {
  1107  		c.Err = err
  1108  		return
  1109  	}
  1110  
  1111  	c.App.ClearSessionCacheForUser(c.Session.UserId)
  1112  	c.Session.SetExpireInDays(*c.App.Config().ServiceSettings.SessionLengthMobileInDays)
  1113  
  1114  	maxAge := *c.App.Config().ServiceSettings.SessionLengthMobileInDays * 60 * 60 * 24
  1115  
  1116  	secure := false
  1117  	if app.GetProtocol(r) == "https" {
  1118  		secure = true
  1119  	}
  1120  
  1121  	expiresAt := time.Unix(model.GetMillis()/1000+int64(maxAge), 0)
  1122  	sessionCookie := &http.Cookie{
  1123  		Name:     model.SESSION_COOKIE_TOKEN,
  1124  		Value:    c.Session.Token,
  1125  		Path:     "/",
  1126  		MaxAge:   maxAge,
  1127  		Expires:  expiresAt,
  1128  		HttpOnly: true,
  1129  		Domain:   c.App.GetCookieDomain(),
  1130  		Secure:   secure,
  1131  	}
  1132  
  1133  	http.SetCookie(w, sessionCookie)
  1134  
  1135  	if err := c.App.AttachDeviceId(c.Session.Id, deviceId, c.Session.ExpiresAt); err != nil {
  1136  		c.Err = err
  1137  		return
  1138  	}
  1139  
  1140  	c.LogAudit("")
  1141  	ReturnStatusOK(w)
  1142  }
  1143  
  1144  func getUserAudits(c *Context, w http.ResponseWriter, r *http.Request) {
  1145  	c.RequireUserId()
  1146  	if c.Err != nil {
  1147  		return
  1148  	}
  1149  
  1150  	if !c.App.SessionHasPermissionToUser(c.Session, c.Params.UserId) {
  1151  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
  1152  		return
  1153  	}
  1154  
  1155  	if audits, err := c.App.GetAuditsPage(c.Params.UserId, c.Params.Page, c.Params.PerPage); err != nil {
  1156  		c.Err = err
  1157  		return
  1158  	} else {
  1159  		w.Write([]byte(audits.ToJson()))
  1160  		return
  1161  	}
  1162  }
  1163  
  1164  func verifyUserEmail(c *Context, w http.ResponseWriter, r *http.Request) {
  1165  	props := model.MapFromJson(r.Body)
  1166  
  1167  	token := props["token"]
  1168  	if len(token) != model.TOKEN_SIZE {
  1169  		c.SetInvalidParam("token")
  1170  		return
  1171  	}
  1172  
  1173  	if err := c.App.VerifyEmailFromToken(token); err != nil {
  1174  		c.Err = model.NewAppError("verifyUserEmail", "api.user.verify_email.bad_link.app_error", nil, err.Error(), http.StatusBadRequest)
  1175  		return
  1176  	} else {
  1177  		c.LogAudit("Email Verified")
  1178  		ReturnStatusOK(w)
  1179  		return
  1180  	}
  1181  }
  1182  
  1183  func sendVerificationEmail(c *Context, w http.ResponseWriter, r *http.Request) {
  1184  	props := model.MapFromJson(r.Body)
  1185  
  1186  	email := props["email"]
  1187  	if len(email) == 0 {
  1188  		c.SetInvalidParam("email")
  1189  		return
  1190  	}
  1191  
  1192  	user, err := c.App.GetUserForLogin("", email)
  1193  	if err != nil {
  1194  		// Don't want to leak whether the email is valid or not
  1195  		ReturnStatusOK(w)
  1196  		return
  1197  	}
  1198  
  1199  	err = c.App.SendEmailVerification(user)
  1200  	if err != nil {
  1201  		// Don't want to leak whether the email is valid or not
  1202  		mlog.Error(err.Error())
  1203  		ReturnStatusOK(w)
  1204  		return
  1205  	}
  1206  
  1207  	ReturnStatusOK(w)
  1208  }
  1209  
  1210  func switchAccountType(c *Context, w http.ResponseWriter, r *http.Request) {
  1211  	switchRequest := model.SwitchRequestFromJson(r.Body)
  1212  	if switchRequest == nil {
  1213  		c.SetInvalidParam("switch_request")
  1214  		return
  1215  	}
  1216  
  1217  	link := ""
  1218  	var err *model.AppError
  1219  
  1220  	if switchRequest.EmailToOAuth() {
  1221  		link, err = c.App.SwitchEmailToOAuth(w, r, switchRequest.Email, switchRequest.Password, switchRequest.MfaCode, switchRequest.NewService)
  1222  	} else if switchRequest.OAuthToEmail() {
  1223  		c.SessionRequired()
  1224  		if c.Err != nil {
  1225  			return
  1226  		}
  1227  
  1228  		link, err = c.App.SwitchOAuthToEmail(switchRequest.Email, switchRequest.NewPassword, c.Session.UserId)
  1229  	} else if switchRequest.EmailToLdap() {
  1230  		link, err = c.App.SwitchEmailToLdap(switchRequest.Email, switchRequest.Password, switchRequest.MfaCode, switchRequest.LdapLoginId, switchRequest.NewPassword)
  1231  	} else if switchRequest.LdapToEmail() {
  1232  		link, err = c.App.SwitchLdapToEmail(switchRequest.Password, switchRequest.MfaCode, switchRequest.Email, switchRequest.NewPassword)
  1233  	} else {
  1234  		c.SetInvalidParam("switch_request")
  1235  		return
  1236  	}
  1237  
  1238  	if err != nil {
  1239  		c.Err = err
  1240  		return
  1241  	}
  1242  
  1243  	c.LogAudit("success")
  1244  	w.Write([]byte(model.MapToJson(map[string]string{"follow_link": link})))
  1245  }
  1246  
  1247  func createUserAccessToken(c *Context, w http.ResponseWriter, r *http.Request) {
  1248  	c.RequireUserId()
  1249  	if c.Err != nil {
  1250  		return
  1251  	}
  1252  
  1253  	if c.Session.IsOAuth {
  1254  		c.SetPermissionError(model.PERMISSION_CREATE_USER_ACCESS_TOKEN)
  1255  		c.Err.DetailedError += ", attempted access by oauth app"
  1256  		return
  1257  	}
  1258  
  1259  	accessToken := model.UserAccessTokenFromJson(r.Body)
  1260  	if accessToken == nil {
  1261  		c.SetInvalidParam("user_access_token")
  1262  		return
  1263  	}
  1264  
  1265  	if accessToken.Description == "" {
  1266  		c.SetInvalidParam("description")
  1267  		return
  1268  	}
  1269  
  1270  	c.LogAudit("")
  1271  
  1272  	if !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_CREATE_USER_ACCESS_TOKEN) {
  1273  		c.SetPermissionError(model.PERMISSION_CREATE_USER_ACCESS_TOKEN)
  1274  		return
  1275  	}
  1276  
  1277  	if !c.App.SessionHasPermissionToUser(c.Session, c.Params.UserId) {
  1278  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
  1279  		return
  1280  	}
  1281  
  1282  	accessToken.UserId = c.Params.UserId
  1283  	accessToken.Token = ""
  1284  
  1285  	var err *model.AppError
  1286  	accessToken, err = c.App.CreateUserAccessToken(accessToken)
  1287  	if err != nil {
  1288  		c.Err = err
  1289  		return
  1290  	}
  1291  
  1292  	c.LogAudit("success - token_id=" + accessToken.Id)
  1293  	w.Write([]byte(accessToken.ToJson()))
  1294  }
  1295  
  1296  func searchUserAccessTokens(c *Context, w http.ResponseWriter, r *http.Request) {
  1297  	if !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM) {
  1298  		c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
  1299  		return
  1300  	}
  1301  	props := model.UserAccessTokenSearchFromJson(r.Body)
  1302  	if props == nil {
  1303  		c.SetInvalidParam("user_access_token_search")
  1304  		return
  1305  	}
  1306  
  1307  	if len(props.Term) == 0 {
  1308  		c.SetInvalidParam("term")
  1309  		return
  1310  	}
  1311  	accessTokens, err := c.App.SearchUserAccessTokens(props.Term)
  1312  	if err != nil {
  1313  		c.Err = err
  1314  		return
  1315  	}
  1316  
  1317  	w.Write([]byte(model.UserAccessTokenListToJson(accessTokens)))
  1318  }
  1319  
  1320  func getUserAccessTokens(c *Context, w http.ResponseWriter, r *http.Request) {
  1321  	if !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM) {
  1322  		c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
  1323  		return
  1324  	}
  1325  
  1326  	accessTokens, err := c.App.GetUserAccessTokens(c.Params.Page, c.Params.PerPage)
  1327  	if err != nil {
  1328  		c.Err = err
  1329  		return
  1330  	}
  1331  
  1332  	w.Write([]byte(model.UserAccessTokenListToJson(accessTokens)))
  1333  }
  1334  
  1335  func getUserAccessTokensForUser(c *Context, w http.ResponseWriter, r *http.Request) {
  1336  	c.RequireUserId()
  1337  	if c.Err != nil {
  1338  		return
  1339  	}
  1340  
  1341  	if !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_READ_USER_ACCESS_TOKEN) {
  1342  		c.SetPermissionError(model.PERMISSION_READ_USER_ACCESS_TOKEN)
  1343  		return
  1344  	}
  1345  
  1346  	if !c.App.SessionHasPermissionToUser(c.Session, c.Params.UserId) {
  1347  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
  1348  		return
  1349  	}
  1350  
  1351  	accessTokens, err := c.App.GetUserAccessTokensForUser(c.Params.UserId, c.Params.Page, c.Params.PerPage)
  1352  	if err != nil {
  1353  		c.Err = err
  1354  		return
  1355  	}
  1356  
  1357  	w.Write([]byte(model.UserAccessTokenListToJson(accessTokens)))
  1358  }
  1359  
  1360  func getUserAccessToken(c *Context, w http.ResponseWriter, r *http.Request) {
  1361  	c.RequireTokenId()
  1362  	if c.Err != nil {
  1363  		return
  1364  	}
  1365  
  1366  	if !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_READ_USER_ACCESS_TOKEN) {
  1367  		c.SetPermissionError(model.PERMISSION_READ_USER_ACCESS_TOKEN)
  1368  		return
  1369  	}
  1370  
  1371  	accessToken, err := c.App.GetUserAccessToken(c.Params.TokenId, true)
  1372  	if err != nil {
  1373  		c.Err = err
  1374  		return
  1375  	}
  1376  
  1377  	if !c.App.SessionHasPermissionToUser(c.Session, accessToken.UserId) {
  1378  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
  1379  		return
  1380  	}
  1381  
  1382  	w.Write([]byte(accessToken.ToJson()))
  1383  }
  1384  
  1385  func revokeUserAccessToken(c *Context, w http.ResponseWriter, r *http.Request) {
  1386  	props := model.MapFromJson(r.Body)
  1387  	tokenId := props["token_id"]
  1388  
  1389  	if tokenId == "" {
  1390  		c.SetInvalidParam("token_id")
  1391  	}
  1392  
  1393  	c.LogAudit("")
  1394  
  1395  	if !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_REVOKE_USER_ACCESS_TOKEN) {
  1396  		c.SetPermissionError(model.PERMISSION_REVOKE_USER_ACCESS_TOKEN)
  1397  		return
  1398  	}
  1399  
  1400  	accessToken, err := c.App.GetUserAccessToken(tokenId, false)
  1401  	if err != nil {
  1402  		c.Err = err
  1403  		return
  1404  	}
  1405  
  1406  	if !c.App.SessionHasPermissionToUser(c.Session, accessToken.UserId) {
  1407  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
  1408  		return
  1409  	}
  1410  
  1411  	err = c.App.RevokeUserAccessToken(accessToken)
  1412  	if err != nil {
  1413  		c.Err = err
  1414  		return
  1415  	}
  1416  
  1417  	c.LogAudit("success - token_id=" + accessToken.Id)
  1418  	ReturnStatusOK(w)
  1419  }
  1420  
  1421  func disableUserAccessToken(c *Context, w http.ResponseWriter, r *http.Request) {
  1422  	props := model.MapFromJson(r.Body)
  1423  	tokenId := props["token_id"]
  1424  
  1425  	if tokenId == "" {
  1426  		c.SetInvalidParam("token_id")
  1427  	}
  1428  
  1429  	c.LogAudit("")
  1430  
  1431  	// No separate permission for this action for now
  1432  	if !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_REVOKE_USER_ACCESS_TOKEN) {
  1433  		c.SetPermissionError(model.PERMISSION_REVOKE_USER_ACCESS_TOKEN)
  1434  		return
  1435  	}
  1436  
  1437  	accessToken, err := c.App.GetUserAccessToken(tokenId, false)
  1438  	if err != nil {
  1439  		c.Err = err
  1440  		return
  1441  	}
  1442  
  1443  	if !c.App.SessionHasPermissionToUser(c.Session, accessToken.UserId) {
  1444  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
  1445  		return
  1446  	}
  1447  
  1448  	err = c.App.DisableUserAccessToken(accessToken)
  1449  	if err != nil {
  1450  		c.Err = err
  1451  		return
  1452  	}
  1453  
  1454  	c.LogAudit("success - token_id=" + accessToken.Id)
  1455  	ReturnStatusOK(w)
  1456  }
  1457  
  1458  func enableUserAccessToken(c *Context, w http.ResponseWriter, r *http.Request) {
  1459  	props := model.MapFromJson(r.Body)
  1460  	tokenId := props["token_id"]
  1461  
  1462  	if tokenId == "" {
  1463  		c.SetInvalidParam("token_id")
  1464  	}
  1465  
  1466  	c.LogAudit("")
  1467  
  1468  	// No separate permission for this action for now
  1469  	if !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_CREATE_USER_ACCESS_TOKEN) {
  1470  		c.SetPermissionError(model.PERMISSION_CREATE_USER_ACCESS_TOKEN)
  1471  		return
  1472  	}
  1473  
  1474  	accessToken, err := c.App.GetUserAccessToken(tokenId, false)
  1475  	if err != nil {
  1476  		c.Err = err
  1477  		return
  1478  	}
  1479  
  1480  	if !c.App.SessionHasPermissionToUser(c.Session, accessToken.UserId) {
  1481  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
  1482  		return
  1483  	}
  1484  
  1485  	err = c.App.EnableUserAccessToken(accessToken)
  1486  	if err != nil {
  1487  		c.Err = err
  1488  		return
  1489  	}
  1490  
  1491  	c.LogAudit("success - token_id=" + accessToken.Id)
  1492  	ReturnStatusOK(w)
  1493  }