Skip to content

Instantly share code, notes, and snippets.

@ianjennings
Last active July 19, 2018 02:04
Show Gist options
  • Select an option

  • Save ianjennings/691e177d87a3cfa0a00d165b4792f5ef to your computer and use it in GitHub Desktop.

Select an option

Save ianjennings/691e177d87a3cfa0a00d165b4792f5ef to your computer and use it in GitHub Desktop.
This is an example auth policy for PubNub ChatEngine that sets the first user to enter a new private chat as the owner. Any additional users must be invited by a user that is already in the chat.
// function to check if a uuid (who) exists in a db record (and is permitted in the channel)
let isAuthed = (record, who) => {
if (!record) {
return true;
} else {
return who && record && record.length > 0 && record.indexOf(who) > -1;
}
};
// this is a function to permit a uuid within a chatengine channel
let authInChannel = (record, who) => {
// create an empty array if a falsey value is provided
record = record || [];
// this is the kv store key we'll use to look up the record
let key = ['authed', body.chat.channel].join(':');
// if the uuid is not already in the record
if (record.indexOf(who) === -1) {
// add it to the record
record.push(who);
// save the record in the db
return db.set(key, record, 525600).then(() => {
return allow();
}).catch((err) => {
console.error(err);
return serverError('Internal Server Error');
});
} else {
// otherwise, the uuid is already in the record. do not duplicate
return allow();
}
};
// this is the auth policy that runs on every request
let authPolicy = () => {
// run this logic on invite route only
if (route === 'invite') {
// if the chat is not private, don't do anything
if (!body.chat.private) {
return allow();
} else {
// this is the record we'll look up in the kv store to add the invited user into
key = ['authed', body.chat.channel].join(':');
// get the record
return db.get(key).then((record) => {
// check that the current user is already authenticatd in this channel (see /grant below)
if (isAuthed(record, body.uuid)) {
// if this user is authentiated, grant the INVITED USER (body.to)
return authInChannel(record, body.to);
} else {
// if the uuid is not in the record, then return unauthorized
return unauthorized();
}
}).catch((err) => {
// handle errors on record lookup
console.error(err);
return serverError('Internal Server Error');
});
}
// this is when the client requests PAM access to a chat
// if this is the first time a chat is made, the first user to make the chat is authed automatically
} else if (route === 'grant') {
// make sure the chat is set as private before executing logic
if (proxyBody.chat.private) {
// look up the reocrd to see if this use is permitted
let key = ['authed', body.chat.channel].join(':');
return db.get(key).then((record) => {
// isAuthed will return true if the record is empty
// this means the first user to be invited is permitted
if (isAuthed(record, body.uuid)) {
// permit the user
return authInChannel(record, body.uuid);
} else {
return unauthorized();
}
}).catch((err) => {
// handle errors
console.error(err);
return die('Internal Server Error');
});
} else {
return allow();
}
} else {
// all other requests
return allow();
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment