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