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

Function replyOfflineTopicSetSub

server/hub.go:778–868  ·  view source on GitHub ↗

replyOfflineTopicSetSub updates Desc.Private and Sub.Mode when the topic is not loaded in memory. Only Private and Mode are updated and only for the requester. The requester must be subscribed to the topic but does not need to be attached.

(sess *Session, msg *ClientComMessage)

Source from the content-addressed store, hash-verified

776// Only Private and Mode are updated and only for the requester. The requester must be subscribed to the
777// topic but does not need to be attached.
778func replyOfflineTopicSetSub(sess *Session, msg *ClientComMessage) {
779 now := types.TimeNow()
780
781 if (msg.Set.Desc == nil || msg.Set.Desc.Private == nil) && (msg.Set.Sub == nil || msg.Set.Sub.Mode == "") {
782 sess.queueOut(InfoNotModifiedReply(msg, now))
783 return
784 }
785
786 if msg.Set.Sub != nil && msg.Set.Sub.User != "" && msg.Set.Sub.User != msg.AsUser {
787 sess.queueOut(ErrPermissionDeniedReply(msg, now))
788 return
789 }
790
791 asUid := types.ParseUserId(msg.AsUser)
792
793 topicName := msg.RcptTo
794 if types.IsChannel(msg.Original) {
795 topicName = msg.Original
796 }
797
798 sub, err := store.Subs.Get(topicName, asUid, false)
799 if err != nil {
800 logs.Warn.Println("replyOfflineTopicSetSub get sub:", err)
801 sess.queueOut(decodeStoreErrorExplicitTs(err, msg.Id, msg.Original, now, msg.Timestamp, nil))
802 return
803 }
804
805 if sub == nil {
806 sess.queueOut(ErrNotFoundExplicitTs(msg.Id, msg.Original, now, msg.Timestamp))
807 return
808 }
809
810 update := make(map[string]any)
811 if msg.Set.Desc != nil && msg.Set.Desc.Private != nil {
812 private, ok := msg.Set.Desc.Private.(map[string]any)
813 if !ok {
814 update = map[string]any{"Private": msg.Set.Desc.Private}
815 } else if private, changed := mergeInterfaces(sub.Private, private); changed {
816 update = map[string]any{"Private": private}
817 }
818 }
819
820 if msg.Set.Sub != nil && msg.Set.Sub.Mode != "" {
821 var modeWant types.AccessMode
822 if err = modeWant.UnmarshalText([]byte(msg.Set.Sub.Mode)); err != nil {
823 logs.Warn.Println("replyOfflineTopicSetSub mode:", err)
824 sess.queueOut(decodeStoreErrorExplicitTs(err, msg.Id, msg.Original, now, msg.Timestamp, nil))
825 return
826 }
827
828 if modeWant.IsOwner() != sub.ModeWant.IsOwner() {
829 // No ownership changes here.
830 sess.queueOut(ErrPermissionDeniedReply(msg, now))
831 return
832 }
833
834 if types.GetTopicCat(msg.RcptTo) == types.TopicCatP2P {
835 // For P2P topics ignore requests exceeding typesModeCP2P and do not allow

Callers 1

runMethod · 0.85

Calls 15

UnmarshalTextMethod · 0.95
IsOwnerMethod · 0.95
TimeNowFunction · 0.92
ParseUserIdFunction · 0.92
IsChannelFunction · 0.92
GetTopicCatFunction · 0.92
InfoNotModifiedReplyFunction · 0.85
ErrPermissionDeniedReplyFunction · 0.85
ErrNotFoundExplicitTsFunction · 0.85
mergeInterfacesFunction · 0.85
NoErrParamsReplyFunction · 0.85

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…