Skip to content

Commit

Permalink
debugging channels
Browse files Browse the repository at this point in the history
  • Loading branch information
or-else committed Jul 26, 2020
1 parent 3db9ecd commit 4972f68
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 22 deletions.
8 changes: 3 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,11 @@ When you register a new account you are asked for an email address to send valid
* [iOS](https://github.com/tinode/ios)
* [Web](https://github.com/tinode/webapp/)
* Scriptable [command line](tn-cli/)
* One-on-one messaging.
* Group messaging with every member's access permissions managed individually. The maximum number of members is configurable (128 by default).
* One-on-one and group messaging.
* Channels with an unlimited number (or hundreds of thousands) of members.
* Sharded clustering with failover.
* Flexible access control with permissions for various actions.
* Server-generated presence notifications for people, group conversations.
* Server-generated presence notifications for people, group chats.
* Support for custom authentication backends.
* Bindings for various programming languages:
* Javascript with no external dependencies.
Expand All @@ -93,15 +93,13 @@ When you register a new account you are asked for an email address to send valid
* Support for client-side data caching.
* Ability to block unwanted communication server-side.
* Anonymous users (important for use cases related to tech support over chat).
* Push notifications using [FCM](https://firebase.google.com/docs/cloud-messaging/) or [TNPG](server/push/tnpg/).
* Storage and out of band transfer of large objects like video files using local file system or Amazon S3.
* Plugins to extend functionality, for example, to enable chatbots.

### Planned

* [Federation](https://en.wikipedia.org/wiki/Federation_(information_technology)).
* End to end encryption with [OTR](https://en.wikipedia.org/wiki/Off-the-Record_Messaging) for one-on-one messaging and undecided method for group messaging.
* Channels with an unlimited number (or hundreds of thousands) of members with bearer token access control.
* Hot standby.
* Different levels of message persistence (from strict persistence to "store until delivered" to purely ephemeral messaging).

Expand Down
1 change: 1 addition & 0 deletions docs/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,7 @@ A `channel` topic is different from the non-channel group topic in the following
* Channel topic is created by sending `{sub topic="nch"}`. Sending `{sub topic="new"}` will create a group topic without enabling channel functionality.
* Sending `{sub topic="chnAbC123"}` will create a `reader` subscription to a channel. A non-channel topic will reject such subscription request.
* When searching for topics using [`fnd`](#fnd-and-tags-finding-users-and-topics), channels will show addresses with `chn` prefixes, non-channel topic will show with `grp` prefixes.
* Messages received by readers on channels have no `From` field. Normal subscribers will receive messages with `From` containing ID of the sender.
* Default permissions for a channel and non-channel group topics are different: channel group topic grants no permissions at all.
* A subscriber joining or leaving the topic (regular or channel-enabled) generates a `{pres}` message to all other subscribers who are currently in the joined state with the topic and have appropriate permissions. Reader joining or leaving the channel generates no `{pres}` message.

Expand Down
5 changes: 3 additions & 2 deletions server/datamodel.go
Original file line number Diff line number Diff line change
Expand Up @@ -882,13 +882,14 @@ func NoErrShutdown(ts time.Time) *ServerComMessage {
}

// NoErrDelivered means requested content has been delivered (208).
func NoErrDeliveredParams(ts time.Time, topic string, params interface{}) *ServerComMessage {
func NoErrDeliveredParams(id, topic string, ts time.Time, params interface{}) *ServerComMessage {
return &ServerComMessage{Ctrl: &MsgServerCtrl{
Id: id,
Code: http.StatusAlreadyReported, // 208
Text: "delivered",
Topic: topic,
Params: params,
Timestamp: ts}}
Timestamp: ts}, Id: id}
}

// 3xx
Expand Down
38 changes: 23 additions & 15 deletions server/topic.go
Original file line number Diff line number Diff line change
Expand Up @@ -1024,17 +1024,19 @@ func (t *Topic) subscriptionReply(h *Hub, join *sessionJoin) error {

params := map[string]interface{}{}
if changed {
pud := t.perUser[asUid]
// Report back the assigned access mode.
params["acs"] = &MsgAccessMode{
Given: pud.modeGiven.String(),
Want: pud.modeWant.String(),
Mode: (pud.modeGiven & pud.modeWant).String()}
} else if isChannel(join.pkt.Original) {
params["acs"] = &MsgAccessMode{
Given: types.ModeCChn.String()
Want: types.ModeCChn.String()
Mode: types.ModeCChn.String()}
if isChannel(join.pkt.Original) {
params["acs"] = &MsgAccessMode{
Given: types.ModeCChn.String(),
Want: types.ModeCChn.String(),
Mode: types.ModeCChn.String()}
} else {
pud := t.perUser[asUid]
// Report back the assigned access mode.
params["acs"] = &MsgAccessMode{
Given: pud.modeGiven.String(),
Want: pud.modeWant.String(),
Mode: (pud.modeGiven & pud.modeWant).String()}
}
}

toriginal := t.original(asUid)
Expand Down Expand Up @@ -1317,7 +1319,6 @@ func (t *Topic) thisUserSub(h *Hub, sess *Session, pkt *ClientComMessage, asUid
}

if !isChanSub {

// If topic is being muted, send "off" notification and disable updates.
// Do it before applying the new permissions.
if (oldWant & oldGiven).IsPresencer() && !(userData.modeWant & userData.modeGiven).IsPresencer() {
Expand Down Expand Up @@ -2137,9 +2138,11 @@ func (t *Topic) replyGetData(sess *Session, asUid types.Uid, id string, req *Msg
return errors.New("invalid MsgGetOpts query")
}

asChan := isChannel(toriginal)

// Check if the user has permission to read the topic data
count := 0
if userData := t.perUser[asUid]; (userData.modeGiven & userData.modeWant).IsReader() {
if userData := t.perUser[asUid]; (userData.modeGiven & userData.modeWant).IsReader() || asChan {
// Read messages from DB
messages, err := store.Messages.GetAll(t.name, asUid, msgOpts2storeOpts(req))
if err != nil {
Expand All @@ -2152,11 +2155,16 @@ func (t *Topic) replyGetData(sess *Session, asUid types.Uid, id string, req *Msg
count = len(messages)
for i := range messages {
mm := &messages[i]
from := ""
if !asChan {
// Don't show sender for channel readers
from = types.ParseUid(mm.From).UserId()
}
sess.queueOut(&ServerComMessage{Data: &MsgServerData{
Topic: toriginal,
Head: mm.Head,
SeqId: mm.SeqId,
From: types.ParseUid(mm.From).UserId(),
From: from,
Timestamp: mm.CreatedAt,
Content: mm.Content}})
}
Expand Down Expand Up @@ -2334,7 +2342,7 @@ func (t *Topic) replyGetDel(sess *Session, asUid types.Uid, id string, req *MsgG
}

// Check if the user has permission to read the topic data and the request is valid
if userData := t.perUser[asUid]; (userData.modeGiven & userData.modeWant).IsReader() {
if userData := t.perUser[asUid]; (userData.modeGiven & userData.modeWant).IsReader() || isChannel(toriginal) {
ranges, delID, err := store.Messages.GetDeleted(t.name, asUid, msgOpts2storeOpts(req))
if err != nil {
sess.queueOut(ErrUnknown(id, toriginal, now))
Expand Down

0 comments on commit 4972f68

Please sign in to comment.