replyLeaveUnsub is a request to unsubscribe user and detach all user's sessions from topic.
(sess *Session, msg *ClientComMessage, asUid types.Uid)
| 3429 | |
| 3430 | // replyLeaveUnsub is a request to unsubscribe user and detach all user's sessions from topic. |
| 3431 | func (t *Topic) replyLeaveUnsub(sess *Session, msg *ClientComMessage, asUid types.Uid) error { |
| 3432 | now := types.TimeNow() |
| 3433 | |
| 3434 | if asUid.IsZero() { |
| 3435 | panic("replyLeaveUnsub: zero asUid") |
| 3436 | } |
| 3437 | |
| 3438 | if t.owner == asUid { |
| 3439 | if msg.init { |
| 3440 | sess.queueOut(ErrPermissionDeniedReply(msg, now)) |
| 3441 | } |
| 3442 | return errors.New("replyLeaveUnsub: owner cannot unsubscribe") |
| 3443 | } |
| 3444 | |
| 3445 | var err error |
| 3446 | var asChan bool |
| 3447 | if msg.init { |
| 3448 | asChan, err = t.verifyChannelAccess(msg.Original) |
| 3449 | if err != nil { |
| 3450 | sess.queueOut(ErrNotFoundReply(msg, now)) |
| 3451 | return errors.New("replyLeaveUnsub: incorrect addressing of channel") |
| 3452 | } |
| 3453 | } |
| 3454 | |
| 3455 | pud := t.perUser[asUid] |
| 3456 | // Delete user's subscription from the database; msg could be nil, so cannot use msg.Original. |
| 3457 | if pud.isChan { |
| 3458 | // Handle channel reader. |
| 3459 | err = store.Subs.Delete(types.GrpToChn(t.name), asUid) |
| 3460 | } else { |
| 3461 | // Handle subscriber. |
| 3462 | err = store.Subs.Delete(t.name, asUid) |
| 3463 | } |
| 3464 | |
| 3465 | if err != nil { |
| 3466 | if msg.init { |
| 3467 | if err == types.ErrNotFound { |
| 3468 | sess.queueOut(InfoNoActionReply(msg, now)) |
| 3469 | err = nil |
| 3470 | } else { |
| 3471 | sess.queueOut(ErrUnknownReply(msg, now)) |
| 3472 | } |
| 3473 | } |
| 3474 | return err |
| 3475 | } |
| 3476 | |
| 3477 | if msg.init { |
| 3478 | sess.queueOut(NoErrReply(msg, now)) |
| 3479 | } |
| 3480 | |
| 3481 | var oldWant types.AccessMode |
| 3482 | var oldGiven types.AccessMode |
| 3483 | if !asChan { |
| 3484 | // Update cached unread count: negative value |
| 3485 | if (pud.modeWant & pud.modeGiven).IsReader() { |
| 3486 | usersUpdateUnread(asUid, pud.readID-t.lastID, true) |
| 3487 | } |
| 3488 | oldWant, oldGiven = pud.modeWant, pud.modeGiven |
no test coverage detected