feat(auth): add user and role management

This commit is contained in:
Ali BARIN
2023-07-18 21:00:10 +00:00
parent a7104c41a2
commit 0deaa03218
108 changed files with 2909 additions and 388 deletions

View File

@@ -16,13 +16,27 @@ export async function up(knex: Knex): Promise<void> {
.select('role')
.groupBy('role');
let shouldCreateAdminRole = true;
for (const { role } of uniqueUserRoles) {
// skip empty roles
if (!role) continue;
const lowerCaseRole = lowerCase(role);
if (lowerCaseRole === 'admin') {
shouldCreateAdminRole = false;
}
await knex('roles').insert({
name: capitalize(role),
key: lowerCase(role),
key: lowerCaseRole,
});
}
if (shouldCreateAdminRole) {
await knex('roles').insert({
name: 'Admin',
key: 'admin',
});
}
}

View File

@@ -1,23 +1,46 @@
import { Knex } from 'knex';
const getPermission = (subject: string, actions: string[]) => actions.map(action => ({ subject, action }));
const getPermissionForRole = (roleId: string, subject: string, actions: string[], conditions: string[] = []) => actions
.map(action => ({
role_id: roleId,
subject,
action,
conditions,
}));
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.uuid('role_id').references('id').inTable('roles');
table.string('action').notNullable();
table.string('subject').notNullable();
table.jsonb('conditions').notNullable().defaultTo([]);
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']),
]);
const roles = await knex('roles').select(['id', 'key']) as { id: string, key: string }[];
for (const role of roles) {
// `admin` role should have no conditions unlike others by default
const isAdmin = role.key === 'admin';
const roleConditions = isAdmin ? [] : ['isCreator'];
// default permissions
await knex('permissions').insert([
...getPermissionForRole(role.id, 'Connection', ['create', 'read', 'delete', 'update'], roleConditions),
...getPermissionForRole(role.id, 'Execution', ['read'], roleConditions),
...getPermissionForRole(role.id, 'Flow', ['create', 'delete', 'publish', 'read', 'update'], roleConditions),
]);
// admin specific permission
if (isAdmin) {
await knex('permissions').insert([
...getPermissionForRole(role.id, 'User', ['create', 'read', 'delete', 'update']),
...getPermissionForRole(role.id, 'Role', ['create', 'read', 'delete', 'update']),
]);
}
}
}
export async function down(knex: Knex): Promise<void> {

View File

@@ -1,25 +0,0 @@
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');
}

View File

@@ -13,6 +13,7 @@ export async function up(knex: Knex): Promise<void> {
table.text('email_attribute_name').notNullable();
table.text('role_attribute_name').notNullable();
table.uuid('default_role_id').references('id').inTable('roles');
table.boolean('active').defaultTo(false);
table.timestamps(true, true);
});

View File

@@ -6,9 +6,6 @@ export async function up(knex: Knex): Promise<void> {
});
}
export async function down(knex: Knex): Promise<void> {
return await knex.schema.alterTable('users', table => {
// what do we do? passwords cannot be left empty
// table.string('password').notNullable().alter();
});
export async function down(): Promise<void> {
// void
}