feat: introduce role based access control
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
import { Knex } from 'knex';
|
||||
import capitalize from 'lodash/capitalize';
|
||||
import lowerCase from 'lodash/lowerCase';
|
||||
|
||||
export async function up(knex: Knex): Promise<void> {
|
||||
await knex.schema.createTable('roles', (table) => {
|
||||
table.uuid('id').primary().defaultTo(knex.raw('gen_random_uuid()'));
|
||||
table.string('name').notNullable();
|
||||
table.string('key').notNullable();
|
||||
table.string('description');
|
||||
|
||||
table.timestamps(true, true);
|
||||
});
|
||||
|
||||
const uniqueUserRoles = await knex('users')
|
||||
.select('role')
|
||||
.groupBy('role');
|
||||
|
||||
for (const { role } of uniqueUserRoles) {
|
||||
// skip empty roles
|
||||
if (!role) continue;
|
||||
|
||||
await knex('roles').insert({
|
||||
name: capitalize(role),
|
||||
key: lowerCase(role),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export async function down(knex: Knex): Promise<void> {
|
||||
return knex.schema.dropTable('roles');
|
||||
}
|
@@ -0,0 +1,25 @@
|
||||
import { Knex } from 'knex';
|
||||
|
||||
const getPermission = (subject: string, actions: string[]) => actions.map(action => ({ subject, action }));
|
||||
|
||||
export async function up(knex: Knex): Promise<void> {
|
||||
await knex.schema.createTable('permissions', (table) => {
|
||||
table.uuid('id').primary().defaultTo(knex.raw('gen_random_uuid()'));
|
||||
table.string('action').notNullable();
|
||||
table.string('subject').notNullable();
|
||||
|
||||
table.timestamps(true, true);
|
||||
});
|
||||
|
||||
await knex('permissions').insert([
|
||||
...getPermission('Connection', ['create', 'read', 'delete', 'update']),
|
||||
...getPermission('Execution', ['read']),
|
||||
...getPermission('Flow', ['create', 'delete', 'publish', 'read', 'update']),
|
||||
...getPermission('Role', ['create', 'delete', 'read', 'update']),
|
||||
...getPermission('User', ['create', 'delete', 'read', 'update']),
|
||||
]);
|
||||
}
|
||||
|
||||
export async function down(knex: Knex): Promise<void> {
|
||||
return knex.schema.dropTable('permissions');
|
||||
}
|
@@ -0,0 +1,25 @@
|
||||
import { Knex } from 'knex';
|
||||
|
||||
export async function up(knex: Knex): Promise<void> {
|
||||
await knex.schema.createTable('roles_permissions', (table) => {
|
||||
table.uuid('id').primary().defaultTo(knex.raw('gen_random_uuid()'));
|
||||
table.uuid('role_id').references('id').inTable('roles');
|
||||
table.uuid('permission_id').references('id').inTable('permissions');
|
||||
});
|
||||
|
||||
const roles = await knex('roles').select('id');
|
||||
const permissions = await knex('permissions').select('id');
|
||||
|
||||
for (const role of roles) {
|
||||
for (const permission of permissions) {
|
||||
await knex('roles_permissions').insert({
|
||||
role_id: role.id,
|
||||
permission_id: permission.id,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export async function down(knex: Knex): Promise<void> {
|
||||
return knex.schema.dropTable('roles_permissions');
|
||||
}
|
@@ -0,0 +1,29 @@
|
||||
import { Knex } from 'knex';
|
||||
|
||||
export async function up(knex: Knex): Promise<void> {
|
||||
await knex.schema.table('users', async (table) => {
|
||||
table.uuid('role_id').references('id').inTable('roles');
|
||||
});
|
||||
|
||||
const theRole = await knex('roles').select('id').limit(1).first();
|
||||
const roles = await knex('roles').select('id', 'key');
|
||||
|
||||
for (const role of roles) {
|
||||
await knex('users')
|
||||
.where({
|
||||
role: role.key
|
||||
})
|
||||
.update({
|
||||
role_id: role.id
|
||||
});
|
||||
}
|
||||
|
||||
// backfill not-migratables
|
||||
await knex('users').whereNull('role_id').update({ role_id: theRole.id });
|
||||
}
|
||||
|
||||
export async function down(knex: Knex): Promise<void> {
|
||||
return await knex.schema.table('users', (table) => {
|
||||
table.dropColumn('role_id');
|
||||
});
|
||||
}
|
@@ -0,0 +1,13 @@
|
||||
import { Knex } from 'knex';
|
||||
|
||||
export async function up(knex: Knex): Promise<void> {
|
||||
await knex.schema.table('users', async (table) => {
|
||||
table.dropColumn('role');
|
||||
});
|
||||
}
|
||||
|
||||
export async function down(knex: Knex): Promise<void> {
|
||||
return await knex.schema.table('users', (table) => {
|
||||
table.string('role').defaultTo('user');
|
||||
});
|
||||
}
|
Reference in New Issue
Block a user