Selective Deliveries
As our first introduction to ACLs, in this section, we will employ ACLs on our messages to perform selective deliveries.
ACLs are a way to define fine-grained access to entities within Mitter.io. You can define which user (or class of users) can or cannot perform an action. ACLs can also be modified during the lifetime of an entity (except for
Messages
) to introduce extremely rich behavior for your apps.In this example, what we will do is allow users to send private messages within a group channel. Whenever a user types a message starting with @username, it will send out a message on the group, but ONLY to that particular user.
An ACL is made up of two lists: the p-list (or the
plusAppliedList
) and the m-list (or the minusAppliedList
). A given user (also called as an accessor
) can perform an action, if for the action the accessor is a part of at least one selector in the plusAppliedList
and is a part of no selector in the minusAppliedList
. For example, if @john were to send a message only to @candice, his message would have the following ACL:appliedAcls: {
plusAppliedAcls: ["read_message:user(@candice)"],
minusAppliedAcls: []
}
On the other hand, if @candice wanted to send a message to everyone except @john, the ACLs on her message would look like:
appliedAcls: {
plusAppliedAcls: ["read_message:any_user()"],
minusAppliedAcls: ["read_message:user(@john)"]
}
We need to now allow users to mention specific users when sending messages and attach the corresponding ACLs. To do this, open up
ChatComponent.ts
and modify the sendMessage
function:ChannelComponent.js
sendMessage() {
const mitter = this.props.mitter
const messageToSend = this.state.typedMessage
const privateMessagePattern = /^(@[a-zA-Z0-9]+)/ // [1]
const privateMessageMatch = messageToSend.match(privateMessagePattern)
let appliedAcls = null
if (privateMessageMatch !== null) {
appliedAcls = {
plusAppliedAcls: [ // [2]
`read_message:user(${mitter.me().identifier})`,
`read_message:user(${privateMessageMatch[0]})`
]
}
}
this.setState((prevState) => Object.assign({}, prevState, {
typedMessage: ''
}))
this.messageInput.focus()
mitter.clients().messages()
.sendMessage(this.state.activeChannel, {
senderId: mitter.me(),
textPayload: this.state.typedMessage,
timelineEvents: [
{
type: "mitter.mtet.SentTime",
eventTimeMs: new Date().getTime(),
subject: mitter.me()
}
],
appliedAcls: appliedAcls // [3]
})
}
Everything is the same as the previous function, so let's discuss what we have changed so far:
- 1.We are using a pattern to match the beginning of a string starting immediately with
@
followed by a sequence of alphanumeric characters. This will match any string that starts with a pattern like@john
,@candice
etc. - 2.If we find that the pattern matches, we construct the ACL object. If no such pattern is found, the ACL object stays as
null
. There are two things to note here. First, we specify the identifiers in an ACL string directly; they are not nested inside anyidentifier
object. This is because Mitter.io ACLs use a custom syntax and are not JSON objects. Second, we have added a read privilege for the sending user as well. When you do not use ACLs, Mitter.io attaches ACLs that allow the user and all the participants in a channel to read the message; but if you decide to use ACLs, then Mitter.io does not perform an operation on the incoming ACLs. So if you did not provide a read message privilege for the user, that message would not be delivered even to the sender. - 3.Finally we attach the ACLs to the message object.
Now open up three browser windows pointing to
http://localhost:3000/user/@john
, http://localhost:3000/user/@amy
and http://localhost:3000/user/@candice
. Point to the #roadtrip
channel in all three of them. Try sending out message to each other and mentioning a specific user and see what happens. Here's a quick demo of this app in action:
A demo app showing private replies within a group chat
We would also like to render such private messages differently. Maybe, send them as non-text messages itself? In the next section, we will be looking at exploring custom payloads and an introduction to some Mitter helper components.
Last modified 4yr ago