github.com/turgay/mattermost-server@v5.3.2-0.20181002173352-2945e8a2b0ce+incompatible/api4/user.go (about)

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