UNPKG

atlassian-connect-express

Version:

Library for building Atlassian Add-ons on top of Express

132 lines (117 loc) 3.11 kB
const _ = require("lodash"); function getGrants( httpClient, accountId, globalPermissions, projectPermissions ) { return new Promise((resolve, reject) => httpClient.post( { url: "/rest/api/3/permissions/check", headers: { "X-Atlassian-Token": "nocheck" }, // don't authenticate the request if there's no user ID associated // this allows anonymous users to have their permissions looked up anonymous: !accountId, json: { globalPermissions, projectPermissions, accountId } }, (err, httpResponse, body) => { if (err) { reject(err); return; } if (body.errors) { reject(body.errors); return; } if (body.errorMessages) { reject(body.errorMessages); return; } resolve({ projectPermissions: body.projectPermissions || [], globalPermissions: body.globalPermissions || [] }); } ) ); } // Normalizes the given array such that all elements are strings, and in sorting order. This is useful for comparing project/issue ids consistently. function normalize(a) { return _.sortBy(_.map(a, item => item.toString())); } function checkProjectGrantsSatisfy(projectGrants, requiredProjectPermissions) { // every permission must be matched at least once with matching project IDs + issue IDs for (const projectPermission of requiredProjectPermissions) { let satisifed = false; const projectIds = normalize(projectPermission.projects); const issueIds = normalize(projectPermission.issues); for (const permissionName of projectPermission.permissions) { for (const grantedProjectPermission of projectGrants) { if ( permissionName === grantedProjectPermission.permission && _.isEqual(projectIds, normalize(grantedProjectPermission.projects)) && _.isEqual(issueIds, normalize(grantedProjectPermission.issues)) ) { satisifed = true; break; } } if (!satisifed) { return false; } } } return true; } function checkGrantsSatisify( grants, requiredGlobalPermissions, requiredProjectPermissions ) { // If an invalid permission is requested checking for equality will ensure no match is made if ( !_.isEqual( _.sortBy(grants.globalPermissions), _.sortBy(requiredGlobalPermissions) ) ) { return false; } if ( !checkProjectGrantsSatisfy( grants.projectPermissions, requiredProjectPermissions ) ) { return false; } return true; } /** * Determins if the given account satisfies the requested permissions */ function isAuthorized( httpClient, accountId, globalPermissions, projectPermissions ) { return getGrants( httpClient, accountId, globalPermissions, projectPermissions ).then(grants => checkGrantsSatisify(grants, globalPermissions, projectPermissions) ); } module.exports = { isAuthorized };