MCPcopy
hub / github.com/tinode/chat / replyDelUser

Function replyDelUser

server/user.go:593–685  ·  view source on GitHub ↗

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)

Source from the content-addressed store, hash-verified

591// 6. Report success or failure.
592// 7. Terminate user's last session.
593func 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")

Callers 1

delMethod · 0.85

Calls 15

UserIdMethod · 0.95
IsZeroMethod · 0.95
ParseUserIdFunction · 0.92
ErrPolicyFunction · 0.85
ErrMalformedFunction · 0.85
ErrPermissionDeniedFunction · 0.85
ErrOperationNotAllowedFunction · 0.85
usersRemoveUserFunction · 0.85
presSubsOfflineOfflineFunction · 0.85
decodeStoreErrorFunction · 0.85
NoErrFunction · 0.85

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…