Request to delete a user: 1. Disable user's login 2. Terminate all user's sessions except the current session. 3. Stop all active topics 4. Notify other subscribers that topics are being deleted. 5. Delete user from the database. 6. Report success or failure. 7. Terminate user's last session.
(s *Session, msg *ClientComMessage)
| 591 | // 6. Report success or failure. |
| 592 | // 7. Terminate user's last session. |
| 593 | func replyDelUser(s *Session, msg *ClientComMessage) { |
| 594 | var uid types.Uid |
| 595 | |
| 596 | if msg.Del.User == "" || msg.Del.User == s.uid.UserId() { |
| 597 | // Check if account deletion is disabled. |
| 598 | if globals.permanentAccounts && s.authLvl != auth.LevelRoot { |
| 599 | logs.Warn.Println("replyDelUser: account deletion disabled", s.sid) |
| 600 | s.queueOut(ErrPolicy(msg.Id, "", msg.Timestamp)) |
| 601 | return |
| 602 | } |
| 603 | |
| 604 | // Delete current user. |
| 605 | uid = s.uid |
| 606 | } else if s.authLvl == auth.LevelRoot { |
| 607 | // Delete another user. |
| 608 | uid = types.ParseUserId(msg.Del.User) |
| 609 | if uid.IsZero() { |
| 610 | logs.Warn.Println("replyDelUser: invalid user ID", msg.Del.User, s.sid) |
| 611 | s.queueOut(ErrMalformed(msg.Id, "", msg.Timestamp)) |
| 612 | return |
| 613 | } |
| 614 | } else { |
| 615 | logs.Warn.Println("replyDelUser: illegal attempt to delete another user", msg.Del.User, s.sid) |
| 616 | s.queueOut(ErrPermissionDenied(msg.Id, "", msg.Timestamp)) |
| 617 | return |
| 618 | } |
| 619 | |
| 620 | // Disable all authenticators |
| 621 | authnames := store.Store.GetAuthNames() |
| 622 | for _, name := range authnames { |
| 623 | hdl := store.Store.GetLogicalAuthHandler(name) |
| 624 | if !hdl.IsInitialized() { |
| 625 | continue |
| 626 | } |
| 627 | if err := hdl.DelRecords(uid); err != nil { |
| 628 | // This could be completely benign, i.e. authenticator exists but not used. |
| 629 | logs.Warn.Println("replyDelUser: failed to delete auth record", uid.UserId(), name, err, s.sid) |
| 630 | if storeErr, ok := err.(types.StoreError); ok && storeErr == types.ErrUnsupported { |
| 631 | // Authenticator refused to delete record: user account cannot be deleted. |
| 632 | s.queueOut(ErrOperationNotAllowed(msg.Id, "", msg.Timestamp)) |
| 633 | return |
| 634 | } |
| 635 | } |
| 636 | } |
| 637 | |
| 638 | // Terminate all sessions. Skip the current session so the requester gets a response. |
| 639 | globals.sessionStore.EvictUser(uid, s.sid) |
| 640 | // Remove user from cache and announce to cluster that the user is deleted. |
| 641 | usersRemoveUser(uid) |
| 642 | |
| 643 | // Stop topics where the user is the owner and p2p topics. |
| 644 | done := make(chan bool) |
| 645 | globals.hub.unreg <- &topicUnreg{forUser: uid, del: msg.Del.Hard, done: done} |
| 646 | <-done |
| 647 | |
| 648 | // Notify users of interest that the user is gone. |
| 649 | if uoi, err := store.Users.GetSubs(uid); err == nil { |
| 650 | presUsersOfInterestOffline(uid, uoi, "gone") |
no test coverage detected
searching dependent graphs…