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