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 }