mirror of
https://github.com/Unleash/unleash.git
synced 2025-03-27 00:19:39 +01:00
feat: add migration (#8891)
This commit is contained in:
parent
8bf1b783e9
commit
2363d99fe7
@ -6,7 +6,12 @@ import {
|
|||||||
} from '../../../test/e2e/helpers/test-helper';
|
} from '../../../test/e2e/helpers/test-helper';
|
||||||
import getLogger from '../../../test/fixtures/no-logger';
|
import getLogger from '../../../test/fixtures/no-logger';
|
||||||
import type { FeatureSearchQueryParameters } from '../../openapi/spec/feature-search-query-parameters';
|
import type { FeatureSearchQueryParameters } from '../../openapi/spec/feature-search-query-parameters';
|
||||||
import { DEFAULT_PROJECT, type IUnleashStores } from '../../types';
|
import {
|
||||||
|
CREATE_FEATURE_STRATEGY,
|
||||||
|
DEFAULT_PROJECT,
|
||||||
|
type IUnleashStores,
|
||||||
|
UPDATE_FEATURE_ENVIRONMENT,
|
||||||
|
} from '../../types';
|
||||||
import { DEFAULT_ENV } from '../../util';
|
import { DEFAULT_ENV } from '../../util';
|
||||||
|
|
||||||
let app: IUnleashTest;
|
let app: IUnleashTest;
|
||||||
@ -29,7 +34,7 @@ beforeAll(async () => {
|
|||||||
);
|
);
|
||||||
stores = db.stores;
|
stores = db.stores;
|
||||||
|
|
||||||
await app.request
|
const { body } = await app.request
|
||||||
.post(`/auth/demo/login`)
|
.post(`/auth/demo/login`)
|
||||||
.send({
|
.send({
|
||||||
email: 'user@getunleash.io',
|
email: 'user@getunleash.io',
|
||||||
@ -43,12 +48,30 @@ beforeAll(async () => {
|
|||||||
|
|
||||||
await app.linkProjectToEnvironment('default', 'development');
|
await app.linkProjectToEnvironment('default', 'development');
|
||||||
|
|
||||||
|
await stores.accessStore.addPermissionsToRole(
|
||||||
|
body.rootRole,
|
||||||
|
[
|
||||||
|
{ name: UPDATE_FEATURE_ENVIRONMENT },
|
||||||
|
{ name: CREATE_FEATURE_STRATEGY },
|
||||||
|
],
|
||||||
|
'development',
|
||||||
|
);
|
||||||
|
|
||||||
await stores.environmentStore.create({
|
await stores.environmentStore.create({
|
||||||
name: 'production',
|
name: 'production',
|
||||||
type: 'production',
|
type: 'production',
|
||||||
});
|
});
|
||||||
|
|
||||||
await app.linkProjectToEnvironment('default', 'production');
|
await app.linkProjectToEnvironment('default', 'production');
|
||||||
|
|
||||||
|
await stores.accessStore.addPermissionsToRole(
|
||||||
|
body.rootRole,
|
||||||
|
[
|
||||||
|
{ name: UPDATE_FEATURE_ENVIRONMENT },
|
||||||
|
{ name: CREATE_FEATURE_STRATEGY },
|
||||||
|
],
|
||||||
|
'production',
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
|
@ -805,6 +805,11 @@ describe('Managing Project access', () => {
|
|||||||
mode: 'open' as const,
|
mode: 'open' as const,
|
||||||
defaultStickiness: 'clientId',
|
defaultStickiness: 'clientId',
|
||||||
};
|
};
|
||||||
|
await db.stores.environmentStore.create({
|
||||||
|
name: 'production',
|
||||||
|
type: 'production',
|
||||||
|
enabled: true,
|
||||||
|
});
|
||||||
|
|
||||||
const auditUser = extractAuditInfoFromUser(user);
|
const auditUser = extractAuditInfoFromUser(user);
|
||||||
await projectService.createProject(project, user, auditUser);
|
await projectService.createProject(project, user, auditUser);
|
||||||
|
@ -0,0 +1,20 @@
|
|||||||
|
exports.up = function (db, cb) {
|
||||||
|
db.runSql(
|
||||||
|
`
|
||||||
|
UPDATE role_permission SET environment = null where environment = '';
|
||||||
|
DELETE FROM role_permission WHERE environment IS NOT NULL AND environment NOT IN (SELECT name FROM environments);
|
||||||
|
ALTER TABLE role_permission ADD CONSTRAINT fk_role_permission_environment FOREIGN KEY (environment) REFERENCES environments(name) ON DELETE CASCADE;
|
||||||
|
`,
|
||||||
|
cb,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.down = function (db, cb) {
|
||||||
|
db.runSql(
|
||||||
|
`
|
||||||
|
ALTER TABLE role_permission
|
||||||
|
DROP CONSTRAINT IF EXISTS fk_role_permission_environment;
|
||||||
|
`,
|
||||||
|
cb,
|
||||||
|
);
|
||||||
|
};
|
@ -21,9 +21,19 @@ delete process.env.DATABASE_URL;
|
|||||||
// because of db-migrate bug (https://github.com/Unleash/unleash/issues/171)
|
// because of db-migrate bug (https://github.com/Unleash/unleash/issues/171)
|
||||||
process.setMaxListeners(0);
|
process.setMaxListeners(0);
|
||||||
|
|
||||||
|
async function getDefaultEnvRolePermissions(knex) {
|
||||||
|
return knex.table('role_permission').whereIn('environment', ['default']);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function restoreRolePermissions(knex, rolePermissions) {
|
||||||
|
await knex.table('role_permission').insert(rolePermissions);
|
||||||
|
}
|
||||||
|
|
||||||
async function resetDatabase(knex) {
|
async function resetDatabase(knex) {
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
knex.table('environments').del(),
|
knex
|
||||||
|
.table('environments')
|
||||||
|
.del(), // deletes role permissions transitively
|
||||||
knex.table('strategies').del(),
|
knex.table('strategies').del(),
|
||||||
knex.table('features').del(),
|
knex.table('features').del(),
|
||||||
knex.table('client_applications').del(),
|
knex.table('client_applications').del(),
|
||||||
@ -110,15 +120,20 @@ export default async function init(
|
|||||||
const testDb = createDb(config);
|
const testDb = createDb(config);
|
||||||
const stores = await createStores(config, testDb);
|
const stores = await createStores(config, testDb);
|
||||||
stores.eventStore.setMaxListeners(0);
|
stores.eventStore.setMaxListeners(0);
|
||||||
|
const defaultRolePermissions = await getDefaultEnvRolePermissions(testDb);
|
||||||
await resetDatabase(testDb);
|
await resetDatabase(testDb);
|
||||||
await setupDatabase(stores);
|
await setupDatabase(stores);
|
||||||
|
await restoreRolePermissions(testDb, defaultRolePermissions);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
rawDatabase: testDb,
|
rawDatabase: testDb,
|
||||||
stores,
|
stores,
|
||||||
reset: async () => {
|
reset: async () => {
|
||||||
|
const defaultRolePermissions =
|
||||||
|
await getDefaultEnvRolePermissions(testDb);
|
||||||
await resetDatabase(testDb);
|
await resetDatabase(testDb);
|
||||||
await setupDatabase(stores);
|
await setupDatabase(stores);
|
||||||
|
await restoreRolePermissions(testDb, defaultRolePermissions);
|
||||||
},
|
},
|
||||||
destroy: async () => {
|
destroy: async () => {
|
||||||
return new Promise<void>((resolve, reject) => {
|
return new Promise<void>((resolve, reject) => {
|
||||||
|
@ -94,8 +94,6 @@ const createRole = async (rolePermissions: PermissionRef[]) => {
|
|||||||
|
|
||||||
const hasCommonProjectAccess = async (user, projectName, condition) => {
|
const hasCommonProjectAccess = async (user, projectName, condition) => {
|
||||||
const defaultEnv = 'default';
|
const defaultEnv = 'default';
|
||||||
const developmentEnv = 'development';
|
|
||||||
const productionEnv = 'production';
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
CREATE_FEATURE,
|
CREATE_FEATURE,
|
||||||
@ -155,70 +153,6 @@ const hasCommonProjectAccess = async (user, projectName, condition) => {
|
|||||||
defaultEnv,
|
defaultEnv,
|
||||||
),
|
),
|
||||||
).toBe(condition);
|
).toBe(condition);
|
||||||
expect(
|
|
||||||
await accessService.hasPermission(
|
|
||||||
user,
|
|
||||||
CREATE_FEATURE_STRATEGY,
|
|
||||||
projectName,
|
|
||||||
developmentEnv,
|
|
||||||
),
|
|
||||||
).toBe(condition);
|
|
||||||
expect(
|
|
||||||
await accessService.hasPermission(
|
|
||||||
user,
|
|
||||||
UPDATE_FEATURE_STRATEGY,
|
|
||||||
projectName,
|
|
||||||
developmentEnv,
|
|
||||||
),
|
|
||||||
).toBe(condition);
|
|
||||||
expect(
|
|
||||||
await accessService.hasPermission(
|
|
||||||
user,
|
|
||||||
DELETE_FEATURE_STRATEGY,
|
|
||||||
projectName,
|
|
||||||
developmentEnv,
|
|
||||||
),
|
|
||||||
).toBe(condition);
|
|
||||||
expect(
|
|
||||||
await accessService.hasPermission(
|
|
||||||
user,
|
|
||||||
UPDATE_FEATURE_ENVIRONMENT,
|
|
||||||
projectName,
|
|
||||||
developmentEnv,
|
|
||||||
),
|
|
||||||
).toBe(condition);
|
|
||||||
expect(
|
|
||||||
await accessService.hasPermission(
|
|
||||||
user,
|
|
||||||
CREATE_FEATURE_STRATEGY,
|
|
||||||
projectName,
|
|
||||||
productionEnv,
|
|
||||||
),
|
|
||||||
).toBe(condition);
|
|
||||||
expect(
|
|
||||||
await accessService.hasPermission(
|
|
||||||
user,
|
|
||||||
UPDATE_FEATURE_STRATEGY,
|
|
||||||
projectName,
|
|
||||||
productionEnv,
|
|
||||||
),
|
|
||||||
).toBe(condition);
|
|
||||||
expect(
|
|
||||||
await accessService.hasPermission(
|
|
||||||
user,
|
|
||||||
DELETE_FEATURE_STRATEGY,
|
|
||||||
projectName,
|
|
||||||
productionEnv,
|
|
||||||
),
|
|
||||||
).toBe(condition);
|
|
||||||
expect(
|
|
||||||
await accessService.hasPermission(
|
|
||||||
user,
|
|
||||||
UPDATE_FEATURE_ENVIRONMENT,
|
|
||||||
projectName,
|
|
||||||
productionEnv,
|
|
||||||
),
|
|
||||||
).toBe(condition);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const hasFullProjectAccess = async (user, projectName: string, condition) => {
|
const hasFullProjectAccess = async (user, projectName: string, condition) => {
|
||||||
@ -378,7 +312,7 @@ test('should remove CREATE_FEATURE on default environment', async () => {
|
|||||||
await accessService.addPermissionToRole(
|
await accessService.addPermissionToRole(
|
||||||
editRole.id,
|
editRole.id,
|
||||||
permissions.CREATE_FEATURE,
|
permissions.CREATE_FEATURE,
|
||||||
'*',
|
'default',
|
||||||
);
|
);
|
||||||
|
|
||||||
// TODO: to validate the remove works, we should make sure that we had permission before removing it
|
// TODO: to validate the remove works, we should make sure that we had permission before removing it
|
||||||
@ -637,7 +571,7 @@ test('should support permission with "ALL" environment requirement', async () =>
|
|||||||
await accessStore.addPermissionsToRole(
|
await accessStore.addPermissionsToRole(
|
||||||
customRole.id,
|
customRole.id,
|
||||||
[{ name: CREATE_FEATURE_STRATEGY }],
|
[{ name: CREATE_FEATURE_STRATEGY }],
|
||||||
'production',
|
'default',
|
||||||
);
|
);
|
||||||
await accessStore.addUserToRole(user.id, customRole.id, ALL_PROJECTS);
|
await accessStore.addUserToRole(user.id, customRole.id, ALL_PROJECTS);
|
||||||
|
|
||||||
@ -645,7 +579,7 @@ test('should support permission with "ALL" environment requirement', async () =>
|
|||||||
user,
|
user,
|
||||||
CREATE_FEATURE_STRATEGY,
|
CREATE_FEATURE_STRATEGY,
|
||||||
'default',
|
'default',
|
||||||
'production',
|
'default',
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(hasAccess).toBe(true);
|
expect(hasAccess).toBe(true);
|
||||||
@ -667,7 +601,7 @@ test('Should have access to create a strategy in an environment', async () => {
|
|||||||
user,
|
user,
|
||||||
CREATE_FEATURE_STRATEGY,
|
CREATE_FEATURE_STRATEGY,
|
||||||
'default',
|
'default',
|
||||||
'development',
|
'default',
|
||||||
),
|
),
|
||||||
).toBe(true);
|
).toBe(true);
|
||||||
});
|
});
|
||||||
@ -693,7 +627,7 @@ test('Should have access to edit a strategy in an environment', async () => {
|
|||||||
user,
|
user,
|
||||||
UPDATE_FEATURE_STRATEGY,
|
UPDATE_FEATURE_STRATEGY,
|
||||||
'default',
|
'default',
|
||||||
'development',
|
'default',
|
||||||
),
|
),
|
||||||
).toBe(true);
|
).toBe(true);
|
||||||
});
|
});
|
||||||
@ -706,7 +640,7 @@ test('Should have access to delete a strategy in an environment', async () => {
|
|||||||
user,
|
user,
|
||||||
DELETE_FEATURE_STRATEGY,
|
DELETE_FEATURE_STRATEGY,
|
||||||
'default',
|
'default',
|
||||||
'development',
|
'default',
|
||||||
),
|
),
|
||||||
).toBe(true);
|
).toBe(true);
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user