1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-01-06 00:07:44 +01:00
unleash.unleash/src/test/e2e/api/admin/user-admin.e2e.test.ts

337 lines
10 KiB
TypeScript
Raw Normal View History

import { setupApp, setupAppWithCustomConfig } from '../../helpers/test-helper';
import dbInit from '../../helpers/database-init';
import getLogger from '../../../fixtures/no-logger';
2021-04-29 10:21:29 +02:00
import {
USER_CREATED,
USER_DELETED,
USER_UPDATED,
} from '../../../../lib/types/events';
feat: custom project roles (#1220) * wip: environment for permissions * fix: add migration for roles * fix: connect environment with access service * feat: add tests * chore: Implement scaffolding for new rbac * fix: add fake store * feat: Add api endpoints for roles and permissions list * feat: Add ability to provide permissions when creating a role and rename environmentName to name in the list permissions datastructure * fix: Make project roles resolve correctly against new environments permissions structure * fix: Patch migration to also populate permission names * fix: Make permissions actually work with new environments * fix: Add back to get permissions working for editor role * fix: Removed ability to set role type through api during creation - it's now always custom * feat: Return permissions on get role endpoint * feat: Add in support for updating roles * fix: Get a bunch of tests working and delete a few that make no sense anymore * chore: A few small cleanups - remove logging and restore default on dev server config * chore: Refactor role/access stores into more logical domains * feat: Add in validation for roles * feat: Patch db migration to handle old stucture * fix: migration for project roles * fix: patch a few broken tests * fix: add permissions to editor * fix: update test name * fix: update user permission mapping * fix: create new user * fix: update root role test * fix: update tests * feat: Validation now works when updating a role * fix: Add in very barebones down migration for rbac so that tests work * fix: Improve responses from role resolution - getting a non existant role will throw a NotFound error * fix: remove unused permissions * fix: add test for connecting roles and deleting project * fix: add test for adding a project member with a custom role * fix: add test for changing user role * fix: add guard for deleting role if the role is in use * fix: alter migration * chore: Minor code cleanups * chore: Small code cleanups * chore: More minor cleanups of code * chore: Trim some dead code to make the linter happy * feat: Schema validation for roles * fix: setup permission for variant * fix: remove unused import * feat: Add cascading delete for role_permissions when deleting a role * feat: add configuration option for disabling legacy api * chore: update frontend to beta version * 4.6.0-beta.0 * fix: export default project constant * fix: update snapshot * fix: module pattern ../../lib * fix: move DEFAULT_PROJECT to types * fix: remove debug logging * fix: remove debug log state * fix: Change permission descriptions * fix: roles should have unique name * fix: root roles should be connected to the default project * fix: typo in role-schema.ts * fix: Role permission empty string for non environment type * feat: new permission for moving project * fix: add event for changeProject * fix: Removing a user from a project will now check to see if that project has an owner, rather than checking if any project has an owner * fix: add tests for move project * fix: Add in missing create/delete tag permissions * fix: Removed duplicate impl caused by multiple good samaritans putting it back in! * fix: Trim out add tag permissions, for now at least * chore: Trim out new add and delete tag permissions - we're going with update feature instead * chore: update frontend * 4.6.0-beta.1 * feat: Prevent editing of built in roles * fix: Patch an issue where permissions for variants/environments didn't match the front end * fix: lint Co-authored-by: Ivar Conradi Østhus <ivarconr@gmail.com> Co-authored-by: Fredrik Oseberg <fredrik.no@gmail.com>
2022-01-13 11:14:17 +01:00
import { IRole } from '../../../../lib/types/stores/access-store';
import { IEventStore } from '../../../../lib/types/stores/event-store';
import { IUserStore } from '../../../../lib/types/stores/user-store';
import { RoleName } from '../../../../lib/types/model';
feat: custom project roles (#1220) * wip: environment for permissions * fix: add migration for roles * fix: connect environment with access service * feat: add tests * chore: Implement scaffolding for new rbac * fix: add fake store * feat: Add api endpoints for roles and permissions list * feat: Add ability to provide permissions when creating a role and rename environmentName to name in the list permissions datastructure * fix: Make project roles resolve correctly against new environments permissions structure * fix: Patch migration to also populate permission names * fix: Make permissions actually work with new environments * fix: Add back to get permissions working for editor role * fix: Removed ability to set role type through api during creation - it's now always custom * feat: Return permissions on get role endpoint * feat: Add in support for updating roles * fix: Get a bunch of tests working and delete a few that make no sense anymore * chore: A few small cleanups - remove logging and restore default on dev server config * chore: Refactor role/access stores into more logical domains * feat: Add in validation for roles * feat: Patch db migration to handle old stucture * fix: migration for project roles * fix: patch a few broken tests * fix: add permissions to editor * fix: update test name * fix: update user permission mapping * fix: create new user * fix: update root role test * fix: update tests * feat: Validation now works when updating a role * fix: Add in very barebones down migration for rbac so that tests work * fix: Improve responses from role resolution - getting a non existant role will throw a NotFound error * fix: remove unused permissions * fix: add test for connecting roles and deleting project * fix: add test for adding a project member with a custom role * fix: add test for changing user role * fix: add guard for deleting role if the role is in use * fix: alter migration * chore: Minor code cleanups * chore: Small code cleanups * chore: More minor cleanups of code * chore: Trim some dead code to make the linter happy * feat: Schema validation for roles * fix: setup permission for variant * fix: remove unused import * feat: Add cascading delete for role_permissions when deleting a role * feat: add configuration option for disabling legacy api * chore: update frontend to beta version * 4.6.0-beta.0 * fix: export default project constant * fix: update snapshot * fix: module pattern ../../lib * fix: move DEFAULT_PROJECT to types * fix: remove debug logging * fix: remove debug log state * fix: Change permission descriptions * fix: roles should have unique name * fix: root roles should be connected to the default project * fix: typo in role-schema.ts * fix: Role permission empty string for non environment type * feat: new permission for moving project * fix: add event for changeProject * fix: Removing a user from a project will now check to see if that project has an owner, rather than checking if any project has an owner * fix: add tests for move project * fix: Add in missing create/delete tag permissions * fix: Removed duplicate impl caused by multiple good samaritans putting it back in! * fix: Trim out add tag permissions, for now at least * chore: Trim out new add and delete tag permissions - we're going with update feature instead * chore: update frontend * 4.6.0-beta.1 * feat: Prevent editing of built in roles * fix: Patch an issue where permissions for variants/environments didn't match the front end * fix: lint Co-authored-by: Ivar Conradi Østhus <ivarconr@gmail.com> Co-authored-by: Fredrik Oseberg <fredrik.no@gmail.com>
2022-01-13 11:14:17 +01:00
import { IRoleStore } from 'lib/types/stores/role-store';
let stores;
let db;
let app;
let userStore: IUserStore;
let eventStore: IEventStore;
feat: custom project roles (#1220) * wip: environment for permissions * fix: add migration for roles * fix: connect environment with access service * feat: add tests * chore: Implement scaffolding for new rbac * fix: add fake store * feat: Add api endpoints for roles and permissions list * feat: Add ability to provide permissions when creating a role and rename environmentName to name in the list permissions datastructure * fix: Make project roles resolve correctly against new environments permissions structure * fix: Patch migration to also populate permission names * fix: Make permissions actually work with new environments * fix: Add back to get permissions working for editor role * fix: Removed ability to set role type through api during creation - it's now always custom * feat: Return permissions on get role endpoint * feat: Add in support for updating roles * fix: Get a bunch of tests working and delete a few that make no sense anymore * chore: A few small cleanups - remove logging and restore default on dev server config * chore: Refactor role/access stores into more logical domains * feat: Add in validation for roles * feat: Patch db migration to handle old stucture * fix: migration for project roles * fix: patch a few broken tests * fix: add permissions to editor * fix: update test name * fix: update user permission mapping * fix: create new user * fix: update root role test * fix: update tests * feat: Validation now works when updating a role * fix: Add in very barebones down migration for rbac so that tests work * fix: Improve responses from role resolution - getting a non existant role will throw a NotFound error * fix: remove unused permissions * fix: add test for connecting roles and deleting project * fix: add test for adding a project member with a custom role * fix: add test for changing user role * fix: add guard for deleting role if the role is in use * fix: alter migration * chore: Minor code cleanups * chore: Small code cleanups * chore: More minor cleanups of code * chore: Trim some dead code to make the linter happy * feat: Schema validation for roles * fix: setup permission for variant * fix: remove unused import * feat: Add cascading delete for role_permissions when deleting a role * feat: add configuration option for disabling legacy api * chore: update frontend to beta version * 4.6.0-beta.0 * fix: export default project constant * fix: update snapshot * fix: module pattern ../../lib * fix: move DEFAULT_PROJECT to types * fix: remove debug logging * fix: remove debug log state * fix: Change permission descriptions * fix: roles should have unique name * fix: root roles should be connected to the default project * fix: typo in role-schema.ts * fix: Role permission empty string for non environment type * feat: new permission for moving project * fix: add event for changeProject * fix: Removing a user from a project will now check to see if that project has an owner, rather than checking if any project has an owner * fix: add tests for move project * fix: Add in missing create/delete tag permissions * fix: Removed duplicate impl caused by multiple good samaritans putting it back in! * fix: Trim out add tag permissions, for now at least * chore: Trim out new add and delete tag permissions - we're going with update feature instead * chore: update frontend * 4.6.0-beta.1 * feat: Prevent editing of built in roles * fix: Patch an issue where permissions for variants/environments didn't match the front end * fix: lint Co-authored-by: Ivar Conradi Østhus <ivarconr@gmail.com> Co-authored-by: Fredrik Oseberg <fredrik.no@gmail.com>
2022-01-13 11:14:17 +01:00
let roleStore: IRoleStore;
let editorRole: IRole;
let adminRole: IRole;
beforeAll(async () => {
db = await dbInit('user_admin_api_serial', getLogger);
stores = db.stores;
app = await setupApp(stores);
userStore = stores.userStore;
eventStore = stores.eventStore;
feat: custom project roles (#1220) * wip: environment for permissions * fix: add migration for roles * fix: connect environment with access service * feat: add tests * chore: Implement scaffolding for new rbac * fix: add fake store * feat: Add api endpoints for roles and permissions list * feat: Add ability to provide permissions when creating a role and rename environmentName to name in the list permissions datastructure * fix: Make project roles resolve correctly against new environments permissions structure * fix: Patch migration to also populate permission names * fix: Make permissions actually work with new environments * fix: Add back to get permissions working for editor role * fix: Removed ability to set role type through api during creation - it's now always custom * feat: Return permissions on get role endpoint * feat: Add in support for updating roles * fix: Get a bunch of tests working and delete a few that make no sense anymore * chore: A few small cleanups - remove logging and restore default on dev server config * chore: Refactor role/access stores into more logical domains * feat: Add in validation for roles * feat: Patch db migration to handle old stucture * fix: migration for project roles * fix: patch a few broken tests * fix: add permissions to editor * fix: update test name * fix: update user permission mapping * fix: create new user * fix: update root role test * fix: update tests * feat: Validation now works when updating a role * fix: Add in very barebones down migration for rbac so that tests work * fix: Improve responses from role resolution - getting a non existant role will throw a NotFound error * fix: remove unused permissions * fix: add test for connecting roles and deleting project * fix: add test for adding a project member with a custom role * fix: add test for changing user role * fix: add guard for deleting role if the role is in use * fix: alter migration * chore: Minor code cleanups * chore: Small code cleanups * chore: More minor cleanups of code * chore: Trim some dead code to make the linter happy * feat: Schema validation for roles * fix: setup permission for variant * fix: remove unused import * feat: Add cascading delete for role_permissions when deleting a role * feat: add configuration option for disabling legacy api * chore: update frontend to beta version * 4.6.0-beta.0 * fix: export default project constant * fix: update snapshot * fix: module pattern ../../lib * fix: move DEFAULT_PROJECT to types * fix: remove debug logging * fix: remove debug log state * fix: Change permission descriptions * fix: roles should have unique name * fix: root roles should be connected to the default project * fix: typo in role-schema.ts * fix: Role permission empty string for non environment type * feat: new permission for moving project * fix: add event for changeProject * fix: Removing a user from a project will now check to see if that project has an owner, rather than checking if any project has an owner * fix: add tests for move project * fix: Add in missing create/delete tag permissions * fix: Removed duplicate impl caused by multiple good samaritans putting it back in! * fix: Trim out add tag permissions, for now at least * chore: Trim out new add and delete tag permissions - we're going with update feature instead * chore: update frontend * 4.6.0-beta.1 * feat: Prevent editing of built in roles * fix: Patch an issue where permissions for variants/environments didn't match the front end * fix: lint Co-authored-by: Ivar Conradi Østhus <ivarconr@gmail.com> Co-authored-by: Fredrik Oseberg <fredrik.no@gmail.com>
2022-01-13 11:14:17 +01:00
roleStore = stores.roleStore;
const roles = await roleStore.getRootRoles();
editorRole = roles.find((r) => r.name === RoleName.EDITOR);
adminRole = roles.find((r) => r.name === RoleName.ADMIN);
});
afterAll(async () => {
await app.destroy();
await db.destroy();
});
afterEach(async () => {
await userStore.deleteAll();
});
test('returns empty list of users', async () => {
return app.request
.get('/api/admin/user-admin')
.expect('Content-Type', /json/)
.expect(200)
.expect((res) => {
expect(res.body.users.length).toBe(0);
});
});
test('creates and returns all users', async () => {
2022-01-06 21:26:53 +01:00
const createUserRequests = [...Array(10).keys()].map((i) =>
app.request
.post('/api/admin/user-admin')
.send({
email: `some${i}@getunleash.ai`,
name: `Some Name ${i}`,
rootRole: editorRole.id,
})
.set('Content-Type', 'application/json'),
);
await Promise.all(createUserRequests);
return app.request
.get('/api/admin/user-admin')
.expect('Content-Type', /json/)
.expect(200)
.expect((res) => {
2022-01-06 21:26:53 +01:00
expect(res.body.users.length).toBe(10);
expect(res.body.users[2].rootRole).toBe(editorRole.id);
});
});
test('creates editor-user without password', async () => {
return app.request
.post('/api/admin/user-admin')
.send({
email: 'some@getunelash.ai',
name: 'Some Name',
rootRole: editorRole.id,
})
.set('Content-Type', 'application/json')
.expect(201)
.expect((res) => {
expect(res.body.email).toBe('some@getunelash.ai');
expect(res.body.rootRole).toBe(editorRole.id);
expect(res.body.id).toBeTruthy();
});
});
test('creates admin-user with password', async () => {
const { body } = await app.request
.post('/api/admin/user-admin')
.send({
email: 'some@getunelash.ai',
name: 'Some Name',
password: 'some-strange-pass-123-GH',
rootRole: adminRole.id,
})
.set('Content-Type', 'application/json')
.expect(201);
expect(body.rootRole).toBe(adminRole.id);
const user = await userStore.getByQuery({ id: body.id });
expect(user.email).toBe('some@getunelash.ai');
expect(user.name).toBe('Some Name');
const passwordHash = userStore.getPasswordHash(body.id);
expect(passwordHash).toBeTruthy();
const roles = await stores.accessStore.getRolesForUserId(body.id);
expect(roles.length).toBe(1);
expect(roles[0].name).toBe(RoleName.ADMIN);
});
test('requires known root role', async () => {
return app.request
.post('/api/admin/user-admin')
.send({
email: 'some@getunelash.ai',
name: 'Some Name',
rootRole: 'Unknown',
})
.set('Content-Type', 'application/json')
.expect(400);
});
test('update user name', async () => {
const { body } = await app.request
.post('/api/admin/user-admin')
.send({
email: 'some@getunelash.ai',
name: 'Some Name',
rootRole: editorRole.id,
})
.set('Content-Type', 'application/json');
return app.request
.put(`/api/admin/user-admin/${body.id}`)
.send({
name: 'New name',
})
.set('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body.email).toBe('some@getunelash.ai');
expect(res.body.name).toBe('New name');
expect(res.body.id).toBe(body.id);
});
});
test('get a single user', async () => {
const { body } = await app.request
.post('/api/admin/user-admin')
.send({
email: 'some2@getunelash.ai',
name: 'Some Name 2',
rootRole: editorRole.id,
})
.set('Content-Type', 'application/json');
const { body: user } = await app.request
.get(`/api/admin/user-admin/${body.id}`)
.expect(200);
expect(user.email).toBe('some2@getunelash.ai');
expect(user.name).toBe('Some Name 2');
expect(user.id).toBe(body.id);
});
test('should delete user', async () => {
const user = await userStore.insert({ email: 'some@mail.com' });
return app.request.delete(`/api/admin/user-admin/${user.id}`).expect(200);
});
test('validator should require strong password', async () => {
return app.request
.post('/api/admin/user-admin/validate-password')
.send({ password: 'simple' })
.expect(400);
});
test('validator should accept strong password', async () => {
return app.request
.post('/api/admin/user-admin/validate-password')
.send({ password: 'simple123-_ASsad' })
.expect(200);
});
test('should change password', async () => {
const user = await userStore.insert({ email: 'some@mail.com' });
return app.request
.post(`/api/admin/user-admin/${user.id}/change-password`)
.send({ password: 'simple123-_ASsad' })
.expect(200);
});
test('should search for users', async () => {
await userStore.insert({ email: 'some@mail.com' });
await userStore.insert({ email: 'another@mail.com' });
await userStore.insert({ email: 'another2@mail.com' });
return app.request
.get('/api/admin/user-admin/search?q=another')
.expect(200)
.expect((res) => {
expect(res.body.length).toBe(2);
expect(res.body.some((u) => u.email === 'another@mail.com')).toBe(
true,
);
});
});
test('Creates a user and includes inviteLink and emailConfigured', async () => {
return app.request
.post('/api/admin/user-admin')
.send({
email: 'some@getunelash.ai',
name: 'Some Name',
rootRole: editorRole.id,
})
.set('Content-Type', 'application/json')
.expect(201)
.expect((res) => {
expect(res.body.email).toBe('some@getunelash.ai');
expect(res.body.rootRole).toBe(editorRole.id);
expect(res.body.inviteLink).toBeTruthy();
expect(res.body.emailSent).toBeFalsy();
expect(res.body.id).toBeTruthy();
});
});
test('Creates a user but does not send email if sendEmail is set to false', async () => {
const myAppConfig = await setupAppWithCustomConfig(stores, {
email: {
host: 'smtp.ethereal.email',
smtpuser: 'rafaela.pouros@ethereal.email',
smtppass: 'CuVPBSvUFBPuqXMFEe',
},
});
await myAppConfig.request
.post('/api/admin/user-admin')
.send({
email: 'some@getunelash.ai',
name: 'Some Name',
rootRole: editorRole.id,
sendEmail: false,
})
.set('Content-Type', 'application/json')
.expect(201)
.expect((res) => {
expect(res.body.emailSent).toBeFalsy();
});
await myAppConfig.request
.post('/api/admin/user-admin')
.send({
email: 'some2@getunelash.ai',
name: 'Some2 Name',
rootRole: editorRole.id,
})
.set('Content-Type', 'application/json')
.expect(201)
.expect((res) => {
expect(res.body.emailSent).toBeTruthy();
});
await myAppConfig.destroy();
});
test('generates USER_CREATED event', async () => {
const email = 'some@getunelash.ai';
const name = 'Some Name';
const { body } = await app.request
.post('/api/admin/user-admin')
.send({
email,
name,
password: 'some-strange-pass-123-GH',
rootRole: adminRole.id,
})
.set('Content-Type', 'application/json')
.expect(201);
const events = await eventStore.getEvents();
expect(events[0].type).toBe(USER_CREATED);
expect(events[0].data.email).toBe(email);
expect(events[0].data.name).toBe(name);
expect(events[0].data.id).toBe(body.id);
expect(events[0].data.password).toBeFalsy();
});
test('generates USER_DELETED event', async () => {
const user = await userStore.insert({ email: 'some@mail.com' });
await app.request.delete(`/api/admin/user-admin/${user.id}`);
const events = await eventStore.getEvents();
expect(events[0].type).toBe(USER_DELETED);
expect(events[0].preData.id).toBe(user.id);
expect(events[0].preData.email).toBe(user.email);
});
test('generates USER_UPDATED event', async () => {
const { body } = await app.request
.post('/api/admin/user-admin')
.send({
email: 'some@getunelash.ai',
name: 'Some Name',
rootRole: editorRole.id,
})
.set('Content-Type', 'application/json');
await app.request
.put(`/api/admin/user-admin/${body.id}`)
.send({
name: 'New name',
})
.set('Content-Type', 'application/json');
const events = await eventStore.getEvents();
expect(events[0].type).toBe(USER_UPDATED);
expect(events[0].data.id).toBe(body.id);
expect(events[0].data.name).toBe('New name');
});