UNPKG

openhim-core

Version:

The OpenHIM core application that provides logging and routing of http requests

508 lines (491 loc) 13.1 kB
var Channel, Client, authorisation, buildFindChannelByIdOrNameCriteria, buildFindClientByIdOrClientIDCriteria, filterRolesFromChannels, logger, utils; Channel = require('../model/channels').Channel; Client = require('../model/clients').Client; logger = require('winston'); authorisation = require('./authorisation'); utils = require('../utils'); /* * Roles is a virtual API; virtual in the sense that it is not linked * to a concrete roles collection. * * Rather it an abstraction of the 'allow' field on Channels and 'roles' on Clients, * providing a mechanism for setting up allowed permissions. */ filterRolesFromChannels = function(channels, clients) { var ch, cl, i, isClient, j, k, l, len, len1, len2, len3, len4, m, permission, ref, ref1, role, rolesArray, rolesMap; rolesMap = {}; for (i = 0, len = channels.length; i < len; i++) { ch = channels[i]; ref = ch.allow; for (j = 0, len1 = ref.length; j < len1; j++) { permission = ref[j]; isClient = false; for (k = 0, len2 = clients.length; k < len2; k++) { cl = clients[k]; if (cl.clientID === permission) { isClient = true; } } if (!isClient) { if (!rolesMap[permission]) { rolesMap[permission] = { channels: [], clients: [] }; } rolesMap[permission].channels.push({ _id: ch._id, name: ch.name }); } } } for (l = 0, len3 = clients.length; l < len3; l++) { cl = clients[l]; ref1 = cl.roles; for (m = 0, len4 = ref1.length; m < len4; m++) { permission = ref1[m]; if (!rolesMap[permission]) { rolesMap[permission] = { channels: [], clients: [] }; } rolesMap[permission].clients.push({ _id: cl._id, clientID: cl.clientID }); } } rolesArray = []; for (role in rolesMap) { rolesArray.push({ name: role, channels: rolesMap[role].channels, clients: rolesMap[role].clients }); } return rolesArray; }; exports.getRoles = function*() { var channels, clients, e, error; if (!authorisation.inGroup('admin', this.authenticated)) { return utils.logAndSetResponse(this, 403, "User " + this.authenticated.email + " is not an admin, API access to getRoles denied.", 'info'); } try { channels = (yield Channel.find({}, { name: 1, allow: 1 }).exec()); clients = (yield Client.find({}, { clientID: 1, roles: 1 }).exec()); return this.body = filterRolesFromChannels(channels, clients); } catch (error) { e = error; logger.error("Could not fetch roles via the API: " + e.message); this.message = e.message; return this.status = 500; } }; exports.getRole = function*(name) { var channels, clients, e, error; if (!authorisation.inGroup('admin', this.authenticated)) { return utils.logAndSetResponse(this, 403, "User " + this.authenticated.email + " is not an admin, API access to getRole denied.", 'info'); } try { channels = (yield Channel.find({ allow: { $in: [name] } }, { name: 1 }).exec()); clients = (yield Client.find({ roles: { $in: [name] } }, { clientID: 1 }).exec()); if ((channels === null || channels.length === 0) && (clients === null || clients.length === 0)) { return utils.logAndSetResponse(this, 404, "Role with name '" + name + "' could not be found.", 'info'); } else { return this.body = { name: name, channels: channels.map(function(r) { return { _id: r._id, name: r.name }; }), clients: clients.map(function(c) { return { _id: c._id, clientID: c.clientID }; }) }; } } catch (error) { e = error; logger.error("Could not find role with name '" + name + "' via the API: " + e.message); this.body = e.message; return this.status = 500; } }; buildFindChannelByIdOrNameCriteria = function(ctx, role) { var ch, criteria, i, ids, len, names, ref; criteria = {}; ids = []; names = []; ref = role.channels; for (i = 0, len = ref.length; i < len; i++) { ch = ref[i]; if (ch._id) { ids.push(ch._id); } else if (ch.name) { names.push(ch.name); } else { utils.logAndSetResponse(ctx, 400, "_id and/or name must be specified for a channel", 'info'); return null; } } if (ids.length > 0 && names.length > 0) { criteria = { $or: [ { _id: { $in: ids } }, { name: { $in: names } } ] }; } else { if (ids.length > 0) { criteria._id = { $in: ids }; } if (names.length > 0) { criteria.name = { $in: names }; } } return criteria; }; buildFindClientByIdOrClientIDCriteria = function(ctx, role) { var ch, clientIDs, criteria, i, ids, len, ref; criteria = {}; ids = []; clientIDs = []; ref = role.clients; for (i = 0, len = ref.length; i < len; i++) { ch = ref[i]; if (ch._id) { ids.push(ch._id); } else if (ch.clientID) { clientIDs.push(ch.clientID); } else { utils.logAndSetResponse(ctx, 400, "_id and/or clientID must be specified for a client", 'info'); return null; } } if (ids.length > 0 && clientIDs.length > 0) { criteria = { $or: [ { _id: { $in: ids } }, { clientID: { $in: clientIDs } } ] }; } else { if (ids.length > 0) { criteria._id = { $in: ids }; } if (clientIDs.length > 0) { criteria.clientID = { $in: clientIDs }; } } return criteria; }; exports.addRole = function*() { var chCriteria, chResult, clCriteria, clResult, e, error, ref, ref1, role; if (!authorisation.inGroup('admin', this.authenticated)) { return utils.logAndSetResponse(this, 403, "User " + this.authenticated.email + " is not an admin, API access to addRole denied.", 'info'); } role = this.request.body; if (!role.name) { return utils.logAndSetResponse(this, 400, 'Must specify a role name', 'info'); } if (((ref = role.channels) != null ? ref.length : void 0) === 0 && ((ref1 = role.clients) != null ? ref1.length : void 0) === 0) { return utils.logAndSetResponse(this, 400, 'Must specify at least one channel or client to link the role to', 'info'); } try { chResult = (yield Channel.find({ allow: { $in: [role.name] } }, { name: 1 }).exec()); clResult = (yield Client.find({ roles: { $in: [role.name] } }, { clientID: 1 }).exec()); if ((chResult != null ? chResult.length : void 0) > 0 || (typeof clResults !== "undefined" && clResults !== null ? clResults.length : void 0) > 0) { return utils.logAndSetResponse(this, 400, "Role with name '" + role.name + "' already exists.", 'info'); } if (role.channels) { chCriteria = buildFindChannelByIdOrNameCriteria(this, role); if (!chCriteria) { return; } } if (role.clients) { clCriteria = buildFindClientByIdOrClientIDCriteria(this, role); if (!clCriteria) { return; } } if (role.channels) { (yield Channel.update(chCriteria, { $push: { allow: role.name } }, { multi: true }).exec()); } if (role.clients) { (yield Client.update(clCriteria, { $push: { roles: role.name } }, { multi: true }).exec()); } logger.info("User " + this.authenticated.email + " setup role '" + role.name + "'"); this.body = 'Role successfully created'; return this.status = 201; } catch (error) { e = error; logger.error("Could not add a role via the API: " + e.message); this.body = e.message; return this.status = 400; } }; exports.updateRole = function*(name) { var chCriteria, chResult, channels, clCriteria, clResult, clients, e, error, ref, role; if (!authorisation.inGroup('admin', this.authenticated)) { return utils.logAndSetResponse(this, 403, "User " + this.authenticated.email + " is not an admin, API access to updateRole denied.", 'info'); } role = this.request.body; try { chResult = (yield Channel.find({ allow: { $in: [name] } }, { name: 1 }).exec()); clResult = (yield Client.find({ roles: { $in: [name] } }, { clientID: 1 }).exec()); if ((chResult === null || chResult.length === 0) && (clResult === null || clResult.length === 0)) { return utils.logAndSetResponse(this, 404, "Role with name '" + name + "' could not be found.", 'info'); } if (role.name) { channels = (yield Channel.find({ allow: { $in: [role.name] } }, { name: 1 }).exec()); clients = (yield Client.find({ roles: { $in: [role.name] } }, { name: 1 }).exec()); if ((channels != null ? channels.length : void 0) > 0 || (clients != null ? clients.length : void 0) > 0) { return utils.logAndSetResponse(this, 400, "Role with name '" + role.name + "' already exists.", 'info'); } } if (role.channels) { chCriteria = buildFindChannelByIdOrNameCriteria(this, role); if (!chCriteria) { return; } } if (role.clients) { clCriteria = buildFindClientByIdOrClientIDCriteria(this, role); if (!clCriteria) { return; } } if (role.channels) { (yield Channel.update({}, { $pull: { allow: name } }, { multi: true }).exec()); if (role.channels.length > 0) { (yield Channel.update(chCriteria, { $push: { allow: name } }, { multi: true }).exec()); } } if (role.clients) { (yield Client.update({}, { $pull: { roles: name } }, { multi: true }).exec()); if (((ref = role.clients) != null ? ref.length : void 0) > 0) { (yield Client.update(clCriteria, { $push: { roles: name } }, { multi: true }).exec()); } } if (role.name) { (yield Channel.update({ allow: { $in: [name] } }, { $push: { allow: role.name } }, { multi: true }).exec()); (yield Channel.update({ allow: { $in: [name] } }, { $pull: { allow: name } }, { multi: true }).exec()); (yield Client.update({ roles: { $in: [name] } }, { $push: { roles: role.name } }, { multi: true }).exec()); (yield Client.update({ roles: { $in: [name] } }, { $pull: { roles: name } }, { multi: true }).exec()); } logger.info("User " + this.authenticated.email + " updated role with name '" + name + "'"); this.body = 'Successfully updated role'; return this.status = 200; } catch (error) { e = error; logger.error("Could not update role with name '" + name + "' via the API: " + e.message); this.body = e.message; return this.status = 500; } }; exports.deleteRole = function*(name) { var channels, clients, e, error; if (!authorisation.inGroup('admin', this.authenticated)) { return utils.logAndSetResponse(this, 403, "User " + this.authenticated.email + " is not an admin, API access to updateRole denied.", 'info'); } try { channels = (yield Channel.find({ allow: { $in: [name] } }, { name: 1 }).exec()); clients = (yield Client.find({ roles: { $in: [name] } }, { clientID: 1 }).exec()); if ((channels === null || channels.length === 0) && (clients === null || clients.length === 0)) { return utils.logAndSetResponse(this, 404, "Role with name '" + name + "' could not be found.", 'info'); } (yield Channel.update({}, { $pull: { allow: name } }, { multi: true }).exec()); (yield Client.update({}, { $pull: { roles: name } }, { multi: true }).exec()); logger.info("User " + this.authenticated.email + " deleted role with name '" + name + "'"); return this.body = 'Successfully deleted role'; } catch (error) { e = error; logger.error("Could not update role with name '" + name + "' via the API: " + e.message); this.body = e.message; return this.status = 500; } }; //# sourceMappingURL=roles.js.map