github.com/psyb0t/mattermost-server@v4.6.1-0.20180125161845-5503a1351abf+incompatible/api/user.go (about)

     1  // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
     2  // See License.txt for license information.
     3  
     4  package api
     5  
     6  import (
     7  	b64 "encoding/base64"
     8  	"fmt"
     9  	"net/http"
    10  	"strconv"
    11  	"strings"
    12  	"time"
    13  
    14  	l4g "github.com/alecthomas/log4go"
    15  	"github.com/gorilla/mux"
    16  	"github.com/mattermost/mattermost-server/app"
    17  	"github.com/mattermost/mattermost-server/model"
    18  	"github.com/mattermost/mattermost-server/store"
    19  	"github.com/mattermost/mattermost-server/utils"
    20  )
    21  
    22  func (api *API) InitUser() {
    23  	api.BaseRoutes.Users.Handle("/create", api.ApiAppHandler(createUser)).Methods("POST")
    24  	api.BaseRoutes.Users.Handle("/update", api.ApiUserRequired(updateUser)).Methods("POST")
    25  	api.BaseRoutes.Users.Handle("/update_active", api.ApiUserRequired(updateActive)).Methods("POST")
    26  	api.BaseRoutes.Users.Handle("/update_notify", api.ApiUserRequired(updateUserNotify)).Methods("POST")
    27  	api.BaseRoutes.Users.Handle("/newpassword", api.ApiUserRequired(updatePassword)).Methods("POST")
    28  	api.BaseRoutes.Users.Handle("/send_password_reset", api.ApiAppHandler(sendPasswordReset)).Methods("POST")
    29  	api.BaseRoutes.Users.Handle("/reset_password", api.ApiAppHandler(resetPassword)).Methods("POST")
    30  	api.BaseRoutes.Users.Handle("/login", api.ApiAppHandler(login)).Methods("POST")
    31  	api.BaseRoutes.Users.Handle("/logout", api.ApiAppHandler(logout)).Methods("POST")
    32  	api.BaseRoutes.Users.Handle("/revoke_session", api.ApiUserRequired(revokeSession)).Methods("POST")
    33  	api.BaseRoutes.Users.Handle("/attach_device", api.ApiUserRequired(attachDeviceId)).Methods("POST")
    34  	//DEPRICATED FOR SECURITY USE APIV4 api.BaseRoutes.Users.Handle("/verify_email", ApiAppHandler(verifyEmail)).Methods("POST")
    35  	//DEPRICATED FOR SECURITY USE APIV4 api.BaseRoutes.Users.Handle("/resend_verification", ApiAppHandler(resendVerification)).Methods("POST")
    36  	api.BaseRoutes.Users.Handle("/newimage", api.ApiUserRequired(uploadProfileImage)).Methods("POST")
    37  	api.BaseRoutes.Users.Handle("/me", api.ApiUserRequired(getMe)).Methods("GET")
    38  	api.BaseRoutes.Users.Handle("/initial_load", api.ApiAppHandler(getInitialLoad)).Methods("GET")
    39  	api.BaseRoutes.Users.Handle("/{offset:[0-9]+}/{limit:[0-9]+}", api.ApiUserRequired(getProfiles)).Methods("GET")
    40  	api.BaseRoutes.NeedTeam.Handle("/users/{offset:[0-9]+}/{limit:[0-9]+}", api.ApiUserRequired(getProfilesInTeam)).Methods("GET")
    41  	api.BaseRoutes.NeedChannel.Handle("/users/{offset:[0-9]+}/{limit:[0-9]+}", api.ApiUserRequired(getProfilesInChannel)).Methods("GET")
    42  	api.BaseRoutes.NeedChannel.Handle("/users/not_in_channel/{offset:[0-9]+}/{limit:[0-9]+}", api.ApiUserRequired(getProfilesNotInChannel)).Methods("GET")
    43  	api.BaseRoutes.Users.Handle("/search", api.ApiUserRequired(searchUsers)).Methods("POST")
    44  	api.BaseRoutes.Users.Handle("/ids", api.ApiUserRequired(getProfilesByIds)).Methods("POST")
    45  	api.BaseRoutes.Users.Handle("/autocomplete", api.ApiUserRequired(autocompleteUsers)).Methods("GET")
    46  
    47  	api.BaseRoutes.NeedTeam.Handle("/users/autocomplete", api.ApiUserRequired(autocompleteUsersInTeam)).Methods("GET")
    48  	api.BaseRoutes.NeedChannel.Handle("/users/autocomplete", api.ApiUserRequired(autocompleteUsersInChannel)).Methods("GET")
    49  
    50  	api.BaseRoutes.Users.Handle("/mfa", api.ApiAppHandler(checkMfa)).Methods("POST")
    51  	api.BaseRoutes.Users.Handle("/generate_mfa_secret", api.ApiUserRequiredMfa(generateMfaSecret)).Methods("GET")
    52  	api.BaseRoutes.Users.Handle("/update_mfa", api.ApiUserRequiredMfa(updateMfa)).Methods("POST")
    53  
    54  	api.BaseRoutes.Users.Handle("/claim/email_to_oauth", api.ApiAppHandler(emailToOAuth)).Methods("POST")
    55  	api.BaseRoutes.Users.Handle("/claim/oauth_to_email", api.ApiUserRequired(oauthToEmail)).Methods("POST")
    56  	api.BaseRoutes.Users.Handle("/claim/email_to_ldap", api.ApiAppHandler(emailToLdap)).Methods("POST")
    57  	api.BaseRoutes.Users.Handle("/claim/ldap_to_email", api.ApiAppHandler(ldapToEmail)).Methods("POST")
    58  
    59  	api.BaseRoutes.NeedUser.Handle("/get", api.ApiUserRequired(getUser)).Methods("GET")
    60  	api.BaseRoutes.Users.Handle("/name/{username:[A-Za-z0-9_\\-.]+}", api.ApiUserRequired(getByUsername)).Methods("GET")
    61  	api.BaseRoutes.Users.Handle("/email/{email}", api.ApiUserRequired(getByEmail)).Methods("GET")
    62  	api.BaseRoutes.NeedUser.Handle("/sessions", api.ApiUserRequired(getSessions)).Methods("GET")
    63  	api.BaseRoutes.NeedUser.Handle("/audits", api.ApiUserRequired(getAudits)).Methods("GET")
    64  	api.BaseRoutes.NeedUser.Handle("/image", api.ApiUserRequiredTrustRequester(getProfileImage)).Methods("GET")
    65  	api.BaseRoutes.NeedUser.Handle("/update_roles", api.ApiUserRequired(updateRoles)).Methods("POST")
    66  
    67  	api.BaseRoutes.Root.Handle("/login/sso/saml", api.AppHandlerIndependent(loginWithSaml)).Methods("GET")
    68  	api.BaseRoutes.Root.Handle("/login/sso/saml", api.AppHandlerIndependent(completeSaml)).Methods("POST")
    69  }
    70  
    71  func createUser(c *Context, w http.ResponseWriter, r *http.Request) {
    72  	user := model.UserFromJson(r.Body)
    73  
    74  	if user == nil {
    75  		c.SetInvalidParam("createUser", "user")
    76  		return
    77  	}
    78  
    79  	hash := r.URL.Query().Get("h")
    80  	inviteId := r.URL.Query().Get("iid")
    81  
    82  	var ruser *model.User
    83  	var err *model.AppError
    84  	if len(hash) > 0 {
    85  		ruser, err = c.App.CreateUserWithHash(user, hash, r.URL.Query().Get("d"))
    86  	} else if len(inviteId) > 0 {
    87  		ruser, err = c.App.CreateUserWithInviteId(user, inviteId)
    88  	} else {
    89  		ruser, err = c.App.CreateUserFromSignup(user)
    90  	}
    91  
    92  	if err != nil {
    93  		c.Err = err
    94  		return
    95  	}
    96  
    97  	w.Write([]byte(ruser.ToJson()))
    98  }
    99  
   100  func login(c *Context, w http.ResponseWriter, r *http.Request) {
   101  	props := model.MapFromJson(r.Body)
   102  
   103  	id := props["id"]
   104  	loginId := props["login_id"]
   105  	password := props["password"]
   106  	mfaToken := props["token"]
   107  	deviceId := props["device_id"]
   108  	ldapOnly := props["ldap_only"] == "true"
   109  
   110  	c.LogAudit("attempt - user_id=" + id + " login_id=" + loginId)
   111  	user, err := c.App.AuthenticateUserForLogin(id, loginId, password, mfaToken, deviceId, ldapOnly)
   112  	if err != nil {
   113  		c.LogAudit("failure - user_id=" + id + " login_id=" + loginId)
   114  		c.Err = err
   115  		return
   116  	}
   117  
   118  	c.LogAuditWithUserId(user.Id, "success")
   119  
   120  	doLogin(c, w, r, user, deviceId)
   121  	if c.Err != nil {
   122  		return
   123  	}
   124  
   125  	user.Sanitize(map[string]bool{})
   126  
   127  	w.Write([]byte(user.ToJson()))
   128  }
   129  
   130  // User MUST be authenticated completely before calling Login
   131  func doLogin(c *Context, w http.ResponseWriter, r *http.Request, user *model.User, deviceId string) {
   132  	session, err := c.App.DoLogin(w, r, user, deviceId)
   133  	if err != nil {
   134  		c.Err = err
   135  		return
   136  	}
   137  
   138  	c.Session = *session
   139  }
   140  
   141  func revokeSession(c *Context, w http.ResponseWriter, r *http.Request) {
   142  	props := model.MapFromJson(r.Body)
   143  	id := props["id"]
   144  
   145  	if err := c.App.RevokeSessionById(id); err != nil {
   146  		c.Err = err
   147  		return
   148  	}
   149  
   150  	w.Write([]byte(model.MapToJson(props)))
   151  }
   152  
   153  func attachDeviceId(c *Context, w http.ResponseWriter, r *http.Request) {
   154  	props := model.MapFromJson(r.Body)
   155  
   156  	deviceId := props["device_id"]
   157  	if len(deviceId) == 0 {
   158  		c.SetInvalidParam("attachDevice", "deviceId")
   159  		return
   160  	}
   161  
   162  	// A special case where we logout of all other sessions with the same device id
   163  	if err := c.App.RevokeSessionsForDeviceId(c.Session.UserId, deviceId, c.Session.Id); err != nil {
   164  		c.Err = err
   165  		c.Err.StatusCode = http.StatusInternalServerError
   166  		return
   167  	}
   168  
   169  	c.App.ClearSessionCacheForUser(c.Session.UserId)
   170  	c.Session.SetExpireInDays(*c.App.Config().ServiceSettings.SessionLengthMobileInDays)
   171  
   172  	maxAge := *c.App.Config().ServiceSettings.SessionLengthMobileInDays * 60 * 60 * 24
   173  
   174  	secure := false
   175  	if app.GetProtocol(r) == "https" {
   176  		secure = true
   177  	}
   178  
   179  	expiresAt := time.Unix(model.GetMillis()/1000+int64(maxAge), 0)
   180  	sessionCookie := &http.Cookie{
   181  		Name:     model.SESSION_COOKIE_TOKEN,
   182  		Value:    c.Session.Token,
   183  		Path:     "/",
   184  		MaxAge:   maxAge,
   185  		Expires:  expiresAt,
   186  		HttpOnly: true,
   187  		Secure:   secure,
   188  	}
   189  
   190  	http.SetCookie(w, sessionCookie)
   191  
   192  	if err := c.App.AttachDeviceId(c.Session.Id, deviceId, c.Session.ExpiresAt); err != nil {
   193  		c.Err = err
   194  		return
   195  	}
   196  
   197  	w.Write([]byte(model.MapToJson(props)))
   198  }
   199  
   200  func getSessions(c *Context, w http.ResponseWriter, r *http.Request) {
   201  
   202  	params := mux.Vars(r)
   203  	id := params["user_id"]
   204  
   205  	if !c.App.SessionHasPermissionToUser(c.Session, id) {
   206  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
   207  		return
   208  	}
   209  
   210  	if sessions, err := c.App.GetSessions(id); err != nil {
   211  		c.Err = err
   212  		return
   213  	} else {
   214  		for _, session := range sessions {
   215  			session.Sanitize()
   216  		}
   217  
   218  		w.Write([]byte(model.SessionsToJson(sessions)))
   219  	}
   220  }
   221  
   222  func logout(c *Context, w http.ResponseWriter, r *http.Request) {
   223  	data := make(map[string]string)
   224  	data["user_id"] = c.Session.UserId
   225  
   226  	Logout(c, w, r)
   227  	if c.Err == nil {
   228  		w.Write([]byte(model.MapToJson(data)))
   229  	}
   230  }
   231  
   232  func Logout(c *Context, w http.ResponseWriter, r *http.Request) {
   233  	c.LogAudit("")
   234  	c.RemoveSessionCookie(w, r)
   235  	if c.Session.Id != "" {
   236  		if err := c.App.RevokeSessionById(c.Session.Id); err != nil {
   237  			c.Err = err
   238  			return
   239  		}
   240  	}
   241  }
   242  
   243  func getMe(c *Context, w http.ResponseWriter, r *http.Request) {
   244  
   245  	if user, err := c.App.GetUser(c.Session.UserId); err != nil {
   246  		c.Err = err
   247  		c.RemoveSessionCookie(w, r)
   248  		l4g.Error(utils.T("api.user.get_me.getting.error"), c.Session.UserId)
   249  		return
   250  	} else if c.HandleEtag(user.Etag(c.App.Config().PrivacySettings.ShowFullName, c.App.Config().PrivacySettings.ShowEmailAddress), "Get Me", w, r) {
   251  		return
   252  	} else {
   253  		user.Sanitize(map[string]bool{})
   254  		w.Header().Set(model.HEADER_ETAG_SERVER, user.Etag(c.App.Config().PrivacySettings.ShowFullName, c.App.Config().PrivacySettings.ShowEmailAddress))
   255  		w.Write([]byte(user.ToJson()))
   256  		return
   257  	}
   258  }
   259  
   260  func getInitialLoad(c *Context, w http.ResponseWriter, r *http.Request) {
   261  
   262  	il := model.InitialLoad{}
   263  
   264  	if len(c.Session.UserId) != 0 {
   265  		var err *model.AppError
   266  
   267  		il.User, err = c.App.GetUser(c.Session.UserId)
   268  		if err != nil {
   269  			c.Err = err
   270  			return
   271  		}
   272  		il.User.Sanitize(map[string]bool{})
   273  
   274  		il.Preferences, err = c.App.GetPreferencesForUser(c.Session.UserId)
   275  		if err != nil {
   276  			c.Err = err
   277  			return
   278  		}
   279  
   280  		il.Teams, err = c.App.GetTeamsForUser(c.Session.UserId)
   281  		if err != nil {
   282  			c.Err = err
   283  			return
   284  		}
   285  
   286  		for _, team := range il.Teams {
   287  			team.Sanitize()
   288  		}
   289  
   290  		il.TeamMembers = c.Session.TeamMembers
   291  	}
   292  
   293  	if c.App.SessionCacheLength() == 0 {
   294  		// Below is a special case when intializating a new server
   295  		// Lets check to make sure the server is really empty
   296  
   297  		il.NoAccounts = c.App.IsFirstUserAccount()
   298  	}
   299  
   300  	il.ClientCfg = c.App.ClientConfig()
   301  	if c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM) {
   302  		il.LicenseCfg = utils.ClientLicense()
   303  	} else {
   304  		il.LicenseCfg = utils.GetSanitizedClientLicense()
   305  	}
   306  
   307  	w.Write([]byte(il.ToJson()))
   308  }
   309  
   310  func getUser(c *Context, w http.ResponseWriter, r *http.Request) {
   311  	params := mux.Vars(r)
   312  	id := params["user_id"]
   313  
   314  	var user *model.User
   315  	var err *model.AppError
   316  
   317  	if user, err = c.App.GetUser(id); err != nil {
   318  		c.Err = err
   319  		return
   320  	}
   321  
   322  	etag := user.Etag(c.App.Config().PrivacySettings.ShowFullName, c.App.Config().PrivacySettings.ShowEmailAddress)
   323  
   324  	if c.HandleEtag(etag, "Get User", w, r) {
   325  		return
   326  	} else {
   327  		c.App.SanitizeProfile(user, c.IsSystemAdmin())
   328  		w.Header().Set(model.HEADER_ETAG_SERVER, etag)
   329  		w.Write([]byte(user.ToJson()))
   330  		return
   331  	}
   332  }
   333  
   334  func getByUsername(c *Context, w http.ResponseWriter, r *http.Request) {
   335  	params := mux.Vars(r)
   336  	username := params["username"]
   337  
   338  	var user *model.User
   339  	var err *model.AppError
   340  
   341  	if user, err = c.App.GetUserByUsername(username); err != nil {
   342  		c.Err = err
   343  		return
   344  	} else if c.HandleEtag(user.Etag(c.App.Config().PrivacySettings.ShowFullName, c.App.Config().PrivacySettings.ShowEmailAddress), "Get By Username", w, r) {
   345  		return
   346  	} else {
   347  		sanitizeProfile(c, user)
   348  
   349  		w.Header().Set(model.HEADER_ETAG_SERVER, user.Etag(c.App.Config().PrivacySettings.ShowFullName, c.App.Config().PrivacySettings.ShowEmailAddress))
   350  		w.Write([]byte(user.ToJson()))
   351  		return
   352  	}
   353  }
   354  
   355  func getByEmail(c *Context, w http.ResponseWriter, r *http.Request) {
   356  	params := mux.Vars(r)
   357  	email := params["email"]
   358  
   359  	if user, err := c.App.GetUserByEmail(email); err != nil {
   360  		c.Err = err
   361  		return
   362  	} else if c.HandleEtag(user.Etag(c.App.Config().PrivacySettings.ShowFullName, c.App.Config().PrivacySettings.ShowEmailAddress), "Get By Email", w, r) {
   363  		return
   364  	} else {
   365  		sanitizeProfile(c, user)
   366  
   367  		w.Header().Set(model.HEADER_ETAG_SERVER, user.Etag(c.App.Config().PrivacySettings.ShowFullName, c.App.Config().PrivacySettings.ShowEmailAddress))
   368  		w.Write([]byte(user.ToJson()))
   369  		return
   370  	}
   371  }
   372  
   373  func getProfiles(c *Context, w http.ResponseWriter, r *http.Request) {
   374  	params := mux.Vars(r)
   375  
   376  	offset, err := strconv.Atoi(params["offset"])
   377  	if err != nil {
   378  		c.SetInvalidParam("getProfiles", "offset")
   379  		return
   380  	}
   381  
   382  	limit, err := strconv.Atoi(params["limit"])
   383  	if err != nil {
   384  		c.SetInvalidParam("getProfiles", "limit")
   385  		return
   386  	}
   387  
   388  	etag := c.App.GetUsersEtag() + params["offset"] + "." + params["limit"]
   389  	if c.HandleEtag(etag, "Get Profiles", w, r) {
   390  		return
   391  	}
   392  
   393  	if profiles, err := c.App.GetUsersMap(offset, limit, c.IsSystemAdmin()); err != nil {
   394  		c.Err = err
   395  		return
   396  	} else {
   397  		w.Header().Set(model.HEADER_ETAG_SERVER, etag)
   398  		w.Write([]byte(model.UserMapToJson(profiles)))
   399  	}
   400  }
   401  
   402  func getProfilesInTeam(c *Context, w http.ResponseWriter, r *http.Request) {
   403  	params := mux.Vars(r)
   404  	teamId := params["team_id"]
   405  
   406  	if c.Session.GetTeamByTeamId(teamId) == nil {
   407  		if !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM) {
   408  			return
   409  		}
   410  	}
   411  
   412  	offset, err := strconv.Atoi(params["offset"])
   413  	if err != nil {
   414  		c.SetInvalidParam("getProfilesInTeam", "offset")
   415  		return
   416  	}
   417  
   418  	limit, err := strconv.Atoi(params["limit"])
   419  	if err != nil {
   420  		c.SetInvalidParam("getProfilesInTeam", "limit")
   421  		return
   422  	}
   423  
   424  	etag := c.App.GetUsersInTeamEtag(teamId)
   425  	if c.HandleEtag(etag, "Get Profiles In Team", w, r) {
   426  		return
   427  	}
   428  
   429  	if profiles, err := c.App.GetUsersInTeamMap(teamId, offset, limit, c.IsSystemAdmin()); err != nil {
   430  		c.Err = err
   431  		return
   432  	} else {
   433  		w.Header().Set(model.HEADER_ETAG_SERVER, etag)
   434  		w.Write([]byte(model.UserMapToJson(profiles)))
   435  	}
   436  }
   437  
   438  func getProfilesInChannel(c *Context, w http.ResponseWriter, r *http.Request) {
   439  	params := mux.Vars(r)
   440  	channelId := params["channel_id"]
   441  
   442  	offset, err := strconv.Atoi(params["offset"])
   443  	if err != nil {
   444  		c.SetInvalidParam("getProfiles", "offset")
   445  		return
   446  	}
   447  
   448  	limit, err := strconv.Atoi(params["limit"])
   449  	if err != nil {
   450  		c.SetInvalidParam("getProfiles", "limit")
   451  		return
   452  	}
   453  
   454  	if c.Session.GetTeamByTeamId(c.TeamId) == nil {
   455  		if !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM) {
   456  			c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
   457  			return
   458  		}
   459  	}
   460  
   461  	if !c.App.SessionHasPermissionToChannel(c.Session, channelId, model.PERMISSION_READ_CHANNEL) {
   462  		c.SetPermissionError(model.PERMISSION_READ_CHANNEL)
   463  		return
   464  	}
   465  
   466  	if profiles, err := c.App.GetUsersInChannelMap(channelId, offset, limit, c.IsSystemAdmin()); err != nil {
   467  		c.Err = err
   468  		return
   469  	} else {
   470  		w.Write([]byte(model.UserMapToJson(profiles)))
   471  	}
   472  }
   473  
   474  func getProfilesNotInChannel(c *Context, w http.ResponseWriter, r *http.Request) {
   475  	params := mux.Vars(r)
   476  	channelId := params["channel_id"]
   477  
   478  	if c.Session.GetTeamByTeamId(c.TeamId) == nil {
   479  		if !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM) {
   480  			c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
   481  			return
   482  		}
   483  	}
   484  
   485  	if !c.App.SessionHasPermissionToChannel(c.Session, channelId, model.PERMISSION_READ_CHANNEL) {
   486  		c.SetPermissionError(model.PERMISSION_READ_CHANNEL)
   487  		return
   488  	}
   489  
   490  	offset, err := strconv.Atoi(params["offset"])
   491  	if err != nil {
   492  		c.SetInvalidParam("getProfiles", "offset")
   493  		return
   494  	}
   495  
   496  	limit, err := strconv.Atoi(params["limit"])
   497  	if err != nil {
   498  		c.SetInvalidParam("getProfiles", "limit")
   499  		return
   500  	}
   501  
   502  	if profiles, err := c.App.GetUsersNotInChannelMap(c.TeamId, channelId, offset, limit, c.IsSystemAdmin()); err != nil {
   503  		c.Err = err
   504  		return
   505  	} else {
   506  		w.Write([]byte(model.UserMapToJson(profiles)))
   507  	}
   508  }
   509  
   510  func getAudits(c *Context, w http.ResponseWriter, r *http.Request) {
   511  	params := mux.Vars(r)
   512  	id := params["user_id"]
   513  
   514  	if !c.App.SessionHasPermissionToUser(c.Session, id) {
   515  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
   516  		return
   517  	}
   518  
   519  	if audits, err := c.App.GetAudits(id, 20); err != nil {
   520  		c.Err = err
   521  		return
   522  	} else {
   523  		etag := audits.Etag()
   524  
   525  		if c.HandleEtag(etag, "Get Audits", w, r) {
   526  			return
   527  		}
   528  
   529  		if len(etag) > 0 {
   530  			w.Header().Set(model.HEADER_ETAG_SERVER, etag)
   531  		}
   532  
   533  		w.Write([]byte(audits.ToJson()))
   534  		return
   535  	}
   536  }
   537  
   538  func getProfileImage(c *Context, w http.ResponseWriter, r *http.Request) {
   539  	params := mux.Vars(r)
   540  	id := params["user_id"]
   541  	readFailed := false
   542  
   543  	var etag string
   544  
   545  	if users, err := c.App.GetUsersByIds([]string{id}, false); err != nil {
   546  		c.Err = err
   547  		return
   548  	} else {
   549  		if len(users) == 0 {
   550  			c.Err = model.NewAppError("getProfileImage", "store.sql_user.get_profiles.app_error", nil, "", http.StatusInternalServerError)
   551  			return
   552  		}
   553  
   554  		user := users[0]
   555  		etag = strconv.FormatInt(user.LastPictureUpdate, 10)
   556  		if c.HandleEtag(etag, "Profile Image", w, r) {
   557  			return
   558  		}
   559  
   560  		var img []byte
   561  		img, readFailed, err = c.App.GetProfileImage(user)
   562  		if err != nil {
   563  			c.Err = err
   564  			return
   565  		}
   566  
   567  		if readFailed {
   568  			w.Header().Set("Cache-Control", "max-age=300, public") // 5 mins
   569  		} else {
   570  			w.Header().Set("Cache-Control", "max-age=86400, public") // 24 hrs
   571  			w.Header().Set(model.HEADER_ETAG_SERVER, etag)
   572  		}
   573  
   574  		w.Header().Set("Content-Type", "image/png")
   575  		w.Write(img)
   576  	}
   577  }
   578  
   579  func uploadProfileImage(c *Context, w http.ResponseWriter, r *http.Request) {
   580  	if len(*c.App.Config().FileSettings.DriverName) == 0 {
   581  		c.Err = model.NewAppError("uploadProfileImage", "api.user.upload_profile_user.storage.app_error", nil, "", http.StatusNotImplemented)
   582  		return
   583  	}
   584  
   585  	if r.ContentLength > *c.App.Config().FileSettings.MaxFileSize {
   586  		c.Err = model.NewAppError("uploadProfileImage", "api.user.upload_profile_user.too_large.app_error", nil, "", http.StatusRequestEntityTooLarge)
   587  		return
   588  	}
   589  
   590  	if err := r.ParseMultipartForm(*c.App.Config().FileSettings.MaxFileSize); err != nil {
   591  		c.Err = model.NewAppError("uploadProfileImage", "api.user.upload_profile_user.parse.app_error", nil, "", http.StatusBadRequest)
   592  		return
   593  	}
   594  
   595  	m := r.MultipartForm
   596  
   597  	imageArray, ok := m.File["image"]
   598  	if !ok {
   599  		c.Err = model.NewAppError("uploadProfileImage", "api.user.upload_profile_user.no_file.app_error", nil, "", http.StatusBadRequest)
   600  		return
   601  	}
   602  
   603  	if len(imageArray) <= 0 {
   604  		c.Err = model.NewAppError("uploadProfileImage", "api.user.upload_profile_user.array.app_error", nil, "", http.StatusBadRequest)
   605  		return
   606  	}
   607  
   608  	imageData := imageArray[0]
   609  
   610  	if err := c.App.SetProfileImage(c.Session.UserId, imageData); err != nil {
   611  		c.Err = err
   612  		return
   613  	}
   614  
   615  	c.LogAudit("")
   616  
   617  	// write something as the response since jQuery expects a json response
   618  	w.Write([]byte("true"))
   619  }
   620  
   621  func updateUser(c *Context, w http.ResponseWriter, r *http.Request) {
   622  	user := model.UserFromJson(r.Body)
   623  
   624  	if user == nil {
   625  		c.SetInvalidParam("updateUser", "user")
   626  		return
   627  	}
   628  
   629  	if !c.App.SessionHasPermissionToUser(c.Session, user.Id) {
   630  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
   631  		return
   632  	}
   633  
   634  	if ruser, err := c.App.UpdateUserAsUser(user, c.IsSystemAdmin()); err != nil {
   635  		c.Err = err
   636  		return
   637  	} else {
   638  		c.LogAudit("")
   639  		w.Write([]byte(ruser.ToJson()))
   640  	}
   641  }
   642  
   643  func updatePassword(c *Context, w http.ResponseWriter, r *http.Request) {
   644  	c.LogAudit("attempted")
   645  
   646  	props := model.MapFromJson(r.Body)
   647  	userId := props["user_id"]
   648  	if len(userId) != 26 {
   649  		c.SetInvalidParam("updatePassword", "user_id")
   650  		return
   651  	}
   652  
   653  	currentPassword := props["current_password"]
   654  	if len(currentPassword) <= 0 {
   655  		c.SetInvalidParam("updatePassword", "current_password")
   656  		return
   657  	}
   658  
   659  	newPassword := props["new_password"]
   660  
   661  	if userId != c.Session.UserId {
   662  		c.Err = model.NewAppError("updatePassword", "api.user.update_password.context.app_error", nil, "", http.StatusForbidden)
   663  		return
   664  	}
   665  
   666  	if err := c.App.UpdatePasswordAsUser(userId, currentPassword, newPassword); err != nil {
   667  		c.LogAudit("failed")
   668  		c.Err = err
   669  		return
   670  	} else {
   671  		c.LogAudit("completed")
   672  
   673  		data := make(map[string]string)
   674  		data["user_id"] = c.Session.UserId
   675  		w.Write([]byte(model.MapToJson(data)))
   676  	}
   677  }
   678  
   679  func updateRoles(c *Context, w http.ResponseWriter, r *http.Request) {
   680  	props := model.MapFromJson(r.Body)
   681  	params := mux.Vars(r)
   682  
   683  	userId := params["user_id"]
   684  	if len(userId) != 26 {
   685  		c.SetInvalidParam("updateMemberRoles", "user_id")
   686  		return
   687  	}
   688  
   689  	newRoles := props["new_roles"]
   690  	if !(model.IsValidUserRoles(newRoles)) {
   691  		c.SetInvalidParam("updateMemberRoles", "new_roles")
   692  		return
   693  	}
   694  
   695  	if !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_ROLES) {
   696  		c.SetPermissionError(model.PERMISSION_MANAGE_ROLES)
   697  		return
   698  	}
   699  
   700  	if _, err := c.App.UpdateUserRoles(userId, newRoles, true); err != nil {
   701  		return
   702  	} else {
   703  		c.LogAuditWithUserId(userId, "roles="+newRoles)
   704  	}
   705  
   706  	rdata := map[string]string{}
   707  	rdata["status"] = "ok"
   708  	w.Write([]byte(model.MapToJson(rdata)))
   709  }
   710  
   711  func updateActive(c *Context, w http.ResponseWriter, r *http.Request) {
   712  	props := model.MapFromJson(r.Body)
   713  
   714  	userId := props["user_id"]
   715  	if len(userId) != 26 {
   716  		c.SetInvalidParam("updateActive", "user_id")
   717  		return
   718  	}
   719  
   720  	active := props["active"] == "true"
   721  
   722  	// true when you're trying to de-activate yourself
   723  	isSelfDeactive := !active && userId == c.Session.UserId
   724  
   725  	if !isSelfDeactive && !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM) {
   726  		c.Err = model.NewAppError("updateActive", "api.user.update_active.permissions.app_error", nil, "userId="+userId, http.StatusForbidden)
   727  		return
   728  	}
   729  
   730  	var ruser *model.User
   731  	var err *model.AppError
   732  
   733  	if ruser, err = c.App.GetUser(userId); err != nil {
   734  		c.Err = err
   735  		return
   736  	}
   737  
   738  	if _, err := c.App.UpdateActive(ruser, active); err != nil {
   739  		c.Err = err
   740  	} else {
   741  		c.LogAuditWithUserId(ruser.Id, fmt.Sprintf("active=%v", active))
   742  		w.Write([]byte(ruser.ToJson()))
   743  	}
   744  }
   745  
   746  func sendPasswordReset(c *Context, w http.ResponseWriter, r *http.Request) {
   747  	props := model.MapFromJson(r.Body)
   748  
   749  	email := props["email"]
   750  	if len(email) == 0 {
   751  		c.SetInvalidParam("sendPasswordReset", "email")
   752  		return
   753  	}
   754  
   755  	if sent, err := c.App.SendPasswordReset(email, utils.GetSiteURL()); err != nil {
   756  		c.Err = err
   757  		return
   758  	} else if sent {
   759  		c.LogAudit("sent=" + email)
   760  	}
   761  
   762  	w.Write([]byte(model.MapToJson(props)))
   763  }
   764  
   765  func resetPassword(c *Context, w http.ResponseWriter, r *http.Request) {
   766  	props := model.MapFromJson(r.Body)
   767  
   768  	code := props["code"]
   769  	if len(code) != model.TOKEN_SIZE {
   770  		c.SetInvalidParam("resetPassword", "code")
   771  		return
   772  	}
   773  
   774  	newPassword := props["new_password"]
   775  
   776  	c.LogAudit("attempt - token=" + code)
   777  
   778  	if err := c.App.ResetPasswordFromToken(code, newPassword); err != nil {
   779  		c.LogAudit("fail - token=" + code)
   780  		c.Err = err
   781  		return
   782  	}
   783  
   784  	c.LogAudit("success - token=" + code)
   785  
   786  	rdata := map[string]string{}
   787  	rdata["status"] = "ok"
   788  	w.Write([]byte(model.MapToJson(rdata)))
   789  }
   790  
   791  func updateUserNotify(c *Context, w http.ResponseWriter, r *http.Request) {
   792  	props := model.MapFromJson(r.Body)
   793  
   794  	userId := props["user_id"]
   795  	if len(userId) != 26 {
   796  		c.SetInvalidParam("updateUserNotify", "user_id")
   797  		return
   798  	}
   799  
   800  	if !c.App.SessionHasPermissionToUser(c.Session, userId) {
   801  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
   802  		return
   803  	}
   804  
   805  	delete(props, "user_id")
   806  
   807  	email := props["email"]
   808  	if len(email) == 0 {
   809  		c.SetInvalidParam("updateUserNotify", "email")
   810  		return
   811  	}
   812  
   813  	desktop_sound := props["desktop_sound"]
   814  	if len(desktop_sound) == 0 {
   815  		c.SetInvalidParam("updateUserNotify", "desktop_sound")
   816  		return
   817  	}
   818  
   819  	desktop := props["desktop"]
   820  	if len(desktop) == 0 {
   821  		c.SetInvalidParam("updateUserNotify", "desktop")
   822  		return
   823  	}
   824  
   825  	comments := props["comments"]
   826  	if len(comments) == 0 {
   827  		c.SetInvalidParam("updateUserNotify", "comments")
   828  		return
   829  	}
   830  
   831  	ruser, err := c.App.UpdateUserNotifyProps(userId, props)
   832  	if err != nil {
   833  		c.Err = err
   834  		return
   835  	}
   836  
   837  	c.LogAuditWithUserId(ruser.Id, "")
   838  
   839  	options := c.App.Config().GetSanitizeOptions()
   840  	options["passwordupdate"] = false
   841  	ruser.Sanitize(options)
   842  	w.Write([]byte(ruser.ToJson()))
   843  }
   844  
   845  func emailToOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
   846  	props := model.MapFromJson(r.Body)
   847  
   848  	password := props["password"]
   849  	if len(password) == 0 {
   850  		c.SetInvalidParam("emailToOAuth", "password")
   851  		return
   852  	}
   853  
   854  	mfaToken := props["token"]
   855  
   856  	service := props["service"]
   857  	if len(service) == 0 {
   858  		c.SetInvalidParam("emailToOAuth", "service")
   859  		return
   860  	}
   861  
   862  	email := props["email"]
   863  	if len(email) == 0 {
   864  		c.SetInvalidParam("emailToOAuth", "email")
   865  		return
   866  	}
   867  
   868  	link, err := c.App.SwitchEmailToOAuth(w, r, email, password, mfaToken, service)
   869  	if err != nil {
   870  		c.Err = err
   871  		return
   872  	}
   873  
   874  	c.LogAudit("success for email=" + email)
   875  	w.Write([]byte(model.MapToJson(map[string]string{"follow_link": link})))
   876  }
   877  
   878  func oauthToEmail(c *Context, w http.ResponseWriter, r *http.Request) {
   879  	props := model.MapFromJson(r.Body)
   880  
   881  	password := props["password"]
   882  	if err := c.App.IsPasswordValid(password); err != nil {
   883  		c.Err = err
   884  		return
   885  	}
   886  
   887  	email := props["email"]
   888  	if len(email) == 0 {
   889  		c.SetInvalidParam("oauthToEmail", "email")
   890  		return
   891  	}
   892  
   893  	link, err := c.App.SwitchOAuthToEmail(email, password, c.Session.UserId)
   894  	if err != nil {
   895  		c.Err = err
   896  		return
   897  	}
   898  
   899  	c.RemoveSessionCookie(w, r)
   900  	if c.Err != nil {
   901  		return
   902  	}
   903  
   904  	c.LogAudit("success")
   905  	w.Write([]byte(model.MapToJson(map[string]string{"follow_link": link})))
   906  }
   907  
   908  func emailToLdap(c *Context, w http.ResponseWriter, r *http.Request) {
   909  	props := model.MapFromJson(r.Body)
   910  
   911  	email := props["email"]
   912  	if len(email) == 0 {
   913  		c.SetInvalidParam("emailToLdap", "email")
   914  		return
   915  	}
   916  
   917  	emailPassword := props["email_password"]
   918  	if len(emailPassword) == 0 {
   919  		c.SetInvalidParam("emailToLdap", "email_password")
   920  		return
   921  	}
   922  
   923  	ldapId := props["ldap_id"]
   924  	if len(ldapId) == 0 {
   925  		c.SetInvalidParam("emailToLdap", "ldap_id")
   926  		return
   927  	}
   928  
   929  	ldapPassword := props["ldap_password"]
   930  	if len(ldapPassword) == 0 {
   931  		c.SetInvalidParam("emailToLdap", "ldap_password")
   932  		return
   933  	}
   934  
   935  	token := props["token"]
   936  
   937  	c.LogAudit("attempt")
   938  
   939  	link, err := c.App.SwitchEmailToLdap(email, emailPassword, token, ldapId, ldapPassword)
   940  	if err != nil {
   941  		c.Err = err
   942  		return
   943  	}
   944  
   945  	c.RemoveSessionCookie(w, r)
   946  	if c.Err != nil {
   947  		return
   948  	}
   949  
   950  	c.LogAudit("success")
   951  	w.Write([]byte(model.MapToJson(map[string]string{"follow_link": link})))
   952  }
   953  
   954  func ldapToEmail(c *Context, w http.ResponseWriter, r *http.Request) {
   955  	props := model.MapFromJson(r.Body)
   956  
   957  	email := props["email"]
   958  	if len(email) == 0 {
   959  		c.SetInvalidParam("ldapToEmail", "email")
   960  		return
   961  	}
   962  
   963  	emailPassword := props["email_password"]
   964  	if err := c.App.IsPasswordValid(emailPassword); err != nil {
   965  		c.Err = err
   966  		return
   967  	}
   968  
   969  	ldapPassword := props["ldap_password"]
   970  	if len(ldapPassword) == 0 {
   971  		c.SetInvalidParam("ldapToEmail", "ldap_password")
   972  		return
   973  	}
   974  
   975  	token := props["token"]
   976  
   977  	c.LogAudit("attempt")
   978  
   979  	link, err := c.App.SwitchLdapToEmail(ldapPassword, token, email, emailPassword)
   980  	if err != nil {
   981  		c.Err = err
   982  		return
   983  	}
   984  
   985  	c.RemoveSessionCookie(w, r)
   986  	if c.Err != nil {
   987  		return
   988  	}
   989  
   990  	c.LogAudit("success")
   991  	w.Write([]byte(model.MapToJson(map[string]string{"follow_link": link})))
   992  }
   993  
   994  func generateMfaSecret(c *Context, w http.ResponseWriter, r *http.Request) {
   995  	secret, err := c.App.GenerateMfaSecret(c.Session.UserId)
   996  	if err != nil {
   997  		c.Err = err
   998  		return
   999  	}
  1000  
  1001  	w.Header().Set("Cache-Control", "no-cache")
  1002  	w.Header().Set("Pragma", "no-cache")
  1003  	w.Header().Set("Expires", "0")
  1004  	w.Write([]byte(secret.ToJson()))
  1005  }
  1006  
  1007  func updateMfa(c *Context, w http.ResponseWriter, r *http.Request) {
  1008  	props := model.StringInterfaceFromJson(r.Body)
  1009  
  1010  	activate, ok := props["activate"].(bool)
  1011  	if !ok {
  1012  		c.SetInvalidParam("updateMfa", "activate")
  1013  		return
  1014  	}
  1015  
  1016  	token := ""
  1017  	if activate {
  1018  		token = props["token"].(string)
  1019  		if len(token) == 0 {
  1020  			c.SetInvalidParam("updateMfa", "token")
  1021  			return
  1022  		}
  1023  	}
  1024  
  1025  	c.LogAudit("attempt")
  1026  
  1027  	if activate {
  1028  		if err := c.App.ActivateMfa(c.Session.UserId, token); err != nil {
  1029  			c.Err = err
  1030  			return
  1031  		}
  1032  		c.LogAudit("success - activated")
  1033  	} else {
  1034  		if err := c.App.DeactivateMfa(c.Session.UserId); err != nil {
  1035  			c.Err = err
  1036  			return
  1037  		}
  1038  		c.LogAudit("success - deactivated")
  1039  	}
  1040  
  1041  	c.App.Go(func() {
  1042  		var user *model.User
  1043  		var err *model.AppError
  1044  		if user, err = c.App.GetUser(c.Session.UserId); err != nil {
  1045  			l4g.Warn(err.Error())
  1046  			return
  1047  		}
  1048  
  1049  		if err := c.App.SendMfaChangeEmail(user.Email, activate, user.Locale, utils.GetSiteURL()); err != nil {
  1050  			l4g.Error(err.Error())
  1051  		}
  1052  	})
  1053  
  1054  	rdata := map[string]string{}
  1055  	rdata["status"] = "ok"
  1056  	w.Write([]byte(model.MapToJson(rdata)))
  1057  }
  1058  
  1059  func checkMfa(c *Context, w http.ResponseWriter, r *http.Request) {
  1060  	if !utils.IsLicensed() || !*utils.License().Features.MFA || !*c.App.Config().ServiceSettings.EnableMultifactorAuthentication {
  1061  		rdata := map[string]string{}
  1062  		rdata["mfa_required"] = "false"
  1063  		w.Write([]byte(model.MapToJson(rdata)))
  1064  		return
  1065  	}
  1066  
  1067  	props := model.MapFromJson(r.Body)
  1068  
  1069  	loginId := props["login_id"]
  1070  	if len(loginId) == 0 {
  1071  		c.SetInvalidParam("checkMfa", "login_id")
  1072  		return
  1073  	}
  1074  
  1075  	rdata := map[string]string{}
  1076  	if user, err := c.App.GetUserForLogin(loginId, false); err != nil {
  1077  		rdata["mfa_required"] = "false"
  1078  	} else {
  1079  		rdata["mfa_required"] = strconv.FormatBool(user.MfaActive)
  1080  	}
  1081  	w.Write([]byte(model.MapToJson(rdata)))
  1082  }
  1083  
  1084  func loginWithSaml(c *Context, w http.ResponseWriter, r *http.Request) {
  1085  	samlInterface := c.App.Saml
  1086  
  1087  	if samlInterface == nil {
  1088  		c.Err = model.NewAppError("loginWithSaml", "api.user.saml.not_available.app_error", nil, "", http.StatusFound)
  1089  		return
  1090  	}
  1091  
  1092  	teamId, err := c.App.GetTeamIdFromQuery(r.URL.Query())
  1093  	if err != nil {
  1094  		c.Err = err
  1095  		return
  1096  	}
  1097  	action := r.URL.Query().Get("action")
  1098  	redirectTo := r.URL.Query().Get("redirect_to")
  1099  	relayProps := map[string]string{}
  1100  	relayState := ""
  1101  
  1102  	if len(action) != 0 {
  1103  		relayProps["team_id"] = teamId
  1104  		relayProps["action"] = action
  1105  		if action == model.OAUTH_ACTION_EMAIL_TO_SSO {
  1106  			relayProps["email"] = r.URL.Query().Get("email")
  1107  		}
  1108  	}
  1109  
  1110  	if len(redirectTo) != 0 {
  1111  		relayProps["redirect_to"] = redirectTo
  1112  	}
  1113  
  1114  	if len(relayProps) > 0 {
  1115  		relayState = b64.StdEncoding.EncodeToString([]byte(model.MapToJson(relayProps)))
  1116  	}
  1117  
  1118  	if data, err := samlInterface.BuildRequest(relayState); err != nil {
  1119  		c.Err = err
  1120  		return
  1121  	} else {
  1122  		w.Header().Set("Content-Type", "application/x-www-form-urlencoded")
  1123  		http.Redirect(w, r, data.URL, http.StatusFound)
  1124  	}
  1125  }
  1126  
  1127  func completeSaml(c *Context, w http.ResponseWriter, r *http.Request) {
  1128  	samlInterface := c.App.Saml
  1129  
  1130  	if samlInterface == nil {
  1131  		c.Err = model.NewAppError("completeSaml", "api.user.saml.not_available.app_error", nil, "", http.StatusFound)
  1132  		return
  1133  	}
  1134  
  1135  	//Validate that the user is with SAML and all that
  1136  	encodedXML := r.FormValue("SAMLResponse")
  1137  	relayState := r.FormValue("RelayState")
  1138  
  1139  	relayProps := make(map[string]string)
  1140  	if len(relayState) > 0 {
  1141  		stateStr := ""
  1142  		if b, err := b64.StdEncoding.DecodeString(relayState); err != nil {
  1143  			c.Err = model.NewAppError("completeSaml", "api.user.authorize_oauth_user.invalid_state.app_error", nil, err.Error(), http.StatusFound)
  1144  			return
  1145  		} else {
  1146  			stateStr = string(b)
  1147  		}
  1148  		relayProps = model.MapFromJson(strings.NewReader(stateStr))
  1149  	}
  1150  
  1151  	action := relayProps["action"]
  1152  	if user, err := samlInterface.DoLogin(encodedXML, relayProps); err != nil {
  1153  		if action == model.OAUTH_ACTION_MOBILE {
  1154  			err.Translate(c.T)
  1155  			w.Write([]byte(err.ToJson()))
  1156  		} else {
  1157  			c.Err = err
  1158  			c.Err.StatusCode = http.StatusFound
  1159  		}
  1160  		return
  1161  	} else {
  1162  		if err := c.App.CheckUserAdditionalAuthenticationCriteria(user, ""); err != nil {
  1163  			c.Err = err
  1164  			c.Err.StatusCode = http.StatusFound
  1165  			return
  1166  		}
  1167  
  1168  		switch action {
  1169  		case model.OAUTH_ACTION_SIGNUP:
  1170  			teamId := relayProps["team_id"]
  1171  			if len(teamId) > 0 {
  1172  				c.App.Go(func() {
  1173  					c.App.AddDirectChannels(teamId, user)
  1174  				})
  1175  			}
  1176  		case model.OAUTH_ACTION_EMAIL_TO_SSO:
  1177  			if err := c.App.RevokeAllSessions(user.Id); err != nil {
  1178  				c.Err = err
  1179  				return
  1180  			}
  1181  			c.LogAuditWithUserId(user.Id, "Revoked all sessions for user")
  1182  			c.App.Go(func() {
  1183  				if err := c.App.SendSignInChangeEmail(user.Email, strings.Title(model.USER_AUTH_SERVICE_SAML)+" SSO", user.Locale, utils.GetSiteURL()); err != nil {
  1184  					l4g.Error(err.Error())
  1185  				}
  1186  			})
  1187  		}
  1188  		doLogin(c, w, r, user, "")
  1189  		if c.Err != nil {
  1190  			return
  1191  		}
  1192  
  1193  		if val, ok := relayProps["redirect_to"]; ok {
  1194  			http.Redirect(w, r, c.GetSiteURLHeader()+val, http.StatusFound)
  1195  			return
  1196  		}
  1197  
  1198  		if action == model.OAUTH_ACTION_MOBILE {
  1199  			ReturnStatusOK(w)
  1200  		} else {
  1201  			http.Redirect(w, r, app.GetProtocol(r)+"://"+r.Host, http.StatusFound)
  1202  		}
  1203  	}
  1204  }
  1205  
  1206  func sanitizeProfile(c *Context, user *model.User) *model.User {
  1207  	options := c.App.Config().GetSanitizeOptions()
  1208  
  1209  	if c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM) {
  1210  		options["email"] = true
  1211  		options["fullname"] = true
  1212  		options["authservice"] = true
  1213  	}
  1214  
  1215  	user.SanitizeProfile(options)
  1216  
  1217  	return user
  1218  }
  1219  
  1220  func searchUsers(c *Context, w http.ResponseWriter, r *http.Request) {
  1221  	props := model.UserSearchFromJson(r.Body)
  1222  	if props == nil {
  1223  		c.SetInvalidParam("searchUsers", "")
  1224  		return
  1225  	}
  1226  
  1227  	if len(props.Term) == 0 {
  1228  		c.SetInvalidParam("searchUsers", "term")
  1229  		return
  1230  	}
  1231  
  1232  	if props.InChannelId != "" && !c.App.SessionHasPermissionToChannel(c.Session, props.InChannelId, model.PERMISSION_READ_CHANNEL) {
  1233  		c.SetPermissionError(model.PERMISSION_READ_CHANNEL)
  1234  		return
  1235  	}
  1236  
  1237  	if props.NotInChannelId != "" && !c.App.SessionHasPermissionToChannel(c.Session, props.NotInChannelId, model.PERMISSION_READ_CHANNEL) {
  1238  		c.SetPermissionError(model.PERMISSION_READ_CHANNEL)
  1239  		return
  1240  	}
  1241  
  1242  	searchOptions := map[string]bool{}
  1243  	searchOptions[store.USER_SEARCH_OPTION_ALLOW_INACTIVE] = props.AllowInactive
  1244  
  1245  	if !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM) {
  1246  		hideFullName := !c.App.Config().PrivacySettings.ShowFullName
  1247  		hideEmail := !c.App.Config().PrivacySettings.ShowEmailAddress
  1248  
  1249  		if hideFullName && hideEmail {
  1250  			searchOptions[store.USER_SEARCH_OPTION_NAMES_ONLY_NO_FULL_NAME] = true
  1251  		} else if hideFullName {
  1252  			searchOptions[store.USER_SEARCH_OPTION_ALL_NO_FULL_NAME] = true
  1253  		} else if hideEmail {
  1254  			searchOptions[store.USER_SEARCH_OPTION_NAMES_ONLY] = true
  1255  		}
  1256  	}
  1257  
  1258  	if profiles, err := c.App.SearchUsers(props, searchOptions, c.IsSystemAdmin()); err != nil {
  1259  		c.Err = err
  1260  		return
  1261  	} else {
  1262  		w.Write([]byte(model.UserListToJson(profiles)))
  1263  	}
  1264  }
  1265  
  1266  func getProfilesByIds(c *Context, w http.ResponseWriter, r *http.Request) {
  1267  	userIds := model.ArrayFromJson(r.Body)
  1268  
  1269  	if len(userIds) == 0 {
  1270  		c.SetInvalidParam("getProfilesByIds", "user_ids")
  1271  		return
  1272  	}
  1273  
  1274  	if profiles, err := c.App.GetUsersByIds(userIds, c.IsSystemAdmin()); err != nil {
  1275  		c.Err = err
  1276  		return
  1277  	} else {
  1278  		profileMap := map[string]*model.User{}
  1279  		for _, p := range profiles {
  1280  			profileMap[p.Id] = p
  1281  		}
  1282  		w.Write([]byte(model.UserMapToJson(profileMap)))
  1283  	}
  1284  }
  1285  
  1286  func autocompleteUsersInChannel(c *Context, w http.ResponseWriter, r *http.Request) {
  1287  	params := mux.Vars(r)
  1288  	channelId := params["channel_id"]
  1289  	teamId := params["team_id"]
  1290  
  1291  	term := r.URL.Query().Get("term")
  1292  
  1293  	if c.Session.GetTeamByTeamId(teamId) == nil {
  1294  		if !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM) {
  1295  			return
  1296  		}
  1297  	}
  1298  
  1299  	if !c.App.SessionHasPermissionToChannel(c.Session, channelId, model.PERMISSION_READ_CHANNEL) {
  1300  		c.SetPermissionError(model.PERMISSION_READ_CHANNEL)
  1301  		return
  1302  	}
  1303  
  1304  	searchOptions := map[string]bool{}
  1305  
  1306  	hideFullName := !c.App.Config().PrivacySettings.ShowFullName
  1307  	if hideFullName && !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM) {
  1308  		searchOptions[store.USER_SEARCH_OPTION_NAMES_ONLY_NO_FULL_NAME] = true
  1309  	} else {
  1310  		searchOptions[store.USER_SEARCH_OPTION_NAMES_ONLY] = true
  1311  	}
  1312  
  1313  	autocomplete, err := c.App.AutocompleteUsersInChannel(teamId, channelId, term, searchOptions, c.IsSystemAdmin())
  1314  	if err != nil {
  1315  		c.Err = err
  1316  		return
  1317  	}
  1318  
  1319  	w.Write([]byte(autocomplete.ToJson()))
  1320  }
  1321  
  1322  func autocompleteUsersInTeam(c *Context, w http.ResponseWriter, r *http.Request) {
  1323  	params := mux.Vars(r)
  1324  	teamId := params["team_id"]
  1325  
  1326  	term := r.URL.Query().Get("term")
  1327  
  1328  	if c.Session.GetTeamByTeamId(teamId) == nil {
  1329  		if !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM) {
  1330  			return
  1331  		}
  1332  	}
  1333  
  1334  	searchOptions := map[string]bool{}
  1335  
  1336  	hideFullName := !c.App.Config().PrivacySettings.ShowFullName
  1337  	if hideFullName && !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM) {
  1338  		searchOptions[store.USER_SEARCH_OPTION_NAMES_ONLY_NO_FULL_NAME] = true
  1339  	} else {
  1340  		searchOptions[store.USER_SEARCH_OPTION_NAMES_ONLY] = true
  1341  	}
  1342  
  1343  	autocomplete, err := c.App.AutocompleteUsersInTeam(teamId, term, searchOptions, c.IsSystemAdmin())
  1344  	if err != nil {
  1345  		c.Err = err
  1346  		return
  1347  	}
  1348  
  1349  	w.Write([]byte(autocomplete.ToJson()))
  1350  }
  1351  
  1352  func autocompleteUsers(c *Context, w http.ResponseWriter, r *http.Request) {
  1353  	term := r.URL.Query().Get("term")
  1354  
  1355  	searchOptions := map[string]bool{}
  1356  
  1357  	hideFullName := !c.App.Config().PrivacySettings.ShowFullName
  1358  	if hideFullName && !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM) {
  1359  		searchOptions[store.USER_SEARCH_OPTION_NAMES_ONLY_NO_FULL_NAME] = true
  1360  	} else {
  1361  		searchOptions[store.USER_SEARCH_OPTION_NAMES_ONLY] = true
  1362  	}
  1363  
  1364  	var profiles []*model.User
  1365  	var err *model.AppError
  1366  
  1367  	if profiles, err = c.App.SearchUsersInTeam("", term, searchOptions, c.IsSystemAdmin()); err != nil {
  1368  		c.Err = err
  1369  		return
  1370  	}
  1371  
  1372  	w.Write([]byte(model.UserListToJson(profiles)))
  1373  }