github.com/adacta-ru/mattermost-server/v6@v6.0.0/api4/user.go (about) 1 // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. 2 // See LICENSE.txt for license information. 3 4 package api4 5 6 import ( 7 "encoding/json" 8 "fmt" 9 "io" 10 "io/ioutil" 11 "net/http" 12 "strconv" 13 "strings" 14 "time" 15 16 "github.com/adacta-ru/mattermost-server/v6/app" 17 "github.com/adacta-ru/mattermost-server/v6/audit" 18 "github.com/adacta-ru/mattermost-server/v6/mlog" 19 "github.com/adacta-ru/mattermost-server/v6/model" 20 "github.com/adacta-ru/mattermost-server/v6/store" 21 "github.com/adacta-ru/mattermost-server/v6/utils" 22 ) 23 24 func (api *API) InitUser() { 25 api.BaseRoutes.Users.Handle("", api.ApiHandler(createUser)).Methods("POST") 26 api.BaseRoutes.Users.Handle("", api.ApiSessionRequired(getUsers)).Methods("GET") 27 api.BaseRoutes.Users.Handle("/ids", api.ApiSessionRequired(getUsersByIds)).Methods("POST") 28 api.BaseRoutes.Users.Handle("/usernames", api.ApiSessionRequired(getUsersByNames)).Methods("POST") 29 api.BaseRoutes.Users.Handle("/known", api.ApiSessionRequired(getKnownUsers)).Methods("GET") 30 api.BaseRoutes.Users.Handle("/search", api.ApiSessionRequiredDisableWhenBusy(searchUsers)).Methods("POST") 31 api.BaseRoutes.Users.Handle("/autocomplete", api.ApiSessionRequired(autocompleteUsers)).Methods("GET") 32 api.BaseRoutes.Users.Handle("/stats", api.ApiSessionRequired(getTotalUsersStats)).Methods("GET") 33 api.BaseRoutes.Users.Handle("/stats/filtered", api.ApiSessionRequired(getFilteredUsersStats)).Methods("GET") 34 api.BaseRoutes.Users.Handle("/group_channels", api.ApiSessionRequired(getUsersByGroupChannelIds)).Methods("POST") 35 36 api.BaseRoutes.User.Handle("", api.ApiSessionRequired(getUser)).Methods("GET") 37 api.BaseRoutes.User.Handle("/image/default", api.ApiSessionRequiredTrustRequester(getDefaultProfileImage)).Methods("GET") 38 api.BaseRoutes.User.Handle("/image", api.ApiSessionRequiredTrustRequester(getProfileImage)).Methods("GET") 39 api.BaseRoutes.User.Handle("/image", api.ApiSessionRequired(setProfileImage)).Methods("POST") 40 api.BaseRoutes.User.Handle("/image", api.ApiSessionRequired(setDefaultProfileImage)).Methods("DELETE") 41 api.BaseRoutes.User.Handle("", api.ApiSessionRequired(updateUser)).Methods("PUT") 42 api.BaseRoutes.User.Handle("/patch", api.ApiSessionRequired(patchUser)).Methods("PUT") 43 api.BaseRoutes.User.Handle("", api.ApiSessionRequired(deleteUser)).Methods("DELETE") 44 api.BaseRoutes.User.Handle("/roles", api.ApiSessionRequired(updateUserRoles)).Methods("PUT") 45 api.BaseRoutes.User.Handle("/active", api.ApiSessionRequired(updateUserActive)).Methods("PUT") 46 api.BaseRoutes.User.Handle("/password", api.ApiSessionRequired(updatePassword)).Methods("PUT") 47 api.BaseRoutes.User.Handle("/promote", api.ApiSessionRequired(promoteGuestToUser)).Methods("POST") 48 api.BaseRoutes.User.Handle("/demote", api.ApiSessionRequired(demoteUserToGuest)).Methods("POST") 49 api.BaseRoutes.User.Handle("/convert_to_bot", api.ApiSessionRequired(convertUserToBot)).Methods("POST") 50 api.BaseRoutes.Users.Handle("/password/reset", api.ApiHandler(resetPassword)).Methods("POST") 51 api.BaseRoutes.Users.Handle("/password/reset/send", api.ApiHandler(sendPasswordReset)).Methods("POST") 52 api.BaseRoutes.Users.Handle("/email/verify", api.ApiHandler(verifyUserEmail)).Methods("POST") 53 api.BaseRoutes.Users.Handle("/email/verify/send", api.ApiHandler(sendVerificationEmail)).Methods("POST") 54 api.BaseRoutes.User.Handle("/email/verify/member", api.ApiSessionRequired(verifyUserEmailWithoutToken)).Methods("POST") 55 api.BaseRoutes.User.Handle("/terms_of_service", api.ApiSessionRequired(saveUserTermsOfService)).Methods("POST") 56 api.BaseRoutes.User.Handle("/terms_of_service", api.ApiSessionRequired(getUserTermsOfService)).Methods("GET") 57 58 api.BaseRoutes.User.Handle("/auth", api.ApiSessionRequiredTrustRequester(updateUserAuth)).Methods("PUT") 59 60 api.BaseRoutes.Users.Handle("/mfa", api.ApiHandler(checkUserMfa)).Methods("POST") 61 api.BaseRoutes.User.Handle("/mfa", api.ApiSessionRequiredMfa(updateUserMfa)).Methods("PUT") 62 api.BaseRoutes.User.Handle("/mfa/generate", api.ApiSessionRequiredMfa(generateMfaSecret)).Methods("POST") 63 64 api.BaseRoutes.Users.Handle("/login", api.ApiHandler(login)).Methods("POST") 65 api.BaseRoutes.Users.Handle("/login/switch", api.ApiHandler(switchAccountType)).Methods("POST") 66 api.BaseRoutes.Users.Handle("/login/cws", api.ApiHandlerTrustRequester(loginCWS)).Methods("POST") 67 api.BaseRoutes.Users.Handle("/logout", api.ApiHandler(logout)).Methods("POST") 68 69 api.BaseRoutes.UserByUsername.Handle("", api.ApiSessionRequired(getUserByUsername)).Methods("GET") 70 api.BaseRoutes.UserByEmail.Handle("", api.ApiSessionRequired(getUserByEmail)).Methods("GET") 71 72 api.BaseRoutes.User.Handle("/sessions", api.ApiSessionRequired(getSessions)).Methods("GET") 73 api.BaseRoutes.User.Handle("/sessions/revoke", api.ApiSessionRequired(revokeSession)).Methods("POST") 74 api.BaseRoutes.User.Handle("/sessions/revoke/all", api.ApiSessionRequired(revokeAllSessionsForUser)).Methods("POST") 75 api.BaseRoutes.Users.Handle("/sessions/revoke/all", api.ApiSessionRequired(revokeAllSessionsAllUsers)).Methods("POST") 76 api.BaseRoutes.Users.Handle("/sessions/device", api.ApiSessionRequired(attachDeviceId)).Methods("PUT") 77 api.BaseRoutes.User.Handle("/audits", api.ApiSessionRequired(getUserAudits)).Methods("GET") 78 79 api.BaseRoutes.User.Handle("/tokens", api.ApiSessionRequired(createUserAccessToken)).Methods("POST") 80 api.BaseRoutes.User.Handle("/tokens", api.ApiSessionRequired(getUserAccessTokensForUser)).Methods("GET") 81 api.BaseRoutes.Users.Handle("/tokens", api.ApiSessionRequired(getUserAccessTokens)).Methods("GET") 82 api.BaseRoutes.Users.Handle("/tokens/search", api.ApiSessionRequired(searchUserAccessTokens)).Methods("POST") 83 api.BaseRoutes.Users.Handle("/tokens/{token_id:[A-Za-z0-9]+}", api.ApiSessionRequired(getUserAccessToken)).Methods("GET") 84 api.BaseRoutes.Users.Handle("/tokens/revoke", api.ApiSessionRequired(revokeUserAccessToken)).Methods("POST") 85 api.BaseRoutes.Users.Handle("/tokens/disable", api.ApiSessionRequired(disableUserAccessToken)).Methods("POST") 86 api.BaseRoutes.Users.Handle("/tokens/enable", api.ApiSessionRequired(enableUserAccessToken)).Methods("POST") 87 88 api.BaseRoutes.User.Handle("/typing", api.ApiSessionRequiredDisableWhenBusy(publishUserTyping)).Methods("POST") 89 90 api.BaseRoutes.Users.Handle("/migrate_auth/ldap", api.ApiSessionRequired(migrateAuthToLDAP)).Methods("POST") 91 api.BaseRoutes.Users.Handle("/migrate_auth/saml", api.ApiSessionRequired(migrateAuthToSaml)).Methods("POST") 92 93 api.BaseRoutes.User.Handle("/uploads", api.ApiSessionRequired(getUploadsForUser)).Methods("GET") 94 95 api.BaseRoutes.UserThreads.Handle("", api.ApiSessionRequired(getThreadsForUser)).Methods("GET") 96 api.BaseRoutes.UserThreads.Handle("/read", api.ApiSessionRequired(updateReadStateAllThreadsByUser)).Methods("PUT") 97 98 api.BaseRoutes.UserThread.Handle("/following", api.ApiSessionRequired(followThreadByUser)).Methods("PUT") 99 api.BaseRoutes.UserThread.Handle("/following", api.ApiSessionRequired(unfollowThreadByUser)).Methods("DELETE") 100 api.BaseRoutes.UserThread.Handle("/read/{timestamp:[0-9]+}", api.ApiSessionRequired(updateReadStateThreadByUser)).Methods("PUT") 101 } 102 103 func createUser(c *Context, w http.ResponseWriter, r *http.Request) { 104 user := model.UserFromJson(r.Body) 105 if user == nil { 106 c.SetInvalidParam("user") 107 return 108 } 109 110 user.SanitizeInput(c.IsSystemAdmin()) 111 112 tokenId := r.URL.Query().Get("t") 113 inviteId := r.URL.Query().Get("iid") 114 redirect := r.URL.Query().Get("r") 115 116 auditRec := c.MakeAuditRecord("createUser", audit.Fail) 117 defer c.LogAuditRec(auditRec) 118 auditRec.AddMeta("invite_id", inviteId) 119 auditRec.AddMeta("user", user) 120 121 // No permission check required 122 123 var ruser *model.User 124 var err *model.AppError 125 if len(tokenId) > 0 { 126 token, nErr := c.App.Srv().Store.Token().GetByToken(tokenId) 127 if nErr != nil { 128 var status int 129 switch nErr.(type) { 130 case *store.ErrNotFound: 131 status = http.StatusNotFound 132 default: 133 status = http.StatusInternalServerError 134 } 135 c.Err = model.NewAppError("CreateUserWithToken", "api.user.create_user.signup_link_invalid.app_error", nil, nErr.Error(), status) 136 return 137 } 138 auditRec.AddMeta("token_type", token.Type) 139 140 if token.Type == app.TOKEN_TYPE_GUEST_INVITATION { 141 if c.App.Srv().License() == nil { 142 c.Err = model.NewAppError("CreateUserWithToken", "api.user.create_user.guest_accounts.license.app_error", nil, "", http.StatusBadRequest) 143 return 144 } 145 if !*c.App.Config().GuestAccountsSettings.Enable { 146 c.Err = model.NewAppError("CreateUserWithToken", "api.user.create_user.guest_accounts.disabled.app_error", nil, "", http.StatusBadRequest) 147 return 148 } 149 } 150 ruser, err = c.App.CreateUserWithToken(user, token) 151 } else if len(inviteId) > 0 { 152 ruser, err = c.App.CreateUserWithInviteId(user, inviteId, redirect) 153 } else if c.IsSystemAdmin() { 154 ruser, err = c.App.CreateUserAsAdmin(user, redirect) 155 auditRec.AddMeta("admin", true) 156 } else { 157 ruser, err = c.App.CreateUserFromSignup(user, redirect) 158 } 159 160 if err != nil { 161 c.Err = err 162 return 163 } 164 165 // New user created, check cloud limits and send emails if needed 166 // Soft fail on error since user is already created 167 if ruser != nil { 168 err = c.App.CheckAndSendUserLimitWarningEmails() 169 if err != nil { 170 mlog.Error(err.Error()) 171 } 172 } 173 174 auditRec.Success() 175 auditRec.AddMeta("user", ruser) // overwrite meta 176 177 w.WriteHeader(http.StatusCreated) 178 w.Write([]byte(ruser.ToJson())) 179 } 180 181 func getUser(c *Context, w http.ResponseWriter, r *http.Request) { 182 c.RequireUserId() 183 if c.Err != nil { 184 return 185 } 186 187 canSee, err := c.App.UserCanSeeOtherUser(c.App.Session().UserId, c.Params.UserId) 188 if err != nil { 189 c.SetPermissionError(model.PERMISSION_VIEW_MEMBERS) 190 return 191 } 192 193 if !canSee { 194 c.SetPermissionError(model.PERMISSION_VIEW_MEMBERS) 195 return 196 } 197 198 user, err := c.App.GetUser(c.Params.UserId) 199 if err != nil { 200 c.Err = err 201 return 202 } 203 204 if c.IsSystemAdmin() || c.App.Session().UserId == user.Id { 205 userTermsOfService, err := c.App.GetUserTermsOfService(user.Id) 206 if err != nil && err.StatusCode != http.StatusNotFound { 207 c.Err = err 208 return 209 } 210 211 if userTermsOfService != nil { 212 user.TermsOfServiceId = userTermsOfService.TermsOfServiceId 213 user.TermsOfServiceCreateAt = userTermsOfService.CreateAt 214 } 215 } 216 217 etag := user.Etag(*c.App.Config().PrivacySettings.ShowFullName, *c.App.Config().PrivacySettings.ShowEmailAddress) 218 219 if c.HandleEtag(etag, "Get User", w, r) { 220 return 221 } 222 223 if c.App.Session().UserId == user.Id { 224 user.Sanitize(map[string]bool{}) 225 } else { 226 c.App.SanitizeProfile(user, c.IsSystemAdmin()) 227 } 228 c.App.UpdateLastActivityAtIfNeeded(*c.App.Session()) 229 w.Header().Set(model.HEADER_ETAG_SERVER, etag) 230 w.Write([]byte(user.ToJson())) 231 } 232 233 func getUserByUsername(c *Context, w http.ResponseWriter, r *http.Request) { 234 c.RequireUsername() 235 if c.Err != nil { 236 return 237 } 238 239 user, err := c.App.GetUserByUsername(c.Params.Username) 240 if err != nil { 241 restrictions, err2 := c.App.GetViewUsersRestrictions(c.App.Session().UserId) 242 if err2 != nil { 243 c.Err = err2 244 return 245 } 246 if restrictions != nil { 247 c.SetPermissionError(model.PERMISSION_VIEW_MEMBERS) 248 return 249 } 250 c.Err = err 251 return 252 } 253 254 canSee, err := c.App.UserCanSeeOtherUser(c.App.Session().UserId, user.Id) 255 if err != nil { 256 c.Err = err 257 return 258 } 259 260 if !canSee { 261 c.SetPermissionError(model.PERMISSION_VIEW_MEMBERS) 262 return 263 } 264 265 if c.IsSystemAdmin() || c.App.Session().UserId == user.Id { 266 userTermsOfService, err := c.App.GetUserTermsOfService(user.Id) 267 if err != nil && err.StatusCode != http.StatusNotFound { 268 c.Err = err 269 return 270 } 271 272 if userTermsOfService != nil { 273 user.TermsOfServiceId = userTermsOfService.TermsOfServiceId 274 user.TermsOfServiceCreateAt = userTermsOfService.CreateAt 275 } 276 } 277 278 etag := user.Etag(*c.App.Config().PrivacySettings.ShowFullName, *c.App.Config().PrivacySettings.ShowEmailAddress) 279 280 if c.HandleEtag(etag, "Get User", w, r) { 281 return 282 } 283 284 if c.App.Session().UserId == user.Id { 285 user.Sanitize(map[string]bool{}) 286 } else { 287 c.App.SanitizeProfile(user, c.IsSystemAdmin()) 288 } 289 w.Header().Set(model.HEADER_ETAG_SERVER, etag) 290 w.Write([]byte(user.ToJson())) 291 } 292 293 func getUserByEmail(c *Context, w http.ResponseWriter, r *http.Request) { 294 c.SanitizeEmail() 295 if c.Err != nil { 296 return 297 } 298 299 sanitizeOptions := c.App.GetSanitizeOptions(c.IsSystemAdmin()) 300 if !sanitizeOptions["email"] { 301 c.Err = model.NewAppError("getUserByEmail", "api.user.get_user_by_email.permissions.app_error", nil, "userId="+c.App.Session().UserId, http.StatusForbidden) 302 return 303 } 304 305 user, err := c.App.GetUserByEmail(c.Params.Email) 306 if err != nil { 307 restrictions, err2 := c.App.GetViewUsersRestrictions(c.App.Session().UserId) 308 if err2 != nil { 309 c.Err = err2 310 return 311 } 312 if restrictions != nil { 313 c.SetPermissionError(model.PERMISSION_VIEW_MEMBERS) 314 return 315 } 316 c.Err = err 317 return 318 } 319 320 canSee, err := c.App.UserCanSeeOtherUser(c.App.Session().UserId, user.Id) 321 if err != nil { 322 c.Err = err 323 return 324 } 325 326 if !canSee { 327 c.SetPermissionError(model.PERMISSION_VIEW_MEMBERS) 328 return 329 } 330 331 etag := user.Etag(*c.App.Config().PrivacySettings.ShowFullName, *c.App.Config().PrivacySettings.ShowEmailAddress) 332 333 if c.HandleEtag(etag, "Get User", w, r) { 334 return 335 } 336 337 c.App.SanitizeProfile(user, c.IsSystemAdmin()) 338 w.Header().Set(model.HEADER_ETAG_SERVER, etag) 339 w.Write([]byte(user.ToJson())) 340 } 341 342 func getDefaultProfileImage(c *Context, w http.ResponseWriter, r *http.Request) { 343 c.RequireUserId() 344 if c.Err != nil { 345 return 346 } 347 348 canSee, err := c.App.UserCanSeeOtherUser(c.App.Session().UserId, c.Params.UserId) 349 if err != nil { 350 c.Err = err 351 return 352 } 353 354 if !canSee { 355 c.SetPermissionError(model.PERMISSION_VIEW_MEMBERS) 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 img, err := c.App.GetDefaultProfileImage(user) 366 if err != nil { 367 c.Err = err 368 return 369 } 370 371 w.Header().Set("Cache-Control", fmt.Sprintf("max-age=%v, public", 24*60*60)) // 24 hrs 372 w.Header().Set("Content-Type", "image/png") 373 w.Write(img) 374 } 375 376 func getProfileImage(c *Context, w http.ResponseWriter, r *http.Request) { 377 c.RequireUserId() 378 if c.Err != nil { 379 return 380 } 381 382 canSee, err := c.App.UserCanSeeOtherUser(c.App.Session().UserId, c.Params.UserId) 383 if err != nil { 384 c.Err = err 385 return 386 } 387 388 if !canSee { 389 c.SetPermissionError(model.PERMISSION_VIEW_MEMBERS) 390 return 391 } 392 393 user, err := c.App.GetUser(c.Params.UserId) 394 if err != nil { 395 c.Err = err 396 return 397 } 398 399 etag := strconv.FormatInt(user.LastPictureUpdate, 10) 400 if c.HandleEtag(etag, "Get Profile Image", w, r) { 401 return 402 } 403 404 img, readFailed, err := c.App.GetProfileImage(user) 405 if err != nil { 406 c.Err = err 407 return 408 } 409 410 if readFailed { 411 w.Header().Set("Cache-Control", fmt.Sprintf("max-age=%v, public", 5*60)) // 5 mins 412 } else { 413 w.Header().Set("Cache-Control", fmt.Sprintf("max-age=%v, public", 24*60*60)) // 24 hrs 414 w.Header().Set(model.HEADER_ETAG_SERVER, etag) 415 } 416 417 w.Header().Set("Content-Type", "image/png") 418 w.Write(img) 419 } 420 421 func setProfileImage(c *Context, w http.ResponseWriter, r *http.Request) { 422 defer io.Copy(ioutil.Discard, r.Body) 423 424 c.RequireUserId() 425 if c.Err != nil { 426 return 427 } 428 429 if !c.App.SessionHasPermissionToUser(*c.App.Session(), c.Params.UserId) { 430 c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS) 431 return 432 } 433 434 if len(*c.App.Config().FileSettings.DriverName) == 0 { 435 c.Err = model.NewAppError("uploadProfileImage", "api.user.upload_profile_user.storage.app_error", nil, "", http.StatusNotImplemented) 436 return 437 } 438 439 if r.ContentLength > *c.App.Config().FileSettings.MaxFileSize { 440 c.Err = model.NewAppError("uploadProfileImage", "api.user.upload_profile_user.too_large.app_error", nil, "", http.StatusRequestEntityTooLarge) 441 return 442 } 443 444 if err := r.ParseMultipartForm(*c.App.Config().FileSettings.MaxFileSize); err != nil { 445 c.Err = model.NewAppError("uploadProfileImage", "api.user.upload_profile_user.parse.app_error", nil, err.Error(), http.StatusInternalServerError) 446 return 447 } 448 449 m := r.MultipartForm 450 imageArray, ok := m.File["image"] 451 if !ok { 452 c.Err = model.NewAppError("uploadProfileImage", "api.user.upload_profile_user.no_file.app_error", nil, "", http.StatusBadRequest) 453 return 454 } 455 456 if len(imageArray) <= 0 { 457 c.Err = model.NewAppError("uploadProfileImage", "api.user.upload_profile_user.array.app_error", nil, "", http.StatusBadRequest) 458 return 459 } 460 461 auditRec := c.MakeAuditRecord("setProfileImage", audit.Fail) 462 defer c.LogAuditRec(auditRec) 463 if imageArray[0] != nil { 464 auditRec.AddMeta("filename", imageArray[0].Filename) 465 } 466 467 if user, err := c.App.GetUser(c.Params.UserId); err == nil { 468 auditRec.AddMeta("user", user) 469 } 470 471 imageData := imageArray[0] 472 if err := c.App.SetProfileImage(c.Params.UserId, imageData); err != nil { 473 c.Err = err 474 return 475 } 476 477 auditRec.Success() 478 c.LogAudit("") 479 480 ReturnStatusOK(w) 481 } 482 483 func setDefaultProfileImage(c *Context, w http.ResponseWriter, r *http.Request) { 484 c.RequireUserId() 485 if c.Err != nil { 486 return 487 } 488 489 if !c.App.SessionHasPermissionToUser(*c.App.Session(), c.Params.UserId) { 490 c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS) 491 return 492 } 493 494 if len(*c.App.Config().FileSettings.DriverName) == 0 { 495 c.Err = model.NewAppError("setDefaultProfileImage", "api.user.upload_profile_user.storage.app_error", nil, "", http.StatusNotImplemented) 496 return 497 } 498 499 auditRec := c.MakeAuditRecord("setDefaultProfileImage", audit.Fail) 500 defer c.LogAuditRec(auditRec) 501 502 user, err := c.App.GetUser(c.Params.UserId) 503 if err != nil { 504 c.Err = err 505 return 506 } 507 auditRec.AddMeta("user", user) 508 509 if err := c.App.SetDefaultProfileImage(user); err != nil { 510 c.Err = err 511 return 512 } 513 514 auditRec.Success() 515 c.LogAudit("") 516 517 ReturnStatusOK(w) 518 } 519 520 func getTotalUsersStats(c *Context, w http.ResponseWriter, r *http.Request) { 521 if c.Err != nil { 522 return 523 } 524 525 restrictions, err := c.App.GetViewUsersRestrictions(c.App.Session().UserId) 526 if err != nil { 527 c.Err = err 528 return 529 } 530 531 stats, err := c.App.GetTotalUsersStats(restrictions) 532 if err != nil { 533 c.Err = err 534 return 535 } 536 537 w.Write([]byte(stats.ToJson())) 538 } 539 540 func getFilteredUsersStats(c *Context, w http.ResponseWriter, r *http.Request) { 541 teamID := r.URL.Query().Get("in_team") 542 channelID := r.URL.Query().Get("in_channel") 543 includeDeleted := r.URL.Query().Get("include_deleted") 544 includeBotAccounts := r.URL.Query().Get("include_bots") 545 rolesString := r.URL.Query().Get("roles") 546 channelRolesString := r.URL.Query().Get("channel_roles") 547 teamRolesString := r.URL.Query().Get("team_roles") 548 549 includeDeletedBool, _ := strconv.ParseBool(includeDeleted) 550 includeBotAccountsBool, _ := strconv.ParseBool(includeBotAccounts) 551 552 roles := []string{} 553 var rolesValid bool 554 if rolesString != "" { 555 roles, rolesValid = model.CleanRoleNames(strings.Split(rolesString, ",")) 556 if !rolesValid { 557 c.SetInvalidParam("roles") 558 return 559 } 560 } 561 channelRoles := []string{} 562 if channelRolesString != "" && channelID != "" { 563 channelRoles, rolesValid = model.CleanRoleNames(strings.Split(channelRolesString, ",")) 564 if !rolesValid { 565 c.SetInvalidParam("channelRoles") 566 return 567 } 568 } 569 teamRoles := []string{} 570 if teamRolesString != "" && teamID != "" { 571 teamRoles, rolesValid = model.CleanRoleNames(strings.Split(teamRolesString, ",")) 572 if !rolesValid { 573 c.SetInvalidParam("teamRoles") 574 return 575 } 576 } 577 578 options := &model.UserCountOptions{ 579 IncludeDeleted: includeDeletedBool, 580 IncludeBotAccounts: includeBotAccountsBool, 581 TeamId: teamID, 582 ChannelId: channelID, 583 Roles: roles, 584 ChannelRoles: channelRoles, 585 TeamRoles: teamRoles, 586 } 587 588 if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_USERS) { 589 c.SetPermissionError(model.PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_USERS) 590 return 591 } 592 593 stats, err := c.App.GetFilteredUsersStats(options) 594 if err != nil { 595 c.Err = err 596 return 597 } 598 599 w.Write([]byte(stats.ToJson())) 600 } 601 602 func getUsersByGroupChannelIds(c *Context, w http.ResponseWriter, r *http.Request) { 603 channelIds := model.ArrayFromJson(r.Body) 604 605 if len(channelIds) == 0 { 606 c.SetInvalidParam("channel_ids") 607 return 608 } 609 610 usersByChannelId, err := c.App.GetUsersByGroupChannelIds(channelIds, c.IsSystemAdmin()) 611 if err != nil { 612 c.Err = err 613 return 614 } 615 616 b, _ := json.Marshal(usersByChannelId) 617 w.Write(b) 618 } 619 620 func getUsers(c *Context, w http.ResponseWriter, r *http.Request) { 621 inTeamId := r.URL.Query().Get("in_team") 622 notInTeamId := r.URL.Query().Get("not_in_team") 623 inChannelId := r.URL.Query().Get("in_channel") 624 inGroupId := r.URL.Query().Get("in_group") 625 notInChannelId := r.URL.Query().Get("not_in_channel") 626 groupConstrained := r.URL.Query().Get("group_constrained") 627 withoutTeam := r.URL.Query().Get("without_team") 628 inactive := r.URL.Query().Get("inactive") 629 active := r.URL.Query().Get("active") 630 role := r.URL.Query().Get("role") 631 sort := r.URL.Query().Get("sort") 632 rolesString := r.URL.Query().Get("roles") 633 channelRolesString := r.URL.Query().Get("channel_roles") 634 teamRolesString := r.URL.Query().Get("team_roles") 635 636 if len(notInChannelId) > 0 && len(inTeamId) == 0 { 637 c.SetInvalidUrlParam("team_id") 638 return 639 } 640 641 if sort != "" && sort != "last_activity_at" && sort != "create_at" && sort != "status" { 642 c.SetInvalidUrlParam("sort") 643 return 644 } 645 646 // Currently only supports sorting on a team 647 // or sort="status" on inChannelId 648 if (sort == "last_activity_at" || sort == "create_at") && (inTeamId == "" || notInTeamId != "" || inChannelId != "" || notInChannelId != "" || withoutTeam != "" || inGroupId != "") { 649 c.SetInvalidUrlParam("sort") 650 return 651 } 652 if sort == "status" && inChannelId == "" { 653 c.SetInvalidUrlParam("sort") 654 return 655 } 656 657 withoutTeamBool, _ := strconv.ParseBool(withoutTeam) 658 groupConstrainedBool, _ := strconv.ParseBool(groupConstrained) 659 inactiveBool, _ := strconv.ParseBool(inactive) 660 activeBool, _ := strconv.ParseBool(active) 661 662 if inactiveBool && activeBool { 663 c.SetInvalidUrlParam("inactive") 664 } 665 666 roles := []string{} 667 var rolesValid bool 668 if rolesString != "" { 669 roles, rolesValid = model.CleanRoleNames(strings.Split(rolesString, ",")) 670 if !rolesValid { 671 c.SetInvalidParam("roles") 672 return 673 } 674 } 675 channelRoles := []string{} 676 if channelRolesString != "" && inChannelId != "" { 677 channelRoles, rolesValid = model.CleanRoleNames(strings.Split(channelRolesString, ",")) 678 if !rolesValid { 679 c.SetInvalidParam("channelRoles") 680 return 681 } 682 } 683 teamRoles := []string{} 684 if teamRolesString != "" && inTeamId != "" { 685 teamRoles, rolesValid = model.CleanRoleNames(strings.Split(teamRolesString, ",")) 686 if !rolesValid { 687 c.SetInvalidParam("teamRoles") 688 return 689 } 690 } 691 692 restrictions, err := c.App.GetViewUsersRestrictions(c.App.Session().UserId) 693 if err != nil { 694 c.Err = err 695 return 696 } 697 698 userGetOptions := &model.UserGetOptions{ 699 InTeamId: inTeamId, 700 InChannelId: inChannelId, 701 NotInTeamId: notInTeamId, 702 NotInChannelId: notInChannelId, 703 InGroupId: inGroupId, 704 GroupConstrained: groupConstrainedBool, 705 WithoutTeam: withoutTeamBool, 706 Inactive: inactiveBool, 707 Active: activeBool, 708 Role: role, 709 Roles: roles, 710 ChannelRoles: channelRoles, 711 TeamRoles: teamRoles, 712 Sort: sort, 713 Page: c.Params.Page, 714 PerPage: c.Params.PerPage, 715 ViewRestrictions: restrictions, 716 } 717 718 var profiles []*model.User 719 etag := "" 720 721 if withoutTeamBool, _ := strconv.ParseBool(withoutTeam); withoutTeamBool { 722 // Use a special permission for now 723 if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_LIST_USERS_WITHOUT_TEAM) { 724 c.SetPermissionError(model.PERMISSION_LIST_USERS_WITHOUT_TEAM) 725 return 726 } 727 728 profiles, err = c.App.GetUsersWithoutTeamPage(userGetOptions, c.IsSystemAdmin()) 729 } else if len(notInChannelId) > 0 { 730 if !c.App.SessionHasPermissionToChannel(*c.App.Session(), notInChannelId, model.PERMISSION_READ_CHANNEL) { 731 c.SetPermissionError(model.PERMISSION_READ_CHANNEL) 732 return 733 } 734 735 profiles, err = c.App.GetUsersNotInChannelPage(inTeamId, notInChannelId, groupConstrainedBool, c.Params.Page, c.Params.PerPage, c.IsSystemAdmin(), restrictions) 736 } else if len(notInTeamId) > 0 { 737 if !c.App.SessionHasPermissionToTeam(*c.App.Session(), notInTeamId, model.PERMISSION_VIEW_TEAM) { 738 c.SetPermissionError(model.PERMISSION_VIEW_TEAM) 739 return 740 } 741 742 etag = c.App.GetUsersNotInTeamEtag(inTeamId, restrictions.Hash()) 743 if c.HandleEtag(etag, "Get Users Not in Team", w, r) { 744 return 745 } 746 747 profiles, err = c.App.GetUsersNotInTeamPage(notInTeamId, groupConstrainedBool, c.Params.Page, c.Params.PerPage, c.IsSystemAdmin(), restrictions) 748 } else if len(inTeamId) > 0 { 749 if !c.App.SessionHasPermissionToTeam(*c.App.Session(), inTeamId, model.PERMISSION_VIEW_TEAM) { 750 c.SetPermissionError(model.PERMISSION_VIEW_TEAM) 751 return 752 } 753 754 if sort == "last_activity_at" { 755 profiles, err = c.App.GetRecentlyActiveUsersForTeamPage(inTeamId, c.Params.Page, c.Params.PerPage, c.IsSystemAdmin(), restrictions) 756 } else if sort == "create_at" { 757 profiles, err = c.App.GetNewUsersForTeamPage(inTeamId, c.Params.Page, c.Params.PerPage, c.IsSystemAdmin(), restrictions) 758 } else { 759 etag = c.App.GetUsersInTeamEtag(inTeamId, restrictions.Hash()) 760 if c.HandleEtag(etag, "Get Users in Team", w, r) { 761 return 762 } 763 profiles, err = c.App.GetUsersInTeamPage(userGetOptions, c.IsSystemAdmin()) 764 } 765 } else if len(inChannelId) > 0 { 766 if !c.App.SessionHasPermissionToChannel(*c.App.Session(), inChannelId, model.PERMISSION_READ_CHANNEL) { 767 c.SetPermissionError(model.PERMISSION_READ_CHANNEL) 768 return 769 } 770 if sort == "status" { 771 profiles, err = c.App.GetUsersInChannelPageByStatus(userGetOptions, c.IsSystemAdmin()) 772 } else { 773 profiles, err = c.App.GetUsersInChannelPage(userGetOptions, c.IsSystemAdmin()) 774 } 775 } else if len(inGroupId) > 0 { 776 if c.App.Srv().License() == nil || !*c.App.Srv().License().Features.LDAPGroups { 777 c.Err = model.NewAppError("Api4.getUsersInGroup", "api.ldap_groups.license_error", nil, "", http.StatusNotImplemented) 778 return 779 } 780 781 if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_GROUPS) { 782 c.SetPermissionError(model.PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_GROUPS) 783 return 784 } 785 786 profiles, _, err = c.App.GetGroupMemberUsersPage(inGroupId, c.Params.Page, c.Params.PerPage) 787 if err != nil { 788 c.Err = err 789 return 790 } 791 } else { 792 userGetOptions, err = c.App.RestrictUsersGetByPermissions(c.App.Session().UserId, userGetOptions) 793 if err != nil { 794 c.Err = err 795 return 796 } 797 profiles, err = c.App.GetUsersPage(userGetOptions, c.IsSystemAdmin()) 798 } 799 800 if err != nil { 801 c.Err = err 802 return 803 } 804 805 if len(etag) > 0 { 806 w.Header().Set(model.HEADER_ETAG_SERVER, etag) 807 } 808 c.App.UpdateLastActivityAtIfNeeded(*c.App.Session()) 809 w.Write([]byte(model.UserListToJson(profiles))) 810 } 811 812 func getUsersByIds(c *Context, w http.ResponseWriter, r *http.Request) { 813 userIds := model.ArrayFromJson(r.Body) 814 815 if len(userIds) == 0 { 816 c.SetInvalidParam("user_ids") 817 return 818 } 819 820 sinceString := r.URL.Query().Get("since") 821 822 options := &store.UserGetByIdsOpts{ 823 IsAdmin: c.IsSystemAdmin(), 824 } 825 826 if len(sinceString) > 0 { 827 since, parseError := strconv.ParseInt(sinceString, 10, 64) 828 if parseError != nil { 829 c.SetInvalidParam("since") 830 return 831 } 832 options.Since = since 833 } 834 835 restrictions, err := c.App.GetViewUsersRestrictions(c.App.Session().UserId) 836 if err != nil { 837 c.Err = err 838 return 839 } 840 options.ViewRestrictions = restrictions 841 842 users, err := c.App.GetUsersByIds(userIds, options) 843 if err != nil { 844 c.Err = err 845 return 846 } 847 848 w.Write([]byte(model.UserListToJson(users))) 849 } 850 851 func getUsersByNames(c *Context, w http.ResponseWriter, r *http.Request) { 852 usernames := model.ArrayFromJson(r.Body) 853 854 if len(usernames) == 0 { 855 c.SetInvalidParam("usernames") 856 return 857 } 858 859 restrictions, err := c.App.GetViewUsersRestrictions(c.App.Session().UserId) 860 if err != nil { 861 c.Err = err 862 return 863 } 864 865 users, err := c.App.GetUsersByUsernames(usernames, c.IsSystemAdmin(), restrictions) 866 if err != nil { 867 c.Err = err 868 return 869 } 870 871 w.Write([]byte(model.UserListToJson(users))) 872 } 873 874 func getKnownUsers(c *Context, w http.ResponseWriter, r *http.Request) { 875 userIds, err := c.App.GetKnownUsers(c.App.Session().UserId) 876 if err != nil { 877 c.Err = err 878 return 879 } 880 881 data, _ := json.Marshal(userIds) 882 883 w.Write(data) 884 } 885 886 func searchUsers(c *Context, w http.ResponseWriter, r *http.Request) { 887 props := model.UserSearchFromJson(r.Body) 888 if props == nil { 889 c.SetInvalidParam("") 890 return 891 } 892 893 if len(props.Term) == 0 { 894 c.SetInvalidParam("term") 895 return 896 } 897 898 if props.TeamId == "" && props.NotInChannelId != "" { 899 c.SetInvalidParam("team_id") 900 return 901 } 902 903 if props.InGroupId != "" { 904 if c.App.Srv().License() == nil || !*c.App.Srv().License().Features.LDAPGroups { 905 c.Err = model.NewAppError("Api4.searchUsers", "api.ldap_groups.license_error", nil, "", http.StatusNotImplemented) 906 return 907 } 908 909 if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_MANAGE_SYSTEM) { 910 c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM) 911 return 912 } 913 } 914 915 if props.InChannelId != "" && !c.App.SessionHasPermissionToChannel(*c.App.Session(), props.InChannelId, model.PERMISSION_READ_CHANNEL) { 916 c.SetPermissionError(model.PERMISSION_READ_CHANNEL) 917 return 918 } 919 920 if props.NotInChannelId != "" && !c.App.SessionHasPermissionToChannel(*c.App.Session(), props.NotInChannelId, model.PERMISSION_READ_CHANNEL) { 921 c.SetPermissionError(model.PERMISSION_READ_CHANNEL) 922 return 923 } 924 925 if props.TeamId != "" && !c.App.SessionHasPermissionToTeam(*c.App.Session(), props.TeamId, model.PERMISSION_VIEW_TEAM) { 926 c.SetPermissionError(model.PERMISSION_VIEW_TEAM) 927 return 928 } 929 930 if props.NotInTeamId != "" && !c.App.SessionHasPermissionToTeam(*c.App.Session(), props.NotInTeamId, model.PERMISSION_VIEW_TEAM) { 931 c.SetPermissionError(model.PERMISSION_VIEW_TEAM) 932 return 933 } 934 935 if props.Limit <= 0 || props.Limit > model.USER_SEARCH_MAX_LIMIT { 936 c.SetInvalidParam("limit") 937 return 938 } 939 940 options := &model.UserSearchOptions{ 941 IsAdmin: c.IsSystemAdmin(), 942 AllowInactive: props.AllowInactive, 943 GroupConstrained: props.GroupConstrained, 944 Limit: props.Limit, 945 Role: props.Role, 946 Roles: props.Roles, 947 ChannelRoles: props.ChannelRoles, 948 TeamRoles: props.TeamRoles, 949 } 950 951 if c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_MANAGE_SYSTEM) { 952 options.AllowEmails = true 953 options.AllowFullNames = true 954 } else { 955 options.AllowEmails = *c.App.Config().PrivacySettings.ShowEmailAddress 956 options.AllowFullNames = *c.App.Config().PrivacySettings.ShowFullName 957 } 958 959 options, err := c.App.RestrictUsersSearchByPermissions(c.App.Session().UserId, options) 960 if err != nil { 961 c.Err = err 962 return 963 } 964 965 profiles, err := c.App.SearchUsers(props, options) 966 if err != nil { 967 c.Err = err 968 return 969 } 970 971 w.Write([]byte(model.UserListToJson(profiles))) 972 } 973 974 func autocompleteUsers(c *Context, w http.ResponseWriter, r *http.Request) { 975 channelId := r.URL.Query().Get("in_channel") 976 teamId := r.URL.Query().Get("in_team") 977 name := r.URL.Query().Get("name") 978 limitStr := r.URL.Query().Get("limit") 979 limit, _ := strconv.Atoi(limitStr) 980 if limitStr == "" { 981 limit = model.USER_SEARCH_DEFAULT_LIMIT 982 } else if limit > model.USER_SEARCH_MAX_LIMIT { 983 limit = model.USER_SEARCH_MAX_LIMIT 984 } 985 986 options := &model.UserSearchOptions{ 987 IsAdmin: c.IsSystemAdmin(), 988 // Never autocomplete on emails. 989 AllowEmails: false, 990 Limit: limit, 991 } 992 993 if c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_MANAGE_SYSTEM) { 994 options.AllowFullNames = true 995 } else { 996 options.AllowFullNames = *c.App.Config().PrivacySettings.ShowFullName 997 } 998 999 if len(channelId) > 0 { 1000 if !c.App.SessionHasPermissionToChannel(*c.App.Session(), channelId, model.PERMISSION_READ_CHANNEL) { 1001 c.SetPermissionError(model.PERMISSION_READ_CHANNEL) 1002 return 1003 } 1004 } 1005 1006 if len(teamId) > 0 { 1007 if !c.App.SessionHasPermissionToTeam(*c.App.Session(), teamId, model.PERMISSION_VIEW_TEAM) { 1008 c.SetPermissionError(model.PERMISSION_VIEW_TEAM) 1009 return 1010 } 1011 } 1012 1013 var autocomplete model.UserAutocomplete 1014 1015 var err *model.AppError 1016 options, err = c.App.RestrictUsersSearchByPermissions(c.App.Session().UserId, options) 1017 if err != nil { 1018 c.Err = err 1019 return 1020 } 1021 1022 if len(channelId) > 0 { 1023 // We're using the channelId to search for users inside that channel and the team 1024 // to get the not in channel list. Also we want to include the DM and GM users for 1025 // that team which could only be obtained having the team id. 1026 if len(teamId) == 0 { 1027 c.Err = model.NewAppError("autocompleteUser", 1028 "api.user.autocomplete_users.missing_team_id.app_error", 1029 nil, 1030 "channelId="+channelId, 1031 http.StatusInternalServerError, 1032 ) 1033 return 1034 } 1035 result, err := c.App.AutocompleteUsersInChannel(teamId, channelId, name, options) 1036 if err != nil { 1037 c.Err = err 1038 return 1039 } 1040 1041 autocomplete.Users = result.InChannel 1042 autocomplete.OutOfChannel = result.OutOfChannel 1043 } else if len(teamId) > 0 { 1044 result, err := c.App.AutocompleteUsersInTeam(teamId, name, options) 1045 if err != nil { 1046 c.Err = err 1047 return 1048 } 1049 1050 autocomplete.Users = result.InTeam 1051 } else { 1052 result, err := c.App.SearchUsersInTeam("", name, options) 1053 if err != nil { 1054 c.Err = err 1055 return 1056 } 1057 autocomplete.Users = result 1058 } 1059 1060 w.Write([]byte((autocomplete.ToJson()))) 1061 } 1062 1063 func updateUser(c *Context, w http.ResponseWriter, r *http.Request) { 1064 c.RequireUserId() 1065 if c.Err != nil { 1066 return 1067 } 1068 1069 user := model.UserFromJson(r.Body) 1070 if user == nil { 1071 c.SetInvalidParam("user") 1072 return 1073 } 1074 1075 // The user being updated in the payload must be the same one as indicated in the URL. 1076 if user.Id != c.Params.UserId { 1077 c.SetInvalidParam("user_id") 1078 return 1079 } 1080 1081 auditRec := c.MakeAuditRecord("updateUser", audit.Fail) 1082 defer c.LogAuditRec(auditRec) 1083 1084 // Cannot update a system admin unless user making request is a systemadmin also. 1085 if user.IsSystemAdmin() && !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_MANAGE_SYSTEM) { 1086 c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM) 1087 return 1088 } 1089 1090 if !c.App.SessionHasPermissionToUser(*c.App.Session(), user.Id) { 1091 c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS) 1092 return 1093 } 1094 1095 ouser, err := c.App.GetUser(user.Id) 1096 if err != nil { 1097 c.Err = err 1098 return 1099 } 1100 auditRec.AddMeta("user", ouser) 1101 1102 if c.App.Session().IsOAuth { 1103 if ouser.Email != user.Email { 1104 c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS) 1105 c.Err.DetailedError += ", attempted email update by oauth app" 1106 return 1107 } 1108 } 1109 1110 // If eMail update is attempted by the currently logged in user, check if correct password was provided 1111 if user.Email != "" && ouser.Email != user.Email && c.App.Session().UserId == c.Params.UserId { 1112 err = c.App.DoubleCheckPassword(ouser, user.Password) 1113 if err != nil { 1114 c.SetInvalidParam("password") 1115 return 1116 } 1117 } 1118 1119 ruser, err := c.App.UpdateUserAsUser(user, c.IsSystemAdmin()) 1120 if err != nil { 1121 c.Err = err 1122 return 1123 } 1124 1125 auditRec.Success() 1126 auditRec.AddMeta("update", ruser) 1127 c.LogAudit("") 1128 1129 w.Write([]byte(ruser.ToJson())) 1130 } 1131 1132 func patchUser(c *Context, w http.ResponseWriter, r *http.Request) { 1133 c.RequireUserId() 1134 if c.Err != nil { 1135 return 1136 } 1137 1138 patch := model.UserPatchFromJson(r.Body) 1139 if patch == nil { 1140 c.SetInvalidParam("user") 1141 return 1142 } 1143 1144 auditRec := c.MakeAuditRecord("patchUser", audit.Fail) 1145 defer c.LogAuditRec(auditRec) 1146 1147 if !c.App.SessionHasPermissionToUser(*c.App.Session(), c.Params.UserId) { 1148 c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS) 1149 return 1150 } 1151 1152 ouser, err := c.App.GetUser(c.Params.UserId) 1153 if err != nil { 1154 c.SetInvalidParam("user_id") 1155 return 1156 } 1157 auditRec.AddMeta("user", ouser) 1158 1159 // Cannot update a system admin unless user making request is a systemadmin also 1160 if ouser.IsSystemAdmin() && !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_MANAGE_SYSTEM) { 1161 c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM) 1162 return 1163 } 1164 1165 if c.App.Session().IsOAuth && patch.Email != nil { 1166 if ouser.Email != *patch.Email { 1167 c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS) 1168 c.Err.DetailedError += ", attempted email update by oauth app" 1169 return 1170 } 1171 } 1172 1173 // If eMail update is attempted by the currently logged in user, check if correct password was provided 1174 if patch.Email != nil && ouser.Email != *patch.Email && c.App.Session().UserId == c.Params.UserId { 1175 if patch.Password == nil { 1176 c.SetInvalidParam("password") 1177 return 1178 } 1179 1180 if err = c.App.DoubleCheckPassword(ouser, *patch.Password); err != nil { 1181 c.Err = err 1182 return 1183 } 1184 } 1185 1186 ruser, err := c.App.PatchUser(c.Params.UserId, patch, c.IsSystemAdmin()) 1187 if err != nil { 1188 c.Err = err 1189 return 1190 } 1191 1192 c.App.SetAutoResponderStatus(ruser, ouser.NotifyProps) 1193 1194 auditRec.Success() 1195 auditRec.AddMeta("patch", ruser) 1196 c.LogAudit("") 1197 1198 w.Write([]byte(ruser.ToJson())) 1199 } 1200 1201 func deleteUser(c *Context, w http.ResponseWriter, r *http.Request) { 1202 c.RequireUserId() 1203 if c.Err != nil { 1204 return 1205 } 1206 1207 userId := c.Params.UserId 1208 1209 auditRec := c.MakeAuditRecord("deleteUser", audit.Fail) 1210 defer c.LogAuditRec(auditRec) 1211 1212 if !c.App.SessionHasPermissionToUser(*c.App.Session(), userId) { 1213 c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS) 1214 return 1215 } 1216 1217 // if EnableUserDeactivation flag is disabled the user cannot deactivate himself. 1218 if c.Params.UserId == c.App.Session().UserId && !*c.App.Config().TeamSettings.EnableUserDeactivation && !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_MANAGE_SYSTEM) { 1219 c.Err = model.NewAppError("deleteUser", "api.user.update_active.not_enable.app_error", nil, "userId="+c.Params.UserId, http.StatusUnauthorized) 1220 return 1221 } 1222 1223 user, err := c.App.GetUser(userId) 1224 if err != nil { 1225 c.Err = err 1226 return 1227 } 1228 auditRec.AddMeta("user", user) 1229 1230 // Cannot update a system admin unless user making request is a systemadmin also 1231 if user.IsSystemAdmin() && !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_MANAGE_SYSTEM) { 1232 c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM) 1233 return 1234 } 1235 1236 if c.Params.Permanent { 1237 if *c.App.Config().ServiceSettings.EnableAPIUserDeletion { 1238 err = c.App.PermanentDeleteUser(user) 1239 } else { 1240 err = model.NewAppError("deleteUser", "api.user.delete_user.not_enabled.app_error", nil, "userId="+c.Params.UserId, http.StatusUnauthorized) 1241 } 1242 } else { 1243 _, err = c.App.UpdateActive(user, false) 1244 } 1245 if err != nil { 1246 c.Err = err 1247 return 1248 } 1249 1250 auditRec.Success() 1251 ReturnStatusOK(w) 1252 } 1253 1254 func updateUserRoles(c *Context, w http.ResponseWriter, r *http.Request) { 1255 c.RequireUserId() 1256 if c.Err != nil { 1257 return 1258 } 1259 1260 props := model.MapFromJson(r.Body) 1261 1262 newRoles := props["roles"] 1263 if !model.IsValidUserRoles(newRoles) { 1264 c.SetInvalidParam("roles") 1265 return 1266 } 1267 1268 // require license feature to assign "new system roles" 1269 for _, roleName := range strings.Fields(newRoles) { 1270 for _, id := range model.NewSystemRoleIDs { 1271 if roleName == id { 1272 if license := c.App.Srv().License(); license == nil || !*license.Features.CustomPermissionsSchemes { 1273 c.Err = model.NewAppError("updateUserRoles", "api.user.update_user_roles.license.app_error", nil, "", http.StatusBadRequest) 1274 return 1275 } 1276 } 1277 } 1278 } 1279 1280 auditRec := c.MakeAuditRecord("updateUserRoles", audit.Fail) 1281 defer c.LogAuditRec(auditRec) 1282 auditRec.AddMeta("roles", newRoles) 1283 1284 if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_MANAGE_ROLES) { 1285 c.SetPermissionError(model.PERMISSION_MANAGE_ROLES) 1286 return 1287 } 1288 1289 user, err := c.App.UpdateUserRoles(c.Params.UserId, newRoles, true) 1290 if err != nil { 1291 c.Err = err 1292 return 1293 } 1294 1295 auditRec.Success() 1296 auditRec.AddMeta("user", user) 1297 c.LogAudit(fmt.Sprintf("user=%s roles=%s", c.Params.UserId, newRoles)) 1298 1299 ReturnStatusOK(w) 1300 } 1301 1302 func updateUserActive(c *Context, w http.ResponseWriter, r *http.Request) { 1303 c.RequireUserId() 1304 if c.Err != nil { 1305 return 1306 } 1307 1308 props := model.StringInterfaceFromJson(r.Body) 1309 1310 active, ok := props["active"].(bool) 1311 if !ok { 1312 c.SetInvalidParam("active") 1313 return 1314 } 1315 1316 auditRec := c.MakeAuditRecord("updateUserActive", audit.Fail) 1317 defer c.LogAuditRec(auditRec) 1318 auditRec.AddMeta("active", active) 1319 1320 // true when you're trying to de-activate yourself 1321 isSelfDeactive := !active && c.Params.UserId == c.App.Session().UserId 1322 1323 if !isSelfDeactive && !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_USERS) { 1324 c.Err = model.NewAppError("updateUserActive", "api.user.update_active.permissions.app_error", nil, "userId="+c.Params.UserId, http.StatusForbidden) 1325 return 1326 } 1327 1328 // if EnableUserDeactivation flag is disabled the user cannot deactivate himself. 1329 if isSelfDeactive && !*c.App.Config().TeamSettings.EnableUserDeactivation { 1330 c.Err = model.NewAppError("updateUserActive", "api.user.update_active.not_enable.app_error", nil, "userId="+c.Params.UserId, http.StatusUnauthorized) 1331 return 1332 } 1333 1334 user, err := c.App.GetUser(c.Params.UserId) 1335 if err != nil { 1336 c.Err = err 1337 return 1338 } 1339 auditRec.AddMeta("user", user) 1340 1341 if user.IsSystemAdmin() && !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_MANAGE_SYSTEM) { 1342 c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM) 1343 return 1344 } 1345 1346 if active && user.IsGuest() && !*c.App.Config().GuestAccountsSettings.Enable { 1347 c.Err = model.NewAppError("updateUserActive", "api.user.update_active.cannot_enable_guest_when_guest_feature_is_disabled.app_error", nil, "userId="+c.Params.UserId, http.StatusUnauthorized) 1348 return 1349 } 1350 1351 if _, err = c.App.UpdateActive(user, active); err != nil { 1352 c.Err = err 1353 } 1354 1355 auditRec.Success() 1356 c.LogAudit(fmt.Sprintf("user_id=%s active=%v", user.Id, active)) 1357 1358 if isSelfDeactive { 1359 c.App.Srv().Go(func() { 1360 if err = c.App.Srv().EmailService.SendDeactivateAccountEmail(user.Email, user.Locale, c.App.GetSiteURL()); err != nil { 1361 mlog.Error(err.Error()) 1362 } 1363 }) 1364 } 1365 1366 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_USER_ACTIVATION_STATUS_CHANGE, "", "", "", nil) 1367 c.App.Publish(message) 1368 1369 // If activating, run cloud check for limit overages 1370 if active { 1371 emailErr := c.App.CheckAndSendUserLimitWarningEmails() 1372 if emailErr != nil { 1373 c.Err = emailErr 1374 return 1375 } 1376 } 1377 1378 ReturnStatusOK(w) 1379 } 1380 1381 func updateUserAuth(c *Context, w http.ResponseWriter, r *http.Request) { 1382 if !c.IsSystemAdmin() { 1383 c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS) 1384 return 1385 } 1386 1387 c.RequireUserId() 1388 if c.Err != nil { 1389 return 1390 } 1391 1392 auditRec := c.MakeAuditRecord("updateUserAuth", audit.Fail) 1393 defer c.LogAuditRec(auditRec) 1394 1395 userAuth := model.UserAuthFromJson(r.Body) 1396 if userAuth == nil { 1397 c.SetInvalidParam("user") 1398 return 1399 } 1400 1401 if user, err := c.App.GetUser(c.Params.UserId); err == nil { 1402 auditRec.AddMeta("user", user) 1403 } 1404 1405 user, err := c.App.UpdateUserAuth(c.Params.UserId, userAuth) 1406 if err != nil { 1407 c.Err = err 1408 return 1409 } 1410 1411 auditRec.Success() 1412 auditRec.AddMeta("auth_service", user.AuthService) 1413 c.LogAudit(fmt.Sprintf("updated user %s auth to service=%v", c.Params.UserId, user.AuthService)) 1414 1415 w.Write([]byte(user.ToJson())) 1416 } 1417 1418 // Deprecated: checkUserMfa is deprecated and should not be used anymore, starting with version 6.0 it will be disabled. 1419 // Clients should attempt a login without MFA and will receive a MFA error when it's required. 1420 func checkUserMfa(c *Context, w http.ResponseWriter, r *http.Request) { 1421 1422 if *c.App.Config().ServiceSettings.DisableLegacyMFA { 1423 http.NotFound(w, r) 1424 return 1425 } 1426 1427 props := model.MapFromJson(r.Body) 1428 1429 loginId := props["login_id"] 1430 if len(loginId) == 0 { 1431 c.SetInvalidParam("login_id") 1432 return 1433 } 1434 1435 resp := map[string]interface{}{} 1436 resp["mfa_required"] = false 1437 1438 if !*c.App.Config().ServiceSettings.EnableMultifactorAuthentication { 1439 w.Write([]byte(model.StringInterfaceToJson(resp))) 1440 return 1441 } 1442 1443 if *c.App.Config().ServiceSettings.ExperimentalEnableHardenedMode { 1444 resp["mfa_required"] = true 1445 } else if user, err := c.App.GetUserForLogin("", loginId); err == nil { 1446 resp["mfa_required"] = user.MfaActive 1447 } 1448 1449 w.Write([]byte(model.StringInterfaceToJson(resp))) 1450 } 1451 1452 func updateUserMfa(c *Context, w http.ResponseWriter, r *http.Request) { 1453 c.RequireUserId() 1454 if c.Err != nil { 1455 return 1456 } 1457 1458 auditRec := c.MakeAuditRecord("updateUserMfa", audit.Fail) 1459 defer c.LogAuditRec(auditRec) 1460 1461 if c.App.Session().IsOAuth { 1462 c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS) 1463 c.Err.DetailedError += ", attempted access by oauth app" 1464 return 1465 } 1466 1467 if !c.App.SessionHasPermissionToUser(*c.App.Session(), c.Params.UserId) { 1468 c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS) 1469 return 1470 } 1471 1472 if user, err := c.App.GetUser(c.Params.UserId); err == nil { 1473 auditRec.AddMeta("user", user) 1474 } 1475 1476 props := model.StringInterfaceFromJson(r.Body) 1477 activate, ok := props["activate"].(bool) 1478 if !ok { 1479 c.SetInvalidParam("activate") 1480 return 1481 } 1482 1483 code := "" 1484 if activate { 1485 code, ok = props["code"].(string) 1486 if !ok || len(code) == 0 { 1487 c.SetInvalidParam("code") 1488 return 1489 } 1490 } 1491 1492 c.LogAudit("attempt") 1493 1494 if err := c.App.UpdateMfa(activate, c.Params.UserId, code); err != nil { 1495 c.Err = err 1496 return 1497 } 1498 1499 auditRec.Success() 1500 auditRec.AddMeta("activate", activate) 1501 c.LogAudit("success - mfa updated") 1502 1503 ReturnStatusOK(w) 1504 } 1505 1506 func generateMfaSecret(c *Context, w http.ResponseWriter, r *http.Request) { 1507 c.RequireUserId() 1508 if c.Err != nil { 1509 return 1510 } 1511 1512 if c.App.Session().IsOAuth { 1513 c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS) 1514 c.Err.DetailedError += ", attempted access by oauth app" 1515 return 1516 } 1517 1518 if !c.App.SessionHasPermissionToUser(*c.App.Session(), c.Params.UserId) { 1519 c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS) 1520 return 1521 } 1522 1523 secret, err := c.App.GenerateMfaSecret(c.Params.UserId) 1524 if err != nil { 1525 c.Err = err 1526 return 1527 } 1528 1529 w.Header().Set("Cache-Control", "no-cache") 1530 w.Header().Set("Pragma", "no-cache") 1531 w.Header().Set("Expires", "0") 1532 w.Write([]byte(secret.ToJson())) 1533 } 1534 1535 func updatePassword(c *Context, w http.ResponseWriter, r *http.Request) { 1536 c.RequireUserId() 1537 if c.Err != nil { 1538 return 1539 } 1540 1541 props := model.MapFromJson(r.Body) 1542 newPassword := props["new_password"] 1543 1544 auditRec := c.MakeAuditRecord("updatePassword", audit.Fail) 1545 defer c.LogAuditRec(auditRec) 1546 c.LogAudit("attempted") 1547 1548 var canUpdatePassword bool 1549 if user, err := c.App.GetUser(c.Params.UserId); err == nil { 1550 auditRec.AddMeta("user", user) 1551 1552 if user.IsSystemAdmin() { 1553 canUpdatePassword = c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_MANAGE_SYSTEM) 1554 } else { 1555 canUpdatePassword = c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_USERS) 1556 } 1557 } 1558 1559 var err *model.AppError 1560 1561 // There are two main update flows depending on whether the provided password 1562 // is already hashed or not. 1563 if props["already_hashed"] == "true" { 1564 if canUpdatePassword { 1565 err = c.App.UpdateHashedPasswordByUserId(c.Params.UserId, newPassword) 1566 } else if c.Params.UserId == c.App.Session().UserId { 1567 err = model.NewAppError("updatePassword", "api.user.update_password.user_and_hashed.app_error", nil, "", http.StatusUnauthorized) 1568 } else { 1569 err = model.NewAppError("updatePassword", "api.user.update_password.context.app_error", nil, "", http.StatusForbidden) 1570 } 1571 } else { 1572 if c.Params.UserId == c.App.Session().UserId { 1573 currentPassword := props["current_password"] 1574 if len(currentPassword) <= 0 { 1575 c.SetInvalidParam("current_password") 1576 return 1577 } 1578 1579 err = c.App.UpdatePasswordAsUser(c.Params.UserId, currentPassword, newPassword) 1580 } else if canUpdatePassword { 1581 err = c.App.UpdatePasswordByUserIdSendEmail(c.Params.UserId, newPassword, c.App.T("api.user.reset_password.method")) 1582 } else { 1583 err = model.NewAppError("updatePassword", "api.user.update_password.context.app_error", nil, "", http.StatusForbidden) 1584 } 1585 } 1586 1587 if err != nil { 1588 c.LogAudit("failed") 1589 c.Err = err 1590 return 1591 } 1592 1593 auditRec.Success() 1594 c.LogAudit("completed") 1595 1596 ReturnStatusOK(w) 1597 } 1598 1599 func resetPassword(c *Context, w http.ResponseWriter, r *http.Request) { 1600 props := model.MapFromJson(r.Body) 1601 1602 token := props["token"] 1603 if len(token) != model.TOKEN_SIZE { 1604 c.SetInvalidParam("token") 1605 return 1606 } 1607 1608 newPassword := props["new_password"] 1609 1610 auditRec := c.MakeAuditRecord("resetPassword", audit.Fail) 1611 defer c.LogAuditRec(auditRec) 1612 auditRec.AddMeta("token", token) 1613 c.LogAudit("attempt - token=" + token) 1614 1615 if err := c.App.ResetPasswordFromToken(token, newPassword); err != nil { 1616 c.LogAudit("fail - token=" + token) 1617 c.Err = err 1618 return 1619 } 1620 1621 auditRec.Success() 1622 c.LogAudit("success - token=" + token) 1623 1624 ReturnStatusOK(w) 1625 } 1626 1627 func sendPasswordReset(c *Context, w http.ResponseWriter, r *http.Request) { 1628 props := model.MapFromJson(r.Body) 1629 1630 email := props["email"] 1631 email = strings.ToLower(email) 1632 if len(email) == 0 { 1633 c.SetInvalidParam("email") 1634 return 1635 } 1636 1637 auditRec := c.MakeAuditRecord("sendPasswordReset", audit.Fail) 1638 defer c.LogAuditRec(auditRec) 1639 auditRec.AddMeta("email", email) 1640 1641 sent, err := c.App.SendPasswordReset(email, c.App.GetSiteURL()) 1642 if err != nil { 1643 if *c.App.Config().ServiceSettings.ExperimentalEnableHardenedMode { 1644 ReturnStatusOK(w) 1645 } else { 1646 c.Err = err 1647 } 1648 return 1649 } 1650 1651 if sent { 1652 auditRec.Success() 1653 c.LogAudit("sent=" + email) 1654 } 1655 ReturnStatusOK(w) 1656 } 1657 1658 func login(c *Context, w http.ResponseWriter, r *http.Request) { 1659 // Mask all sensitive errors, with the exception of the following 1660 defer func() { 1661 if c.Err == nil { 1662 return 1663 } 1664 1665 unmaskedErrors := []string{ 1666 "mfa.validate_token.authenticate.app_error", 1667 "api.user.check_user_mfa.bad_code.app_error", 1668 "api.user.login.blank_pwd.app_error", 1669 "api.user.login.bot_login_forbidden.app_error", 1670 "api.user.login.client_side_cert.certificate.app_error", 1671 "api.user.login.inactive.app_error", 1672 "api.user.login.not_verified.app_error", 1673 "api.user.check_user_login_attempts.too_many.app_error", 1674 "app.team.join_user_to_team.max_accounts.app_error", 1675 "store.sql_user.save.max_accounts.app_error", 1676 } 1677 1678 maskError := true 1679 1680 for _, unmaskedError := range unmaskedErrors { 1681 if c.Err.Id == unmaskedError { 1682 maskError = false 1683 } 1684 } 1685 1686 if !maskError { 1687 return 1688 } 1689 1690 config := c.App.Config() 1691 enableUsername := *config.EmailSettings.EnableSignInWithUsername 1692 enableEmail := *config.EmailSettings.EnableSignInWithEmail 1693 samlEnabled := *config.SamlSettings.Enable 1694 gitlabEnabled := *config.GitLabSettings.Enable 1695 openidEnabled := *config.OpenIdSettings.Enable 1696 googleEnabled := *config.GoogleSettings.Enable 1697 office365Enabled := *config.Office365Settings.Enable 1698 1699 if samlEnabled || gitlabEnabled || googleEnabled || office365Enabled || openidEnabled { 1700 c.Err = model.NewAppError("login", "api.user.login.invalid_credentials_sso", nil, "", http.StatusUnauthorized) 1701 return 1702 } 1703 1704 if enableUsername && !enableEmail { 1705 c.Err = model.NewAppError("login", "api.user.login.invalid_credentials_username", nil, "", http.StatusUnauthorized) 1706 return 1707 } 1708 1709 if !enableUsername && enableEmail { 1710 c.Err = model.NewAppError("login", "api.user.login.invalid_credentials_email", nil, "", http.StatusUnauthorized) 1711 return 1712 } 1713 1714 c.Err = model.NewAppError("login", "api.user.login.invalid_credentials_email_username", nil, "", http.StatusUnauthorized) 1715 }() 1716 1717 props := model.MapFromJson(r.Body) 1718 id := props["id"] 1719 loginId := props["login_id"] 1720 password := props["password"] 1721 mfaToken := props["token"] 1722 deviceId := props["device_id"] 1723 ldapOnly := props["ldap_only"] == "true" 1724 1725 if *c.App.Config().ExperimentalSettings.ClientSideCertEnable { 1726 if license := c.App.Srv().License(); license == nil || !*license.Features.SAML { 1727 c.Err = model.NewAppError("ClientSideCertNotAllowed", "api.user.login.client_side_cert.license.app_error", nil, "", http.StatusBadRequest) 1728 return 1729 } 1730 certPem, certSubject, certEmail := c.App.CheckForClientSideCert(r) 1731 mlog.Debug("Client Cert", mlog.String("cert_subject", certSubject), mlog.String("cert_email", certEmail)) 1732 1733 if len(certPem) == 0 || len(certEmail) == 0 { 1734 c.Err = model.NewAppError("ClientSideCertMissing", "api.user.login.client_side_cert.certificate.app_error", nil, "", http.StatusBadRequest) 1735 return 1736 } 1737 1738 if *c.App.Config().ExperimentalSettings.ClientSideCertCheck == model.CLIENT_SIDE_CERT_CHECK_PRIMARY_AUTH { 1739 loginId = certEmail 1740 password = "certificate" 1741 } 1742 } 1743 1744 auditRec := c.MakeAuditRecord("login", audit.Fail) 1745 defer c.LogAuditRec(auditRec) 1746 auditRec.AddMeta("login_id", loginId) 1747 auditRec.AddMeta("device_id", deviceId) 1748 1749 c.LogAuditWithUserId(id, "attempt - login_id="+loginId) 1750 1751 user, err := c.App.AuthenticateUserForLogin(id, loginId, password, mfaToken, "", ldapOnly) 1752 if err != nil { 1753 c.LogAuditWithUserId(id, "failure - login_id="+loginId) 1754 c.Err = err 1755 return 1756 } 1757 auditRec.AddMeta("user", user) 1758 1759 if user.IsGuest() { 1760 if c.App.Srv().License() == nil { 1761 c.Err = model.NewAppError("login", "api.user.login.guest_accounts.license.error", nil, "", http.StatusUnauthorized) 1762 return 1763 } 1764 if !*c.App.Config().GuestAccountsSettings.Enable { 1765 c.Err = model.NewAppError("login", "api.user.login.guest_accounts.disabled.error", nil, "", http.StatusUnauthorized) 1766 return 1767 } 1768 } 1769 1770 c.LogAuditWithUserId(user.Id, "authenticated") 1771 1772 err = c.App.DoLogin(w, r, user, deviceId, false, false, false) 1773 if err != nil { 1774 c.Err = err 1775 return 1776 } 1777 1778 c.LogAuditWithUserId(user.Id, "success") 1779 1780 if r.Header.Get(model.HEADER_REQUESTED_WITH) == model.HEADER_REQUESTED_WITH_XML { 1781 c.App.AttachSessionCookies(w, r) 1782 } 1783 1784 userTermsOfService, err := c.App.GetUserTermsOfService(user.Id) 1785 if err != nil && err.StatusCode != http.StatusNotFound { 1786 c.Err = err 1787 return 1788 } 1789 1790 if userTermsOfService != nil { 1791 user.TermsOfServiceId = userTermsOfService.TermsOfServiceId 1792 user.TermsOfServiceCreateAt = userTermsOfService.CreateAt 1793 } 1794 1795 user.Sanitize(map[string]bool{}) 1796 1797 auditRec.Success() 1798 w.Write([]byte(user.ToJson())) 1799 } 1800 1801 func loginCWS(c *Context, w http.ResponseWriter, r *http.Request) { 1802 if c.App.Srv().License() == nil || !*c.App.Srv().License().Features.Cloud { 1803 c.Err = model.NewAppError("loginCWS", "api.user.login_cws.license.error", nil, "", http.StatusUnauthorized) 1804 return 1805 } 1806 r.ParseForm() 1807 var loginID string 1808 var token string 1809 if len(r.Form) > 0 { 1810 for key, value := range r.Form { 1811 if key == "login_id" { 1812 loginID = value[0] 1813 } 1814 if key == "cws_token" { 1815 token = value[0] 1816 } 1817 } 1818 } 1819 1820 auditRec := c.MakeAuditRecord("login", audit.Fail) 1821 defer c.LogAuditRec(auditRec) 1822 auditRec.AddMeta("login_id", loginID) 1823 user, err := c.App.AuthenticateUserForLogin("", loginID, "", "", token, false) 1824 if err != nil { 1825 c.LogAuditWithUserId("", "failure - login_id="+loginID) 1826 mlog.Error("CWS authentication error", mlog.Err(err)) 1827 http.Redirect(w, r, *c.App.Config().ServiceSettings.SiteURL, 302) 1828 return 1829 } 1830 auditRec.AddMeta("user", user) 1831 c.LogAuditWithUserId(user.Id, "authenticated") 1832 err = c.App.DoLogin(w, r, user, "", false, false, false) 1833 if err != nil { 1834 mlog.Error("CWS login error", mlog.Err(err)) 1835 http.Redirect(w, r, *c.App.Config().ServiceSettings.SiteURL, 302) 1836 return 1837 } 1838 c.LogAuditWithUserId(user.Id, "success") 1839 c.App.AttachSessionCookies(w, r) 1840 http.Redirect(w, r, *c.App.Config().ServiceSettings.SiteURL, 302) 1841 } 1842 1843 func logout(c *Context, w http.ResponseWriter, r *http.Request) { 1844 Logout(c, w, r) 1845 } 1846 1847 func Logout(c *Context, w http.ResponseWriter, r *http.Request) { 1848 auditRec := c.MakeAuditRecord("Logout", audit.Fail) 1849 defer c.LogAuditRec(auditRec) 1850 c.LogAudit("") 1851 1852 c.RemoveSessionCookie(w, r) 1853 if c.App.Session().Id != "" { 1854 if err := c.App.RevokeSessionById(c.App.Session().Id); err != nil { 1855 c.Err = err 1856 return 1857 } 1858 } 1859 1860 auditRec.Success() 1861 ReturnStatusOK(w) 1862 } 1863 1864 func getSessions(c *Context, w http.ResponseWriter, r *http.Request) { 1865 c.RequireUserId() 1866 if c.Err != nil { 1867 return 1868 } 1869 1870 if !c.App.SessionHasPermissionToUser(*c.App.Session(), c.Params.UserId) { 1871 c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS) 1872 return 1873 } 1874 1875 sessions, err := c.App.GetSessions(c.Params.UserId) 1876 if err != nil { 1877 c.Err = err 1878 return 1879 } 1880 1881 for _, session := range sessions { 1882 session.Sanitize() 1883 } 1884 1885 w.Write([]byte(model.SessionsToJson(sessions))) 1886 } 1887 1888 func revokeSession(c *Context, w http.ResponseWriter, r *http.Request) { 1889 c.RequireUserId() 1890 if c.Err != nil { 1891 return 1892 } 1893 1894 auditRec := c.MakeAuditRecord("revokeSession", audit.Fail) 1895 defer c.LogAuditRec(auditRec) 1896 1897 if !c.App.SessionHasPermissionToUser(*c.App.Session(), c.Params.UserId) { 1898 c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS) 1899 return 1900 } 1901 1902 props := model.MapFromJson(r.Body) 1903 sessionId := props["session_id"] 1904 if sessionId == "" { 1905 c.SetInvalidParam("session_id") 1906 return 1907 } 1908 1909 session, err := c.App.GetSessionById(sessionId) 1910 if err != nil { 1911 c.Err = err 1912 return 1913 } 1914 auditRec.AddMeta("session", session) 1915 1916 if session.UserId != c.Params.UserId { 1917 c.SetInvalidUrlParam("user_id") 1918 return 1919 } 1920 1921 if err := c.App.RevokeSession(session); err != nil { 1922 c.Err = err 1923 return 1924 } 1925 1926 auditRec.Success() 1927 c.LogAudit("") 1928 1929 ReturnStatusOK(w) 1930 } 1931 1932 func revokeAllSessionsForUser(c *Context, w http.ResponseWriter, r *http.Request) { 1933 c.RequireUserId() 1934 if c.Err != nil { 1935 return 1936 } 1937 1938 auditRec := c.MakeAuditRecord("revokeAllSessionsForUser", audit.Fail) 1939 defer c.LogAuditRec(auditRec) 1940 auditRec.AddMeta("user_id", c.Params.UserId) 1941 1942 if !c.App.SessionHasPermissionToUser(*c.App.Session(), c.Params.UserId) { 1943 c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS) 1944 return 1945 } 1946 1947 if err := c.App.RevokeAllSessions(c.Params.UserId); err != nil { 1948 c.Err = err 1949 return 1950 } 1951 1952 auditRec.Success() 1953 c.LogAudit("") 1954 1955 ReturnStatusOK(w) 1956 } 1957 1958 func revokeAllSessionsAllUsers(c *Context, w http.ResponseWriter, r *http.Request) { 1959 if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_MANAGE_SYSTEM) { 1960 c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM) 1961 return 1962 } 1963 1964 auditRec := c.MakeAuditRecord("revokeAllSessionsAllUsers", audit.Fail) 1965 defer c.LogAuditRec(auditRec) 1966 1967 if err := c.App.RevokeSessionsFromAllUsers(); err != nil { 1968 c.Err = err 1969 return 1970 } 1971 1972 auditRec.Success() 1973 c.LogAudit("") 1974 1975 ReturnStatusOK(w) 1976 } 1977 1978 func attachDeviceId(c *Context, w http.ResponseWriter, r *http.Request) { 1979 props := model.MapFromJson(r.Body) 1980 1981 deviceId := props["device_id"] 1982 if len(deviceId) == 0 { 1983 c.SetInvalidParam("device_id") 1984 return 1985 } 1986 1987 auditRec := c.MakeAuditRecord("attachDeviceId", audit.Fail) 1988 defer c.LogAuditRec(auditRec) 1989 auditRec.AddMeta("device_id", deviceId) 1990 1991 // A special case where we logout of all other sessions with the same device id 1992 if err := c.App.RevokeSessionsForDeviceId(c.App.Session().UserId, deviceId, c.App.Session().Id); err != nil { 1993 c.Err = err 1994 return 1995 } 1996 1997 c.App.ClearSessionCacheForUser(c.App.Session().UserId) 1998 c.App.SetSessionExpireInDays(c.App.Session(), *c.App.Config().ServiceSettings.SessionLengthMobileInDays) 1999 2000 maxAge := *c.App.Config().ServiceSettings.SessionLengthMobileInDays * 60 * 60 * 24 2001 2002 secure := false 2003 if app.GetProtocol(r) == "https" { 2004 secure = true 2005 } 2006 2007 subpath, _ := utils.GetSubpathFromConfig(c.App.Config()) 2008 2009 expiresAt := time.Unix(model.GetMillis()/1000+int64(maxAge), 0) 2010 sessionCookie := &http.Cookie{ 2011 Name: model.SESSION_COOKIE_TOKEN, 2012 Value: c.App.Session().Token, 2013 Path: subpath, 2014 MaxAge: maxAge, 2015 Expires: expiresAt, 2016 HttpOnly: true, 2017 Domain: c.App.GetCookieDomain(), 2018 Secure: secure, 2019 } 2020 2021 http.SetCookie(w, sessionCookie) 2022 2023 if err := c.App.AttachDeviceId(c.App.Session().Id, deviceId, c.App.Session().ExpiresAt); err != nil { 2024 c.Err = err 2025 return 2026 } 2027 2028 auditRec.Success() 2029 c.LogAudit("") 2030 2031 ReturnStatusOK(w) 2032 } 2033 2034 func getUserAudits(c *Context, w http.ResponseWriter, r *http.Request) { 2035 c.RequireUserId() 2036 if c.Err != nil { 2037 return 2038 } 2039 2040 auditRec := c.MakeAuditRecord("getUserAudits", audit.Fail) 2041 defer c.LogAuditRec(auditRec) 2042 2043 if user, err := c.App.GetUser(c.Params.UserId); err == nil { 2044 auditRec.AddMeta("user", user) 2045 } 2046 2047 if !c.App.SessionHasPermissionToUser(*c.App.Session(), c.Params.UserId) { 2048 c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS) 2049 return 2050 } 2051 2052 audits, err := c.App.GetAuditsPage(c.Params.UserId, c.Params.Page, c.Params.PerPage) 2053 if err != nil { 2054 c.Err = err 2055 return 2056 } 2057 2058 auditRec.Success() 2059 auditRec.AddMeta("page", c.Params.Page) 2060 auditRec.AddMeta("audits_per_page", c.Params.LogsPerPage) 2061 2062 w.Write([]byte(audits.ToJson())) 2063 } 2064 2065 func verifyUserEmail(c *Context, w http.ResponseWriter, r *http.Request) { 2066 props := model.MapFromJson(r.Body) 2067 2068 token := props["token"] 2069 if len(token) != model.TOKEN_SIZE { 2070 c.SetInvalidParam("token") 2071 return 2072 } 2073 2074 auditRec := c.MakeAuditRecord("verifyUserEmail", audit.Fail) 2075 defer c.LogAuditRec(auditRec) 2076 2077 if err := c.App.VerifyEmailFromToken(token); err != nil { 2078 c.Err = model.NewAppError("verifyUserEmail", "api.user.verify_email.bad_link.app_error", nil, err.Error(), http.StatusBadRequest) 2079 return 2080 } 2081 2082 auditRec.Success() 2083 c.LogAudit("Email Verified") 2084 2085 ReturnStatusOK(w) 2086 } 2087 2088 func sendVerificationEmail(c *Context, w http.ResponseWriter, r *http.Request) { 2089 props := model.MapFromJson(r.Body) 2090 2091 email := props["email"] 2092 email = strings.ToLower(email) 2093 if len(email) == 0 { 2094 c.SetInvalidParam("email") 2095 return 2096 } 2097 redirect := r.URL.Query().Get("r") 2098 2099 auditRec := c.MakeAuditRecord("sendVerificationEmail", audit.Fail) 2100 defer c.LogAuditRec(auditRec) 2101 auditRec.AddMeta("email", email) 2102 2103 user, err := c.App.GetUserForLogin("", email) 2104 if err != nil { 2105 // Don't want to leak whether the email is valid or not 2106 ReturnStatusOK(w) 2107 return 2108 } 2109 auditRec.AddMeta("user", user) 2110 2111 if err = c.App.SendEmailVerification(user, user.Email, redirect); err != nil { 2112 // Don't want to leak whether the email is valid or not 2113 mlog.Error(err.Error()) 2114 ReturnStatusOK(w) 2115 return 2116 } 2117 2118 auditRec.Success() 2119 ReturnStatusOK(w) 2120 } 2121 2122 func switchAccountType(c *Context, w http.ResponseWriter, r *http.Request) { 2123 switchRequest := model.SwitchRequestFromJson(r.Body) 2124 if switchRequest == nil { 2125 c.SetInvalidParam("switch_request") 2126 return 2127 } 2128 2129 auditRec := c.MakeAuditRecord("switchAccountType", audit.Fail) 2130 defer c.LogAuditRec(auditRec) 2131 auditRec.AddMeta("email", switchRequest.Email) 2132 auditRec.AddMeta("new_service", switchRequest.NewService) 2133 auditRec.AddMeta("old_service", switchRequest.CurrentService) 2134 2135 link := "" 2136 var err *model.AppError 2137 2138 if switchRequest.EmailToOAuth() { 2139 link, err = c.App.SwitchEmailToOAuth(w, r, switchRequest.Email, switchRequest.Password, switchRequest.MfaCode, switchRequest.NewService) 2140 } else if switchRequest.OAuthToEmail() { 2141 c.SessionRequired() 2142 if c.Err != nil { 2143 return 2144 } 2145 2146 link, err = c.App.SwitchOAuthToEmail(switchRequest.Email, switchRequest.NewPassword, c.App.Session().UserId) 2147 } else if switchRequest.EmailToLdap() { 2148 link, err = c.App.SwitchEmailToLdap(switchRequest.Email, switchRequest.Password, switchRequest.MfaCode, switchRequest.LdapLoginId, switchRequest.NewPassword) 2149 } else if switchRequest.LdapToEmail() { 2150 link, err = c.App.SwitchLdapToEmail(switchRequest.Password, switchRequest.MfaCode, switchRequest.Email, switchRequest.NewPassword) 2151 } else { 2152 c.SetInvalidParam("switch_request") 2153 return 2154 } 2155 2156 if err != nil { 2157 c.Err = err 2158 return 2159 } 2160 2161 auditRec.Success() 2162 c.LogAudit("success") 2163 2164 w.Write([]byte(model.MapToJson(map[string]string{"follow_link": link}))) 2165 } 2166 2167 func createUserAccessToken(c *Context, w http.ResponseWriter, r *http.Request) { 2168 c.RequireUserId() 2169 if c.Err != nil { 2170 return 2171 } 2172 2173 auditRec := c.MakeAuditRecord("createUserAccessToken", audit.Fail) 2174 defer c.LogAuditRec(auditRec) 2175 2176 if user, err := c.App.GetUser(c.Params.UserId); err == nil { 2177 auditRec.AddMeta("user", user) 2178 } 2179 2180 if c.App.Session().IsOAuth { 2181 c.SetPermissionError(model.PERMISSION_CREATE_USER_ACCESS_TOKEN) 2182 c.Err.DetailedError += ", attempted access by oauth app" 2183 return 2184 } 2185 2186 accessToken := model.UserAccessTokenFromJson(r.Body) 2187 if accessToken == nil { 2188 c.SetInvalidParam("user_access_token") 2189 return 2190 } 2191 2192 if accessToken.Description == "" { 2193 c.SetInvalidParam("description") 2194 return 2195 } 2196 2197 c.LogAudit("") 2198 2199 if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_CREATE_USER_ACCESS_TOKEN) { 2200 c.SetPermissionError(model.PERMISSION_CREATE_USER_ACCESS_TOKEN) 2201 return 2202 } 2203 2204 if !c.App.SessionHasPermissionToUserOrBot(*c.App.Session(), c.Params.UserId) { 2205 c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS) 2206 return 2207 } 2208 2209 accessToken.UserId = c.Params.UserId 2210 accessToken.Token = "" 2211 2212 accessToken, err := c.App.CreateUserAccessToken(accessToken) 2213 if err != nil { 2214 c.Err = err 2215 return 2216 } 2217 2218 auditRec.Success() 2219 auditRec.AddMeta("token_id", accessToken.Id) 2220 c.LogAudit("success - token_id=" + accessToken.Id) 2221 2222 w.Write([]byte(accessToken.ToJson())) 2223 } 2224 2225 func searchUserAccessTokens(c *Context, w http.ResponseWriter, r *http.Request) { 2226 if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_MANAGE_SYSTEM) { 2227 c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM) 2228 return 2229 } 2230 props := model.UserAccessTokenSearchFromJson(r.Body) 2231 if props == nil { 2232 c.SetInvalidParam("user_access_token_search") 2233 return 2234 } 2235 2236 if len(props.Term) == 0 { 2237 c.SetInvalidParam("term") 2238 return 2239 } 2240 2241 accessTokens, err := c.App.SearchUserAccessTokens(props.Term) 2242 if err != nil { 2243 c.Err = err 2244 return 2245 } 2246 2247 w.Write([]byte(model.UserAccessTokenListToJson(accessTokens))) 2248 } 2249 2250 func getUserAccessTokens(c *Context, w http.ResponseWriter, r *http.Request) { 2251 if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_MANAGE_SYSTEM) { 2252 c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM) 2253 return 2254 } 2255 2256 accessTokens, err := c.App.GetUserAccessTokens(c.Params.Page, c.Params.PerPage) 2257 if err != nil { 2258 c.Err = err 2259 return 2260 } 2261 2262 w.Write([]byte(model.UserAccessTokenListToJson(accessTokens))) 2263 } 2264 2265 func getUserAccessTokensForUser(c *Context, w http.ResponseWriter, r *http.Request) { 2266 c.RequireUserId() 2267 if c.Err != nil { 2268 return 2269 } 2270 2271 if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_READ_USER_ACCESS_TOKEN) { 2272 c.SetPermissionError(model.PERMISSION_READ_USER_ACCESS_TOKEN) 2273 return 2274 } 2275 2276 if !c.App.SessionHasPermissionToUserOrBot(*c.App.Session(), c.Params.UserId) { 2277 c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS) 2278 return 2279 } 2280 2281 accessTokens, err := c.App.GetUserAccessTokensForUser(c.Params.UserId, c.Params.Page, c.Params.PerPage) 2282 if err != nil { 2283 c.Err = err 2284 return 2285 } 2286 2287 w.Write([]byte(model.UserAccessTokenListToJson(accessTokens))) 2288 } 2289 2290 func getUserAccessToken(c *Context, w http.ResponseWriter, r *http.Request) { 2291 c.RequireTokenId() 2292 if c.Err != nil { 2293 return 2294 } 2295 2296 if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_READ_USER_ACCESS_TOKEN) { 2297 c.SetPermissionError(model.PERMISSION_READ_USER_ACCESS_TOKEN) 2298 return 2299 } 2300 2301 accessToken, err := c.App.GetUserAccessToken(c.Params.TokenId, true) 2302 if err != nil { 2303 c.Err = err 2304 return 2305 } 2306 2307 if !c.App.SessionHasPermissionToUserOrBot(*c.App.Session(), accessToken.UserId) { 2308 c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS) 2309 return 2310 } 2311 2312 w.Write([]byte(accessToken.ToJson())) 2313 } 2314 2315 func revokeUserAccessToken(c *Context, w http.ResponseWriter, r *http.Request) { 2316 props := model.MapFromJson(r.Body) 2317 2318 tokenId := props["token_id"] 2319 if tokenId == "" { 2320 c.SetInvalidParam("token_id") 2321 } 2322 2323 auditRec := c.MakeAuditRecord("revokeUserAccessToken", audit.Fail) 2324 defer c.LogAuditRec(auditRec) 2325 auditRec.AddMeta("token_id", tokenId) 2326 c.LogAudit("") 2327 2328 if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_REVOKE_USER_ACCESS_TOKEN) { 2329 c.SetPermissionError(model.PERMISSION_REVOKE_USER_ACCESS_TOKEN) 2330 return 2331 } 2332 2333 accessToken, err := c.App.GetUserAccessToken(tokenId, false) 2334 if err != nil { 2335 c.Err = err 2336 return 2337 } 2338 2339 if user, errGet := c.App.GetUser(accessToken.UserId); errGet == nil { 2340 auditRec.AddMeta("user", user) 2341 } 2342 2343 if !c.App.SessionHasPermissionToUserOrBot(*c.App.Session(), accessToken.UserId) { 2344 c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS) 2345 return 2346 } 2347 2348 if err = c.App.RevokeUserAccessToken(accessToken); err != nil { 2349 c.Err = err 2350 return 2351 } 2352 2353 auditRec.Success() 2354 c.LogAudit("success - token_id=" + accessToken.Id) 2355 2356 ReturnStatusOK(w) 2357 } 2358 2359 func disableUserAccessToken(c *Context, w http.ResponseWriter, r *http.Request) { 2360 props := model.MapFromJson(r.Body) 2361 tokenId := props["token_id"] 2362 2363 if tokenId == "" { 2364 c.SetInvalidParam("token_id") 2365 } 2366 2367 auditRec := c.MakeAuditRecord("disableUserAccessToken", audit.Fail) 2368 defer c.LogAuditRec(auditRec) 2369 auditRec.AddMeta("token_id", tokenId) 2370 c.LogAudit("") 2371 2372 // No separate permission for this action for now 2373 if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_REVOKE_USER_ACCESS_TOKEN) { 2374 c.SetPermissionError(model.PERMISSION_REVOKE_USER_ACCESS_TOKEN) 2375 return 2376 } 2377 2378 accessToken, err := c.App.GetUserAccessToken(tokenId, false) 2379 if err != nil { 2380 c.Err = err 2381 return 2382 } 2383 2384 if user, errGet := c.App.GetUser(accessToken.UserId); errGet == nil { 2385 auditRec.AddMeta("user", user) 2386 } 2387 2388 if !c.App.SessionHasPermissionToUserOrBot(*c.App.Session(), accessToken.UserId) { 2389 c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS) 2390 return 2391 } 2392 2393 if err = c.App.DisableUserAccessToken(accessToken); err != nil { 2394 c.Err = err 2395 return 2396 } 2397 2398 auditRec.Success() 2399 c.LogAudit("success - token_id=" + accessToken.Id) 2400 2401 ReturnStatusOK(w) 2402 } 2403 2404 func enableUserAccessToken(c *Context, w http.ResponseWriter, r *http.Request) { 2405 props := model.MapFromJson(r.Body) 2406 2407 tokenId := props["token_id"] 2408 if tokenId == "" { 2409 c.SetInvalidParam("token_id") 2410 } 2411 2412 auditRec := c.MakeAuditRecord("enableUserAccessToken", audit.Fail) 2413 defer c.LogAuditRec(auditRec) 2414 auditRec.AddMeta("token_id", tokenId) 2415 c.LogAudit("") 2416 2417 // No separate permission for this action for now 2418 if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_CREATE_USER_ACCESS_TOKEN) { 2419 c.SetPermissionError(model.PERMISSION_CREATE_USER_ACCESS_TOKEN) 2420 return 2421 } 2422 2423 accessToken, err := c.App.GetUserAccessToken(tokenId, false) 2424 if err != nil { 2425 c.Err = err 2426 return 2427 } 2428 2429 if user, errGet := c.App.GetUser(accessToken.UserId); errGet == nil { 2430 auditRec.AddMeta("user", user) 2431 } 2432 2433 if !c.App.SessionHasPermissionToUserOrBot(*c.App.Session(), accessToken.UserId) { 2434 c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS) 2435 return 2436 } 2437 2438 if err = c.App.EnableUserAccessToken(accessToken); err != nil { 2439 c.Err = err 2440 return 2441 } 2442 2443 auditRec.Success() 2444 c.LogAudit("success - token_id=" + accessToken.Id) 2445 2446 ReturnStatusOK(w) 2447 } 2448 2449 func saveUserTermsOfService(c *Context, w http.ResponseWriter, r *http.Request) { 2450 props := model.StringInterfaceFromJson(r.Body) 2451 2452 userId := c.App.Session().UserId 2453 termsOfServiceId, ok := props["termsOfServiceId"].(string) 2454 if !ok { 2455 c.SetInvalidParam("termsOfServiceId") 2456 return 2457 } 2458 accepted, ok := props["accepted"].(bool) 2459 if !ok { 2460 c.SetInvalidParam("accepted") 2461 return 2462 } 2463 2464 auditRec := c.MakeAuditRecord("saveUserTermsOfService", audit.Fail) 2465 defer c.LogAuditRec(auditRec) 2466 auditRec.AddMeta("terms_id", termsOfServiceId) 2467 auditRec.AddMeta("accepted", accepted) 2468 2469 if user, err := c.App.GetUser(userId); err == nil { 2470 auditRec.AddMeta("user", user) 2471 } 2472 2473 if _, err := c.App.GetTermsOfService(termsOfServiceId); err != nil { 2474 c.Err = err 2475 return 2476 } 2477 2478 if err := c.App.SaveUserTermsOfService(userId, termsOfServiceId, accepted); err != nil { 2479 c.Err = err 2480 return 2481 } 2482 2483 auditRec.Success() 2484 c.LogAudit("TermsOfServiceId=" + termsOfServiceId + ", accepted=" + strconv.FormatBool(accepted)) 2485 2486 ReturnStatusOK(w) 2487 } 2488 2489 func getUserTermsOfService(c *Context, w http.ResponseWriter, r *http.Request) { 2490 userId := c.App.Session().UserId 2491 result, err := c.App.GetUserTermsOfService(userId) 2492 if err != nil { 2493 c.Err = err 2494 return 2495 } 2496 w.Write([]byte(result.ToJson())) 2497 } 2498 2499 func promoteGuestToUser(c *Context, w http.ResponseWriter, r *http.Request) { 2500 c.RequireUserId() 2501 if c.Err != nil { 2502 return 2503 } 2504 2505 auditRec := c.MakeAuditRecord("promoteGuestToUser", audit.Fail) 2506 defer c.LogAuditRec(auditRec) 2507 2508 if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_PROMOTE_GUEST) { 2509 c.SetPermissionError(model.PERMISSION_PROMOTE_GUEST) 2510 return 2511 } 2512 2513 user, err := c.App.GetUser(c.Params.UserId) 2514 if err != nil { 2515 c.Err = err 2516 return 2517 } 2518 auditRec.AddMeta("user", user) 2519 2520 if !user.IsGuest() { 2521 c.Err = model.NewAppError("Api4.promoteGuestToUser", "api.user.promote_guest_to_user.no_guest.app_error", nil, "", http.StatusNotImplemented) 2522 return 2523 } 2524 2525 if err := c.App.PromoteGuestToUser(user, c.App.Session().UserId); err != nil { 2526 c.Err = err 2527 return 2528 } 2529 2530 auditRec.Success() 2531 ReturnStatusOK(w) 2532 } 2533 2534 func demoteUserToGuest(c *Context, w http.ResponseWriter, r *http.Request) { 2535 c.RequireUserId() 2536 if c.Err != nil { 2537 return 2538 } 2539 2540 if c.App.Srv().License() == nil { 2541 c.Err = model.NewAppError("Api4.demoteUserToGuest", "api.team.demote_user_to_guest.license.error", nil, "", http.StatusNotImplemented) 2542 return 2543 } 2544 2545 if !*c.App.Config().GuestAccountsSettings.Enable { 2546 c.Err = model.NewAppError("Api4.demoteUserToGuest", "api.team.demote_user_to_guest.disabled.error", nil, "", http.StatusNotImplemented) 2547 return 2548 } 2549 2550 auditRec := c.MakeAuditRecord("demoteUserToGuest", audit.Fail) 2551 defer c.LogAuditRec(auditRec) 2552 2553 if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_DEMOTE_TO_GUEST) { 2554 c.SetPermissionError(model.PERMISSION_DEMOTE_TO_GUEST) 2555 return 2556 } 2557 2558 user, err := c.App.GetUser(c.Params.UserId) 2559 if err != nil { 2560 c.Err = err 2561 return 2562 } 2563 2564 if user.IsSystemAdmin() && !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_MANAGE_SYSTEM) { 2565 c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM) 2566 return 2567 } 2568 2569 auditRec.AddMeta("user", user) 2570 2571 if user.IsGuest() { 2572 c.Err = model.NewAppError("Api4.demoteUserToGuest", "api.user.demote_user_to_guest.already_guest.app_error", nil, "", http.StatusNotImplemented) 2573 return 2574 } 2575 2576 if err := c.App.DemoteUserToGuest(user); err != nil { 2577 c.Err = err 2578 return 2579 } 2580 2581 auditRec.Success() 2582 ReturnStatusOK(w) 2583 } 2584 2585 func publishUserTyping(c *Context, w http.ResponseWriter, r *http.Request) { 2586 c.RequireUserId() 2587 if c.Err != nil { 2588 return 2589 } 2590 2591 typingRequest := model.TypingRequestFromJson(r.Body) 2592 if typingRequest == nil { 2593 c.SetInvalidParam("typing_request") 2594 return 2595 } 2596 2597 if c.Params.UserId != c.App.Session().UserId && !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_MANAGE_SYSTEM) { 2598 c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM) 2599 return 2600 } 2601 2602 if !c.App.HasPermissionToChannel(c.Params.UserId, typingRequest.ChannelId, model.PERMISSION_CREATE_POST) { 2603 c.SetPermissionError(model.PERMISSION_CREATE_POST) 2604 return 2605 } 2606 2607 if err := c.App.PublishUserTyping(c.Params.UserId, typingRequest.ChannelId, typingRequest.ParentId); err != nil { 2608 c.Err = err 2609 return 2610 } 2611 2612 ReturnStatusOK(w) 2613 } 2614 2615 func verifyUserEmailWithoutToken(c *Context, w http.ResponseWriter, r *http.Request) { 2616 c.RequireUserId() 2617 if c.Err != nil { 2618 return 2619 } 2620 2621 user, err := c.App.GetUser(c.Params.UserId) 2622 if err != nil { 2623 c.Err = err 2624 return 2625 } 2626 2627 auditRec := c.MakeAuditRecord("verifyUserEmailWithoutToken", audit.Fail) 2628 defer c.LogAuditRec(auditRec) 2629 auditRec.AddMeta("user_id", user.Id) 2630 2631 if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_MANAGE_SYSTEM) { 2632 c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM) 2633 return 2634 } 2635 2636 if err := c.App.VerifyUserEmail(user.Id, user.Email); err != nil { 2637 c.Err = err 2638 return 2639 } 2640 2641 auditRec.Success() 2642 c.LogAudit("user verified") 2643 2644 w.Write([]byte(user.ToJson())) 2645 } 2646 2647 func convertUserToBot(c *Context, w http.ResponseWriter, r *http.Request) { 2648 c.RequireUserId() 2649 if c.Err != nil { 2650 return 2651 } 2652 2653 user, err := c.App.GetUser(c.Params.UserId) 2654 if err != nil { 2655 c.Err = err 2656 return 2657 } 2658 2659 auditRec := c.MakeAuditRecord("convertUserToBot", audit.Fail) 2660 defer c.LogAuditRec(auditRec) 2661 auditRec.AddMeta("user", user) 2662 2663 if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_MANAGE_SYSTEM) { 2664 c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM) 2665 return 2666 } 2667 2668 bot, err := c.App.ConvertUserToBot(user) 2669 if err != nil { 2670 c.Err = err 2671 return 2672 } 2673 2674 auditRec.Success() 2675 auditRec.AddMeta("convertedTo", bot) 2676 2677 w.Write(bot.ToJson()) 2678 } 2679 2680 func getUploadsForUser(c *Context, w http.ResponseWriter, r *http.Request) { 2681 c.RequireUserId() 2682 if c.Err != nil { 2683 return 2684 } 2685 2686 if c.Params.UserId != c.App.Session().UserId { 2687 c.Err = model.NewAppError("getUploadsForUser", "api.user.get_uploads_for_user.forbidden.app_error", nil, "", http.StatusForbidden) 2688 return 2689 } 2690 2691 uss, err := c.App.GetUploadSessionsForUser(c.Params.UserId) 2692 if err != nil { 2693 c.Err = err 2694 return 2695 } 2696 2697 w.Write([]byte(model.UploadSessionsToJson(uss))) 2698 } 2699 2700 func migrateAuthToLDAP(c *Context, w http.ResponseWriter, r *http.Request) { 2701 props := model.StringInterfaceFromJson(r.Body) 2702 from, ok := props["from"].(string) 2703 if !ok { 2704 c.SetInvalidParam("from") 2705 return 2706 } 2707 if len(from) == 0 || (from != "email" && from != "gitlab" && from != "saml" && from != "google" && from != "office365") { 2708 c.SetInvalidParam("from") 2709 return 2710 } 2711 2712 force, ok := props["force"].(bool) 2713 if !ok { 2714 c.SetInvalidParam("force") 2715 return 2716 } 2717 2718 matchField, ok := props["match_field"].(string) 2719 if !ok { 2720 c.SetInvalidParam("match_field") 2721 return 2722 } 2723 2724 auditRec := c.MakeAuditRecord("migrateAuthToLdap", audit.Fail) 2725 defer c.LogAuditRec(auditRec) 2726 auditRec.AddMeta("from", from) 2727 auditRec.AddMeta("match_field", matchField) 2728 auditRec.AddMeta("force", force) 2729 2730 if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_MANAGE_SYSTEM) { 2731 c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM) 2732 return 2733 } 2734 2735 if c.App.Srv().License() == nil || !*c.App.Srv().License().Features.LDAP { 2736 c.Err = model.NewAppError("api.migrateAuthToLDAP", "api.admin.ldap.not_available.app_error", nil, "", http.StatusNotImplemented) 2737 return 2738 } 2739 2740 // Email auth in Mattermost system is represented by "" 2741 if from == "email" { 2742 from = "" 2743 } 2744 2745 if migrate := c.App.AccountMigration(); migrate != nil { 2746 if err := migrate.MigrateToLdap(from, matchField, force, false); err != nil { 2747 c.Err = model.NewAppError("api.migrateAuthToLdap", "api.migrate_to_saml.error", nil, err.Error(), http.StatusInternalServerError) 2748 return 2749 } 2750 } else { 2751 c.Err = model.NewAppError("api.migrateAuthToLdap", "api.admin.ldap.not_available.app_error", nil, "", http.StatusNotImplemented) 2752 return 2753 } 2754 2755 auditRec.Success() 2756 ReturnStatusOK(w) 2757 } 2758 2759 func migrateAuthToSaml(c *Context, w http.ResponseWriter, r *http.Request) { 2760 props := model.StringInterfaceFromJson(r.Body) 2761 from, ok := props["from"].(string) 2762 if !ok { 2763 c.SetInvalidParam("from") 2764 return 2765 } 2766 if len(from) == 0 || (from != "email" && from != "gitlab" && from != "ldap" && from != "google" && from != "office365") { 2767 c.SetInvalidParam("from") 2768 return 2769 } 2770 2771 auto, ok := props["auto"].(bool) 2772 if !ok { 2773 c.SetInvalidParam("auto") 2774 return 2775 } 2776 matches, ok := props["matches"].(map[string]interface{}) 2777 if !ok { 2778 c.SetInvalidParam("matches") 2779 return 2780 } 2781 usersMap := model.MapFromJson(strings.NewReader(model.StringInterfaceToJson(matches))) 2782 2783 auditRec := c.MakeAuditRecord("migrateAuthToSaml", audit.Fail) 2784 defer c.LogAuditRec(auditRec) 2785 auditRec.AddMeta("from", from) 2786 auditRec.AddMeta("matches", matches) 2787 auditRec.AddMeta("auto", auto) 2788 2789 if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_MANAGE_SYSTEM) { 2790 c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM) 2791 return 2792 } 2793 2794 if c.App.Srv().License() == nil || !*c.App.Srv().License().Features.SAML { 2795 c.Err = model.NewAppError("api.migrateAuthToSaml", "api.admin.saml.not_available.app_error", nil, "", http.StatusNotImplemented) 2796 return 2797 } 2798 2799 // Email auth in Mattermost system is represented by "" 2800 if from == "email" { 2801 from = "" 2802 } 2803 2804 if migrate := c.App.AccountMigration(); migrate != nil { 2805 if err := migrate.MigrateToSaml(from, usersMap, auto, false); err != nil { 2806 c.Err = model.NewAppError("api.migrateAuthToSaml", "api.migrate_to_saml.error", nil, err.Error(), http.StatusInternalServerError) 2807 return 2808 } 2809 } else { 2810 c.Err = model.NewAppError("api.migrateAuthToSaml", "api.admin.saml.not_available.app_error", nil, "", http.StatusNotImplemented) 2811 return 2812 } 2813 2814 auditRec.Success() 2815 ReturnStatusOK(w) 2816 } 2817 2818 func getThreadsForUser(c *Context, w http.ResponseWriter, r *http.Request) { 2819 c.RequireUserId().RequireTeamId() 2820 if c.Err != nil { 2821 return 2822 } 2823 2824 if !c.App.SessionHasPermissionToUser(*c.App.Session(), c.Params.UserId) { 2825 c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS) 2826 return 2827 } 2828 2829 options := model.GetUserThreadsOpts{ 2830 Since: 0, 2831 Page: 0, 2832 PageSize: 30, 2833 Extended: false, 2834 Deleted: false, 2835 } 2836 2837 sinceString := r.URL.Query().Get("since") 2838 if len(sinceString) > 0 { 2839 since, parseError := strconv.ParseUint(sinceString, 10, 64) 2840 if parseError != nil { 2841 c.SetInvalidParam("since") 2842 return 2843 } 2844 options.Since = since 2845 } 2846 2847 pageString := r.URL.Query().Get("page") 2848 if len(pageString) > 0 { 2849 page, parseError := strconv.ParseUint(pageString, 10, 64) 2850 if parseError != nil { 2851 c.SetInvalidParam("page") 2852 return 2853 } 2854 options.Page = page 2855 } 2856 2857 pageSizeString := r.URL.Query().Get("pageSize") 2858 if len(pageString) > 0 { 2859 pageSize, parseError := strconv.ParseUint(pageSizeString, 10, 64) 2860 if parseError != nil { 2861 c.SetInvalidParam("pageSize") 2862 return 2863 } 2864 options.PageSize = pageSize 2865 } 2866 2867 deletedStr := r.URL.Query().Get("deleted") 2868 extendedStr := r.URL.Query().Get("extended") 2869 2870 options.Deleted, _ = strconv.ParseBool(deletedStr) 2871 options.Extended, _ = strconv.ParseBool(extendedStr) 2872 2873 threads, err := c.App.GetThreadsForUser(c.Params.UserId, c.Params.TeamId, options) 2874 if err != nil { 2875 c.Err = err 2876 return 2877 } 2878 2879 w.Write([]byte(threads.ToJson())) 2880 } 2881 2882 func updateReadStateThreadByUser(c *Context, w http.ResponseWriter, r *http.Request) { 2883 c.RequireUserId().RequireThreadId().RequireTimestamp().RequireTeamId() 2884 if c.Err != nil { 2885 return 2886 } 2887 2888 auditRec := c.MakeAuditRecord("updateReadStateThreadByUser", audit.Fail) 2889 defer c.LogAuditRec(auditRec) 2890 auditRec.AddMeta("user_id", c.Params.UserId) 2891 auditRec.AddMeta("thread_id", c.Params.ThreadId) 2892 auditRec.AddMeta("team_id", c.Params.TeamId) 2893 auditRec.AddMeta("timestamp", c.Params.Timestamp) 2894 if !c.App.SessionHasPermissionToUser(*c.App.Session(), c.Params.UserId) { 2895 c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS) 2896 return 2897 } 2898 2899 err := c.App.UpdateThreadReadForUser(c.Params.UserId, c.Params.TeamId, c.Params.ThreadId, c.Params.Timestamp) 2900 if err != nil { 2901 c.Err = err 2902 return 2903 } 2904 2905 ReturnStatusOK(w) 2906 2907 auditRec.Success() 2908 } 2909 2910 func unfollowThreadByUser(c *Context, w http.ResponseWriter, r *http.Request) { 2911 c.RequireUserId().RequireThreadId().RequireTeamId() 2912 if c.Err != nil { 2913 return 2914 } 2915 2916 auditRec := c.MakeAuditRecord("unfollowThreadByUser", audit.Fail) 2917 defer c.LogAuditRec(auditRec) 2918 auditRec.AddMeta("user_id", c.Params.UserId) 2919 auditRec.AddMeta("thread_id", c.Params.ThreadId) 2920 auditRec.AddMeta("team_id", c.Params.TeamId) 2921 2922 if !c.App.SessionHasPermissionToUser(*c.App.Session(), c.Params.UserId) { 2923 c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS) 2924 return 2925 } 2926 2927 err := c.App.UpdateThreadFollowForUser(c.Params.UserId, c.Params.ThreadId, false) 2928 if err != nil { 2929 c.Err = err 2930 return 2931 } 2932 2933 ReturnStatusOK(w) 2934 2935 auditRec.Success() 2936 } 2937 2938 func followThreadByUser(c *Context, w http.ResponseWriter, r *http.Request) { 2939 c.RequireUserId().RequireThreadId().RequireTeamId() 2940 if c.Err != nil { 2941 return 2942 } 2943 2944 auditRec := c.MakeAuditRecord("followThreadByUser", audit.Fail) 2945 defer c.LogAuditRec(auditRec) 2946 auditRec.AddMeta("user_id", c.Params.UserId) 2947 auditRec.AddMeta("thread_id", c.Params.ThreadId) 2948 auditRec.AddMeta("team_id", c.Params.TeamId) 2949 2950 if !c.App.SessionHasPermissionToUser(*c.App.Session(), c.Params.UserId) { 2951 c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS) 2952 return 2953 } 2954 2955 err := c.App.UpdateThreadFollowForUser(c.Params.UserId, c.Params.ThreadId, true) 2956 if err != nil { 2957 c.Err = err 2958 return 2959 } 2960 2961 ReturnStatusOK(w) 2962 auditRec.Success() 2963 } 2964 2965 func updateReadStateAllThreadsByUser(c *Context, w http.ResponseWriter, r *http.Request) { 2966 c.RequireUserId().RequireTeamId() 2967 if c.Err != nil { 2968 return 2969 } 2970 2971 auditRec := c.MakeAuditRecord("updateReadStateAllThreadsByUser", audit.Fail) 2972 defer c.LogAuditRec(auditRec) 2973 auditRec.AddMeta("user_id", c.Params.UserId) 2974 auditRec.AddMeta("team_id", c.Params.TeamId) 2975 2976 if !c.App.SessionHasPermissionToUser(*c.App.Session(), c.Params.UserId) { 2977 c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS) 2978 return 2979 } 2980 2981 err := c.App.UpdateThreadsReadForUser(c.Params.UserId, c.Params.TeamId) 2982 if err != nil { 2983 c.Err = err 2984 return 2985 } 2986 2987 ReturnStatusOK(w) 2988 auditRec.Success() 2989 }