@tipe/roles
Advanced tools
Comparing version 0.2.0 to 0.3.0
{ | ||
"name": "@tipe/roles", | ||
"version": "0.2.0", | ||
"version": "0.3.0", | ||
"description": "", | ||
@@ -8,3 +8,6 @@ "main": "src/index.js", | ||
"test": "jest", | ||
"prepublishOnly": "npm run test" | ||
"prepublishOnly": "npm run test", | ||
"version": "git add .", | ||
"preversion": "npm test", | ||
"postversion": "git push && git push --tags" | ||
}, | ||
@@ -11,0 +14,0 @@ "repository": { |
@@ -1,1 +0,11 @@ | ||
module.exports = require('./roles') | ||
const { policies } = require('./policies') | ||
const { roles } = require('./roles') | ||
const { actions } = require('./actions') | ||
const { isAllowed } = require('./checks') | ||
module.exports = { | ||
isAllowed, | ||
actions, | ||
roles, | ||
policies | ||
} |
328
src/roles.js
@@ -1,319 +0,29 @@ | ||
exports.policies = ['Org', 'Project', 'Model', 'Content'] | ||
.reduce((result, type) => { | ||
const actions = { | ||
'create': `Create${type}`, | ||
'read': `Read${type}`, | ||
'update': `Update${type}`, | ||
'delete': `Delete${type}` | ||
} | ||
if (type === 'Content') { | ||
actions['publish'] = `Publish${type}` | ||
} | ||
if (type === 'Org') { | ||
actions['subscription'] = `Subscription${type}` | ||
actions['invite'] = `Invite${type}` | ||
} | ||
result[type] = { type, actions } | ||
return result | ||
}, {}) | ||
exports.allPolicies = { | ||
'Org_create': exports.policies.Org.actions['create'], | ||
'Org_read': exports.policies.Org.actions['read'], | ||
'Org_update': exports.policies.Org.actions['update'], | ||
get Org_write() { | ||
console.log('Org_write was changed to Org_update') | ||
return exports.policies.Org.actions['update'] | ||
}, | ||
'Org_delete': exports.policies.Org.actions['delete'], | ||
'Org_subscription': exports.policies.Org.actions['subscription'], | ||
'Org_invites': exports.policies.Org.actions['invites'], | ||
'Project_create': exports.policies.Project.actions['create'], | ||
'Project_read': exports.policies.Project.actions['read'], | ||
'Project_update': exports.policies.Project.actions['update'], | ||
get Project_write() { | ||
console.log('Project_write was changed to Project_update') | ||
return exports.policies.Project.actions['update'] | ||
}, | ||
'Project_delete': exports.policies.Project.actions['delete'], | ||
'Model_create': exports.policies.Model.actions['create'], | ||
'Model_read': exports.policies.Model.actions['read'], | ||
'Model_update': exports.policies.Model.actions['update'], | ||
get Model_write() { | ||
console.log('Model_write was changed Model_update') | ||
return exports.policies.Model.actions['update'] | ||
}, | ||
'Model_delete': exports.policies.Model.actions['delete'], | ||
'Content_create': exports.policies.Content.actions['create'], | ||
'Content_read': exports.policies.Content.actions['read'], | ||
'Content_update': exports.policies.Content.actions['update'], | ||
get Content_write() { | ||
console.log('Content_write was changed to Content_update') | ||
return exports.policies.Content.actions['update'] | ||
}, | ||
'Content_delete': exports.policies.Content.actions['delete'], | ||
'Content_publish': exports.policies.Content.actions['publish'] | ||
const projectRoles = { | ||
PM: 'PM', | ||
Developer: 'Developer', | ||
Collaborator: 'Collaborator', | ||
Editor: 'Editor' | ||
} | ||
exports.roles = { | ||
const orgRoles = { | ||
Admin: 'Admin', | ||
Owner: 'Owner', | ||
Admin: 'Admin', | ||
PM: 'PM', | ||
Creator: 'Creator', | ||
Member: 'Member', | ||
Editor: 'Editor' | ||
} | ||
exports.roleToPolicies = function roleToPolicies(role) { | ||
if (typeof role !== 'string') { | ||
throw new Error('roleToPolicies ' + role + ' needs to be type string') | ||
} | ||
switch (role) { | ||
case exports.roles.Owner: return exports.owner().policies | ||
case exports.roles.Admin: return exports.admin().policies | ||
case exports.roles.PM: return exports.pm().policies | ||
case exports.roles.Creator: return exports.creator().policies | ||
case exports.roles.Member: return exports.member().policies | ||
case exports.roles.Editor: return exports.editor().policies | ||
default: return [] | ||
} | ||
} | ||
const allRoles = [ | ||
...Object.keys(projectRoles) | ||
.map(k => projectRoles[k]), | ||
...Object.keys(orgRoles) | ||
.map(k => orgRoles[k]) | ||
] | ||
exports.owner = function owner() { | ||
return { | ||
name: exports.roles.Owner, | ||
policies: [ | ||
exports.policies.Org.actions['create'], | ||
exports.policies.Org.actions['read'], | ||
exports.policies.Org.actions['update'], | ||
exports.policies.Org.actions['delete'], | ||
exports.policies.Org.actions['subscription'], | ||
exports.policies.Org.actions['invites'], | ||
const allRolesMap = Object.assign({}, projectRoles, orgRoles) | ||
exports.policies.Project.actions['create'], | ||
exports.policies.Project.actions['read'], | ||
exports.policies.Project.actions['update'], | ||
exports.policies.Project.actions['delete'], | ||
exports.policies.Model.actions['create'], | ||
exports.policies.Model.actions['read'], | ||
exports.policies.Model.actions['update'], | ||
exports.policies.Model.actions['delete'], | ||
exports.policies.Content.actions['create'], | ||
exports.policies.Content.actions['read'], | ||
exports.policies.Content.actions['update'], | ||
exports.policies.Content.actions['delete'], | ||
exports.policies.Content.actions['publish'] | ||
] | ||
} | ||
module.exports = { | ||
orgRoles, | ||
projectRoles, | ||
roles: allRoles, | ||
rolesMap: allRolesMap | ||
} | ||
exports.admin = function admin() { | ||
return { | ||
name: exports.roles.Admin, | ||
policies: [ | ||
// exports.policies.Org.actions['create'], | ||
exports.policies.Org.actions['read'], | ||
exports.policies.Org.actions['update'], | ||
// exports.policies.Org.actions['delete'], | ||
// exports.policies.Org.actions['subscription'], | ||
// exports.policies.Org.actions['invites'], | ||
exports.policies.Project.actions['create'], | ||
exports.policies.Project.actions['read'], | ||
exports.policies.Project.actions['update'], | ||
exports.policies.Project.actions['delete'], | ||
exports.policies.Model.actions['create'], | ||
exports.policies.Model.actions['read'], | ||
exports.policies.Model.actions['update'], | ||
exports.policies.Model.actions['delete'], | ||
exports.policies.Content.actions['create'], | ||
exports.policies.Content.actions['read'], | ||
exports.policies.Content.actions['update'], | ||
exports.policies.Content.actions['delete'], | ||
exports.policies.Content.actions['publish'] | ||
] | ||
} | ||
} | ||
exports.pm = function pm() { | ||
return { | ||
name: exports.roles.PM, | ||
policies: [ | ||
// exports.policies.Org.actions['create'], | ||
exports.policies.Org.actions['read'], | ||
// exports.policies.Org.actions['update'], | ||
// exports.policies.Org.actions['delete'], | ||
// exports.policies.Org.actions['subscription'], | ||
// exports.policies.Org.actions['invites'], | ||
exports.policies.Project.actions['create'], | ||
exports.policies.Project.actions['read'], | ||
exports.policies.Project.actions['update'], | ||
exports.policies.Project.actions['delete'], | ||
exports.policies.Model.actions['create'], | ||
exports.policies.Model.actions['read'], | ||
exports.policies.Model.actions['update'], | ||
exports.policies.Model.actions['delete'], | ||
exports.policies.Content.actions['create'], | ||
exports.policies.Content.actions['read'], | ||
exports.policies.Content.actions['update'], | ||
exports.policies.Content.actions['delete'], | ||
exports.policies.Content.actions['publish'] | ||
] | ||
} | ||
} | ||
exports.creator = function creator() { | ||
return { | ||
name: exports.roles.Creator, | ||
policies: [ | ||
// exports.policies.Org.actions['create'], | ||
exports.policies.Org.actions['read'], | ||
// exports.policies.Org.actions['update'], | ||
// exports.policies.Org.actions['delete'], | ||
// exports.policies.Org.actions['subscription'], | ||
// exports.policies.Org.actions['invites'], | ||
// exports.policies.Project.actions['create'], | ||
exports.policies.Project.actions['read'], | ||
// exports.policies.Project.actions['update'], | ||
// exports.policies.Project.actions['delete'], | ||
// exports.policies.Model.actions['create'], | ||
exports.policies.Model.actions['read'], | ||
// exports.policies.Model.actions['update'], | ||
// exports.policies.Model.actions['delete'], | ||
exports.policies.Content.actions['create'], | ||
exports.policies.Content.actions['read'], | ||
exports.policies.Content.actions['update'] | ||
// exports.policies.Content.actions['delete'], | ||
// exports.policies.Content.actions['publish'], | ||
] | ||
} | ||
} | ||
exports.member = function member() { | ||
return { | ||
name: exports.roles.Member, | ||
policies: [ | ||
// exports.policies.Org.actions['create'], | ||
exports.policies.Org.actions['read'], | ||
// exports.policies.Org.actions['update'], | ||
// exports.policies.Org.actions['delete'], | ||
// exports.policies.Org.actions['subscription'], | ||
// exports.policies.Org.actions['invites'], | ||
// exports.policies.Project.actions['create'], | ||
exports.policies.Project.actions['read'], | ||
// exports.policies.Project.actions['update'], | ||
// exports.policies.Project.actions['delete'], | ||
// exports.policies.Model.actions['create'], | ||
exports.policies.Model.actions['read'], | ||
// exports.policies.Model.actions['update'], | ||
// exports.policies.Model.actions['delete'], | ||
// exports.policies.Content.actions['create'], | ||
exports.policies.Content.actions['read'] | ||
// exports.policies.Content.actions['update'], | ||
// exports.policies.Content.actions['delete'], | ||
// exports.policies.Content.actions['publish'], | ||
] | ||
} | ||
} | ||
exports.editor = function editor() { | ||
return { | ||
name: exports.roles.Editor, | ||
policies: [ | ||
// exports.policies.Org.actions['create'], | ||
exports.policies.Org.actions['read'], | ||
// exports.policies.Org.actions['update'], | ||
// exports.policies.Org.actions['delete'], | ||
// exports.policies.Org.actions['subscription'], | ||
// exports.policies.Org.actions['invites'], | ||
// exports.policies.Project.actions['create'], | ||
exports.policies.Project.actions['read'], | ||
// exports.policies.Project.actions['update'], | ||
// exports.policies.Project.actions['delete'], | ||
// exports.policies.Model.actions['create'], | ||
exports.policies.Model.actions['read'], | ||
// exports.policies.Model.actions['update'], | ||
// exports.policies.Model.actions['delete'], | ||
exports.policies.Content.actions['create'], | ||
exports.policies.Content.actions['read'], | ||
exports.policies.Content.actions['update'], | ||
exports.policies.Content.actions['delete'], | ||
exports.policies.Content.actions['publish'] | ||
] | ||
} | ||
} | ||
exports.isAllowed = function isAllowed(policy, id, type, roles) { | ||
// list of all policies in project plus org | ||
return exports.getRoles(id, type, roles).indexOf(policy) !== -1 | ||
} | ||
exports.getRoles = function getRoles(id, type, roles) { | ||
if (type === 'ORG_ROLE') { | ||
const orgRole = roles.find(function (role) { | ||
return role.org.toString() === id.toString() | ||
}) | ||
if (!orgRole) { | ||
return [] | ||
} | ||
// refactor roles to role | ||
const _orgRoles = orgRole.role || orgRole.roles | ||
const combinedRoles = [].concat( | ||
exports.roleToPolicies(_orgRoles) | ||
) | ||
return combinedRoles | ||
} | ||
const orgs = {} | ||
const projectRole = roles | ||
.filter(function(role) { | ||
if (role.type === 'ORG_ROLE') { | ||
// refactor roles to role | ||
orgs[role.org] = role.role || role.roles | ||
} | ||
return role.type === 'PROJECT_ROLE' | ||
}) | ||
.find(function(role) { | ||
return role.project.toString() === id.toString() | ||
}) | ||
if (!projectRole) { | ||
return [] | ||
} | ||
// refactor roles to role | ||
const _orgRoles = orgs[projectRole.org] || '' | ||
const _projectRoles = projectRole.role || projectRole.roles | ||
const combinedRoles = [].concat( | ||
exports.roleToPolicies(_orgRoles), | ||
exports.roleToPolicies(_projectRoles) | ||
) | ||
return combinedRoles | ||
} |
@@ -1,57 +0,129 @@ | ||
const ROLES = require('./roles'); | ||
const { orgRoles, projectRoles, roles, rolesMap } = require('./roles') | ||
const { policies, setPolicies } = require('./policies') | ||
const { isAllowed } = require('./checks') | ||
describe('roles', () => { | ||
test('has correct project roles', () => { | ||
expect(projectRoles) | ||
.toEqual({ | ||
PM: 'PM', | ||
Developer: 'Developer', | ||
Collaborator: 'Collaborator', | ||
Editor: 'Editor' | ||
}) | ||
}) | ||
const ORG_ID = '78998789' | ||
const PROJECT_ID = '898098896' | ||
test('has correct org roles', () => { | ||
expect(orgRoles) | ||
.toEqual({ | ||
Admin: 'Admin', | ||
Owner: 'Owner', | ||
Member: 'Member', | ||
}) | ||
}) | ||
test('isAllowed', function() { | ||
const allowed = ROLES.isAllowed( | ||
'CreateContent', | ||
ORG_ID, | ||
'ORG_ROLE', | ||
[ | ||
{ | ||
type: 'ORG_ROLE', | ||
project: PROJECT_ID, | ||
org: ORG_ID, | ||
roles: 'Admin' | ||
} | ||
] | ||
) | ||
test('has all roles', () => { | ||
expect(roles) | ||
.toEqual([ | ||
'PM', | ||
'Developer', | ||
'Collaborator', | ||
'Editor', | ||
'Admin', | ||
'Owner', | ||
'Member', | ||
]) | ||
}) | ||
expect(allowed).toBe(true); | ||
}); | ||
test('merges all roles', () => { | ||
expect(rolesMap) | ||
.toEqual({ | ||
PM: 'PM', | ||
Developer: 'Developer', | ||
Collaborator: 'Collaborator', | ||
Editor: 'Editor', | ||
Admin: 'Admin', | ||
Owner: 'Owner', | ||
Member: 'Member' | ||
}) | ||
}) | ||
}) | ||
test('getRoles ORG_ROLE', function() { | ||
const roles = ROLES.getRoles( | ||
ORG_ID, | ||
'ORG_ROLE', | ||
[ | ||
{ | ||
type: 'ORG_ROLE', | ||
project: PROJECT_ID, | ||
org: ORG_ID, | ||
roles: 'Admin' | ||
} | ||
] | ||
) | ||
describe('policies', () => { | ||
test('created policies for all resources', () => { | ||
expect(policies).toHaveProperty('Org') | ||
expect(policies).toHaveProperty('Project') | ||
expect(policies).toHaveProperty('Model') | ||
expect(policies).toHaveProperty('Content') | ||
}) | ||
test('created org policies', () => { | ||
expect(policies.Org.actions).toHaveProperty('create') | ||
expect(policies.Org.actions).toHaveProperty('read') | ||
expect(policies.Org.actions).toHaveProperty('update') | ||
expect(policies.Org.actions).toHaveProperty('delete') | ||
expect(policies.Org.actions).toHaveProperty('subscription') | ||
expect(policies.Org.actions).toHaveProperty('removeUser') | ||
expect(policies.Org.actions).toHaveProperty('invite') | ||
expect(policies.Org.actions).not.toHaveProperty('publish') | ||
}) | ||
test('created project policies', () => { | ||
expect(policies.Project.actions).toHaveProperty('create') | ||
expect(policies.Project.actions).toHaveProperty('read') | ||
expect(policies.Project.actions).toHaveProperty('update') | ||
expect(policies.Project.actions).toHaveProperty('delete') | ||
expect(policies.Project.actions).toHaveProperty('removeUser') | ||
expect(policies.Project.actions).toHaveProperty('invite') | ||
expect(policies.Project.actions).not.toHaveProperty('subsciption') | ||
expect(policies.Project.actions).not.toHaveProperty('publish') | ||
}) | ||
test('created Model policies', () => { | ||
expect(policies.Model.actions).toHaveProperty('create') | ||
expect(policies.Model.actions).toHaveProperty('read') | ||
expect(policies.Model.actions).toHaveProperty('update') | ||
expect(policies.Model.actions).toHaveProperty('delete') | ||
expect(policies.Model.actions).not.toHaveProperty('invite') | ||
expect(policies.Model.actions).not.toHaveProperty('subsciption') | ||
expect(policies.Model.actions).not.toHaveProperty('publish') | ||
}) | ||
test('created Content policies', () => { | ||
expect(policies.Content.actions).toHaveProperty('create') | ||
expect(policies.Content.actions).toHaveProperty('read') | ||
expect(policies.Content.actions).toHaveProperty('update') | ||
expect(policies.Content.actions).toHaveProperty('delete') | ||
expect(policies.Content.actions).toHaveProperty('publish') | ||
expect(policies.Content.actions).not.toHaveProperty('invite') | ||
expect(policies.Content.actions).not.toHaveProperty('subsciption') | ||
}) | ||
expect(roles).toEqual(ROLES.admin().policies); | ||
}); | ||
test('gets policies for actions and resource', () => { | ||
let policies = setPolicies('Org', ['create', 'read']) | ||
expect(policies).toEqual(['CreateOrg', 'ReadOrg']) | ||
test('getRoles PROJECT_ROLE', function() { | ||
const roles = ROLES.getRoles( | ||
PROJECT_ID, | ||
'PROJECT_ROLE', | ||
[ | ||
{ | ||
type: 'PROJECT_ROLE', | ||
project: PROJECT_ID, | ||
org: ORG_ID, | ||
roles: 'Admin' | ||
} | ||
] | ||
) | ||
policies = setPolicies('Model', ['invite', 'create']) | ||
expect(policies.length).toBe(1) | ||
}) | ||
}) | ||
expect(roles).toEqual(ROLES.admin().policies); | ||
}); | ||
describe('isAllowed', () => { | ||
test('throws error if no matching action', () => { | ||
expect(() => isAllowed('fakeaction', 'member')) | ||
.toThrow() | ||
}) | ||
test('grants access', () => { | ||
expect(isAllowed('content:create', 'Developer')) | ||
.toBe(true) | ||
}) | ||
test('denies access', () => { | ||
expect(isAllowed('org:delete', 'Developer')) | ||
.toBe(false) | ||
}) | ||
}) |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
97019
10
355
2