github.com/vnforks/kid/v5@v5.22.1-0.20200408055009-b89d99c65676/api4/user.go (about)

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