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

Method anotherUserSub

server/topic.go:1881–2079  ·  view source on GitHub ↗

anotherUserSub processes a request to initiate an invite or approve a subscription request from another user. Returns changed == true if user's access mode has changed. Handle these cases: A. Sharer or Approver is inviting another user for the first time (no prior subscription) B. Sharer or Approver

(sess *Session, asUid, target types.Uid, asChan bool,
	pkt *ClientComMessage)

Source from the content-addressed store, hash-verified

1879// B. Sharer or Approver is re-inviting another user (adjusting modeGiven, modeWant is still Unset)
1880// C. Approver is changing modeGiven for another user, modeWant != Unset
1881func (t *Topic) anotherUserSub(sess *Session, asUid, target types.Uid, asChan bool,
1882 pkt *ClientComMessage) (*MsgAccessMode, error) {
1883
1884 now := types.TimeNow()
1885 set := pkt.Set
1886
1887 // Check if approver actually has permission to manage sharing
1888 hostData, ok := t.perUser[asUid]
1889 // Access mode of the person who is executing this approval process
1890 hostMode := hostData.modeGiven & hostData.modeWant
1891 if !ok || !hostMode.IsSharer() {
1892 sess.queueOut(ErrPermissionDeniedReply(pkt, now))
1893 return nil, errors.New("topic access denied; approver has no permission")
1894 }
1895
1896 if asChan {
1897 // TODO: need to implement promoting reader to subscriber. Rejecting for now.
1898 sess.queueOut(ErrPermissionDeniedReply(pkt, now))
1899 return nil, errors.New("topic access denied: cannot subscribe reader to channel")
1900 }
1901
1902 // Check if topic is suspended.
1903 if t.isReadOnly() {
1904 sess.queueOut(ErrPermissionDeniedReply(pkt, now))
1905 return nil, errors.New("topic is suspended")
1906 }
1907
1908 // Parse the access mode granted
1909 modeGiven := types.ModeUnset
1910 if set.Sub.Mode != "" {
1911 if err := modeGiven.UnmarshalText([]byte(set.Sub.Mode)); err != nil {
1912 sess.queueOut(ErrMalformedReply(pkt, now))
1913 return nil, err
1914 }
1915
1916 // Make sure the new permissions are reasonable in P2P topics: permissions no greater than allowed,
1917 // approver permission cannot be removed.
1918 if t.cat == types.TopicCatP2P {
1919 modeGiven = (modeGiven & globals.typesModeCP2P) | types.ModeApprove
1920 }
1921 }
1922
1923 // Make sure only the owner & approvers can set non-default access mode
1924 if modeGiven != types.ModeUnset && !hostMode.IsAdmin() {
1925 sess.queueOut(ErrPermissionDeniedReply(pkt, now))
1926 return nil, errors.New("sharer cannot set explicit modeGiven")
1927 }
1928
1929 // Make sure no one but the owner can do an ownership transfer
1930 if modeGiven.IsOwner() && t.owner != asUid {
1931 sess.queueOut(ErrPermissionDeniedReply(pkt, now))
1932 return nil, errors.New("attempt to transfer ownership by non-owner")
1933 }
1934
1935 // Access mode values as they were before this request was processed.
1936 oldWant := types.ModeUnset
1937 oldGiven := types.ModeUnset
1938

Callers 1

replySetSubMethod · 0.95

Calls 15

isReadOnlyMethod · 0.95
subsCountMethod · 0.95
accessForMethod · 0.95
IsJoinerMethod · 0.95
pushForP2PSubMethod · 0.95
notifySubChangeMethod · 0.95
evictUserMethod · 0.95
TimeNowFunction · 0.92
ErrPermissionDeniedReplyFunction · 0.85
ErrMalformedReplyFunction · 0.85
ErrPolicyReplyFunction · 0.85

Tested by

no test coverage detected