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