Skip to content

Commit

Permalink
refactored copilotAndAbove permission "middleware" to use general uti…
Browse files Browse the repository at this point in the history
…l.hasPermission method to check permission instead of reimplementing logic
  • Loading branch information
maxceem committed Jul 17, 2019
1 parent a965c22 commit 5a2070d
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 20 deletions.
36 changes: 36 additions & 0 deletions src/permissions/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* Definitions of permissions which could be used with util methods
* `util.hasPermission` or `util.hasPermissionForProject`.
*
* We can define permission using two logics:
* 1. **WHAT** can be done with such a permission. Such constants may have names like:
* - `VIEW_PROJECT`
* - `EDIT_MILESTONE`
* - `DELETE_WORK`
* and os on.
* 2. **WHO** can do actions with such a permission. Such constants **MUST** start from the prefix `ROLES_`, examples:
* - `ROLES_COPILOT_AND_ABOVE`
* - `ROLES_PROJECT_MEMBERS`
* - `ROLES_ADMINS`
*/
import {
PROJECT_MEMBER_ROLE,
ADMIN_ROLES,
} from '../constants';

export const PERMISSION = { // eslint-disable-line import/prefer-default-export
/**
* Permissions defined by logic: **WHO** can do actions with such a permission.
*/
ROLES_COPILOT_AND_ABOVE: {
topcoderRoles: ADMIN_ROLES,
projectRoles: [
PROJECT_MEMBER_ROLE.MANAGER,
PROJECT_MEMBER_ROLE.COPILOT,
],
},
/**
* Permissions defined by logic: **WHAT** can be done with such a permission.
*/
};

26 changes: 6 additions & 20 deletions src/permissions/copilotAndAbove.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
import _ from 'lodash';
import util from '../util';
import {
PROJECT_MEMBER_ROLE,
ADMIN_ROLES,
} from '../constants';
import models from '../models';

import { PERMISSION } from './constants';

/**
* Permission to allow copilot and above roles to perform certain operations
Expand All @@ -16,27 +12,17 @@ import models from '../models';
*/
module.exports = req => new Promise((resolve, reject) => {
const projectId = _.parseInt(req.params.projectId);
const isAdmin = util.hasRoles(req, ADMIN_ROLES);

if (isAdmin) {
return resolve(true);
}

return models.ProjectMember.getActiveProjectMembers(projectId)
.then((members) => {
const hasPermission = util.hasPermission(PERMISSION.ROLES_COPILOT_AND_ABOVE, req.authUser, members);

// TODO should we really do this?
// if no, we can replace `getActiveProjectMembers + util.hasPermission` with one `util.hasPermissionForProject`
req.context = req.context || {};
req.context.currentProjectMembers = members;
const validMemberProjectRoles = [
PROJECT_MEMBER_ROLE.MANAGER,
PROJECT_MEMBER_ROLE.COPILOT,
];
// check if the copilot or manager has access to this project
const isMember = _.some(
members,
m => m.userId === req.authUser.userId && validMemberProjectRoles.includes(m.role),
);

if (!isMember) {
if (!hasPermission) {
// the copilot or manager is not a registered project member
return reject(new Error('You do not have permissions to perform this action'));
}
Expand Down

0 comments on commit 5a2070d

Please sign in to comment.