1
0
mirror of https://github.com/Unleash/unleash.git synced 2024-10-23 20:07:40 +02:00
unleash.unleash/src/test/e2e/services/access-service.e2e.test.js
2021-04-23 12:52:29 +02:00

421 lines
14 KiB
JavaScript

const test = require('ava');
const dbInit = require('../helpers/database-init');
const getLogger = require('../../fixtures/no-logger');
// eslint-disable-next-line import/no-unresolved
const {
AccessService,
RoleName,
ALL_PROJECTS,
} = require('../../../lib/services/access-service');
const permissions = require('../../../lib/permissions');
let db;
let stores;
let accessService;
let editorUser;
let superUser;
let editorRole;
let adminRole;
let readRole;
const createUserEditorAccess = async (name, email) => {
const { userStore } = stores;
const user = await userStore.insert({ name, email });
await accessService.addUserToRole(user.id, editorRole.id);
return user;
};
const createSuperUser = async () => {
const { userStore } = stores;
const user = await userStore.insert({
name: 'Alice Admin',
email: 'admin@getunleash.io',
});
await accessService.addUserToRole(user.id, adminRole.id);
return user;
};
test.before(async () => {
db = await dbInit('access_service_serial', getLogger);
stores = db.stores;
// projectStore = stores.projectStore;
accessService = new AccessService(stores, { getLogger });
const roles = await accessService.getRootRoles();
editorRole = roles.find(r => r.name === RoleName.EDITOR);
adminRole = roles.find(r => r.name === RoleName.ADMIN);
readRole = roles.find(r => r.name === RoleName.VIEWER);
editorUser = await createUserEditorAccess('Bob Test', 'bob@getunleash.io');
superUser = await createSuperUser();
});
test.after(async () => {
await db.destroy();
});
test.serial('should have access to admin addons', async t => {
const { CREATE_ADDON, UPDATE_ADDON, DELETE_ADDON } = permissions;
const user = editorUser;
t.true(await accessService.hasPermission(user, CREATE_ADDON));
t.true(await accessService.hasPermission(user, UPDATE_ADDON));
t.true(await accessService.hasPermission(user, DELETE_ADDON));
});
test.serial('should have access to admin strategies', async t => {
const { CREATE_STRATEGY, UPDATE_STRATEGY, DELETE_STRATEGY } = permissions;
const user = editorUser;
t.true(await accessService.hasPermission(user, CREATE_STRATEGY));
t.true(await accessService.hasPermission(user, UPDATE_STRATEGY));
t.true(await accessService.hasPermission(user, DELETE_STRATEGY));
});
test.serial('should have access to admin contexts', async t => {
const {
CREATE_CONTEXT_FIELD,
UPDATE_CONTEXT_FIELD,
DELETE_CONTEXT_FIELD,
} = permissions;
const user = editorUser;
t.true(await accessService.hasPermission(user, CREATE_CONTEXT_FIELD));
t.true(await accessService.hasPermission(user, UPDATE_CONTEXT_FIELD));
t.true(await accessService.hasPermission(user, DELETE_CONTEXT_FIELD));
});
test.serial('should have access to create projects', async t => {
const { CREATE_PROJECT } = permissions;
const user = editorUser;
t.true(await accessService.hasPermission(user, CREATE_PROJECT));
});
test.serial('should have access to update applications', async t => {
const { UPDATE_APPLICATION } = permissions;
const user = editorUser;
t.true(await accessService.hasPermission(user, UPDATE_APPLICATION));
});
test.serial('should not have admin permission', async t => {
const { ADMIN } = permissions;
const user = editorUser;
t.false(await accessService.hasPermission(user, ADMIN));
});
test.serial('should have project admin to default project', async t => {
const {
DELETE_PROJECT,
UPDATE_PROJECT,
CREATE_FEATURE,
UPDATE_FEATURE,
DELETE_FEATURE,
} = permissions;
const user = editorUser;
t.true(await accessService.hasPermission(user, DELETE_PROJECT, 'default'));
t.true(await accessService.hasPermission(user, UPDATE_PROJECT, 'default'));
t.true(await accessService.hasPermission(user, CREATE_FEATURE, 'default'));
t.true(await accessService.hasPermission(user, UPDATE_FEATURE, 'default'));
t.true(await accessService.hasPermission(user, DELETE_FEATURE, 'default'));
});
test.serial('should grant member CREATE_FEATURE on all projects', async t => {
const { CREATE_FEATURE } = permissions;
const user = editorUser;
await accessService.addPermissionToRole(
editorRole.id,
permissions.CREATE_FEATURE,
ALL_PROJECTS,
);
t.true(
await accessService.hasPermission(user, CREATE_FEATURE, 'some-project'),
);
});
test.serial('cannot add CREATE_FEATURE without defining project', async t => {
await t.throwsAsync(
async () => {
await accessService.addPermissionToRole(
editorRole.id,
permissions.CREATE_FEATURE,
);
},
{
instanceOf: Error,
message: 'ProjectId cannot be empty for permission=CREATE_FEATURE',
},
);
});
test.serial(
'cannot remove CREATE_FEATURE without defining project',
async t => {
await t.throwsAsync(
async () => {
await accessService.removePermissionFromRole(
editorRole.id,
permissions.CREATE_FEATURE,
);
},
{
instanceOf: Error,
message:
'ProjectId cannot be empty for permission=CREATE_FEATURE',
},
);
},
);
test.serial('should remove CREATE_FEATURE on all projects', async t => {
const { CREATE_FEATURE } = permissions;
const user = editorUser;
await accessService.addPermissionToRole(
editorRole.id,
permissions.CREATE_FEATURE,
ALL_PROJECTS,
);
await accessService.removePermissionFromRole(
editorRole.id,
permissions.CREATE_FEATURE,
ALL_PROJECTS,
);
t.false(
await accessService.hasPermission(user, CREATE_FEATURE, 'some-project'),
);
});
test.serial('admin should be admin', async t => {
const {
DELETE_PROJECT,
UPDATE_PROJECT,
CREATE_FEATURE,
UPDATE_FEATURE,
DELETE_FEATURE,
ADMIN,
} = permissions;
const user = superUser;
t.true(await accessService.hasPermission(user, DELETE_PROJECT, 'default'));
t.true(await accessService.hasPermission(user, UPDATE_PROJECT, 'default'));
t.true(await accessService.hasPermission(user, CREATE_FEATURE, 'default'));
t.true(await accessService.hasPermission(user, UPDATE_FEATURE, 'default'));
t.true(await accessService.hasPermission(user, DELETE_FEATURE, 'default'));
t.true(await accessService.hasPermission(user, ADMIN));
});
test.serial('should create default roles to project', async t => {
const {
DELETE_PROJECT,
UPDATE_PROJECT,
CREATE_FEATURE,
UPDATE_FEATURE,
DELETE_FEATURE,
} = permissions;
const project = 'some-project';
const user = editorUser;
await accessService.createDefaultProjectRoles(user, project);
t.true(await accessService.hasPermission(user, UPDATE_PROJECT, project));
t.true(await accessService.hasPermission(user, DELETE_PROJECT, project));
t.true(await accessService.hasPermission(user, CREATE_FEATURE, project));
t.true(await accessService.hasPermission(user, UPDATE_FEATURE, project));
t.true(await accessService.hasPermission(user, DELETE_FEATURE, project));
});
test.serial(
'should require name when create default roles to project',
async t => {
await t.throwsAsync(
async () => {
await accessService.createDefaultProjectRoles(editorUser);
},
{ instanceOf: Error, message: 'ProjectId cannot be empty' },
);
},
);
test.serial('should grant user access to project', async t => {
const {
DELETE_PROJECT,
UPDATE_PROJECT,
CREATE_FEATURE,
UPDATE_FEATURE,
DELETE_FEATURE,
} = permissions;
const project = 'another-project';
const user = editorUser;
const sUser = await createUserEditorAccess(
'Some Random',
'random@getunleash.io',
);
await accessService.createDefaultProjectRoles(user, project);
const roles = await accessService.getRolesForProject(project);
const projectRole = roles.find(
r => r.name === 'Member' && r.project === project,
);
await accessService.addUserToRole(sUser.id, projectRole.id);
// Should be able to update feature toggles inside the project
t.true(await accessService.hasPermission(sUser, CREATE_FEATURE, project));
t.true(await accessService.hasPermission(sUser, UPDATE_FEATURE, project));
t.true(await accessService.hasPermission(sUser, DELETE_FEATURE, project));
// Should not be able to admin the project itself.
t.false(await accessService.hasPermission(sUser, UPDATE_PROJECT, project));
t.false(await accessService.hasPermission(sUser, DELETE_PROJECT, project));
});
test.serial('should not get access if not specifying project', async t => {
const { CREATE_FEATURE, UPDATE_FEATURE, DELETE_FEATURE } = permissions;
const project = 'another-project-2';
const user = editorUser;
const sUser = await createUserEditorAccess(
'Some Random',
'random22@getunleash.io',
);
await accessService.createDefaultProjectRoles(user, project);
const roles = await accessService.getRolesForProject(project);
const projectRole = roles.find(
r => r.name === 'Member' && r.project === project,
);
await accessService.addUserToRole(sUser.id, projectRole.id);
// Should not be able to update feature toggles outside project
t.false(await accessService.hasPermission(sUser, CREATE_FEATURE));
t.false(await accessService.hasPermission(sUser, UPDATE_FEATURE));
t.false(await accessService.hasPermission(sUser, DELETE_FEATURE));
});
test.serial('should remove user from role', async t => {
const { userStore } = stores;
const user = await userStore.insert({
name: 'Some User',
email: 'random123@getunleash.io',
});
await accessService.addUserToRole(user.id, editorRole.id);
// check user has one role
const userRoles = await accessService.getRolesForUser(user.id);
t.is(userRoles.length, 1);
t.is(userRoles[0].name, RoleName.EDITOR);
await accessService.removeUserFromRole(user.id, editorRole.id);
const userRolesAfterRemove = await accessService.getRolesForUser(user.id);
t.is(userRolesAfterRemove.length, 0);
});
test.serial('should return role with users', async t => {
const { userStore } = stores;
const user = await userStore.insert({
name: 'Some User',
email: 'random2223@getunleash.io',
});
await accessService.addUserToRole(user.id, editorRole.id);
const roleWithUsers = await accessService.getRole(editorRole.id);
t.is(roleWithUsers.role.name, RoleName.EDITOR);
t.true(roleWithUsers.users.length > 2);
t.truthy(roleWithUsers.users.find(u => u.id === user.id));
t.truthy(roleWithUsers.users.find(u => u.email === user.email));
});
test.serial('should return role with permissions and users', async t => {
const { userStore } = stores;
const user = await userStore.insert({
name: 'Some User',
email: 'random2244@getunleash.io',
});
await accessService.addUserToRole(user.id, editorRole.id);
const roleWithPermission = await accessService.getRole(editorRole.id);
t.is(roleWithPermission.role.name, RoleName.EDITOR);
t.true(roleWithPermission.permissions.length > 2);
t.truthy(
roleWithPermission.permissions.find(
p => p.permission === permissions.CREATE_PROJECT,
),
);
t.true(roleWithPermission.users.length > 2);
});
test.serial('should return list of permissions', async t => {
const p = await accessService.getPermissions();
const findPerm = perm => p.find(_ => _.name === perm);
const {
DELETE_FEATURE,
UPDATE_FEATURE,
CREATE_FEATURE,
UPDATE_PROJECT,
CREATE_PROJECT,
} = permissions;
t.true(p.length > 2);
t.is(findPerm(CREATE_PROJECT).type, 'root');
t.is(findPerm(UPDATE_PROJECT).type, 'project');
t.is(findPerm(CREATE_FEATURE).type, 'project');
t.is(findPerm(UPDATE_FEATURE).type, 'project');
t.is(findPerm(DELETE_FEATURE).type, 'project');
});
test.serial('should set root role for user', async t => {
const { userStore } = stores;
const user = await userStore.insert({
name: 'Some User',
email: 'random2255@getunleash.io',
});
await accessService.setUserRootRole(user.id, editorRole.id);
const roles = await accessService.getRolesForUser(user.id);
t.is(roles.length, 1);
t.is(roles[0].name, RoleName.EDITOR);
});
test.serial('should switch root role for user', async t => {
const { userStore } = stores;
const user = await userStore.insert({
name: 'Some User',
email: 'random22Read@getunleash.io',
});
await accessService.setUserRootRole(user.id, editorRole.id);
await accessService.setUserRootRole(user.id, readRole.id);
const roles = await accessService.getRolesForUser(user.id);
t.is(roles.length, 1);
t.is(roles[0].name, RoleName.VIEWER);
});
test.serial('should not crash if user does not have permission', async t => {
const { userStore } = stores;
const user = await userStore.insert({
name: 'Some User',
email: 'random55Read@getunleash.io',
});
await accessService.setUserRootRole(user.id, readRole.id);
const { UPDATE_CONTEXT_FIELD } = permissions;
const hasAccess = await accessService.hasPermission(
user,
UPDATE_CONTEXT_FIELD,
);
t.false(hasAccess);
});