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