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