tethys.backend/app/Middleware/Role.ts
2023-03-03 16:54:28 +01:00

84 lines
2.4 KiB
TypeScript

import type { HttpContextContract } from '@ioc:Adonis/Core/HttpContext';
import Database from '@ioc:Adonis/Lucid/Database';
import Config from '@ioc:Adonis/Core/Config';
import User from 'app/Models/User';
import { Exception } from '@adonisjs/core/build/standalone';
const roleTable = Config.get('rolePermission.role_table', 'roles');
const userRoleTable = Config.get('rolePermission.user_role_table', 'link_accounts_roles');
// node ace make:middleware role
export default class Role {
// .middleware(['auth', 'role:admin,moderator'])
public async handle(
{ auth, response }: HttpContextContract,
next: () => Promise<void>,
userRoles: string[]
) {
// Check if user is logged-in or not.
// let expression = "";
// if (Array.isArray(args)) {
// expression = args.join(" || ");
// }
let user = await auth.user;
if (!user) {
return response.unauthorized({ error: 'Must be logged in' });
}
let hasRole = await this.checkHasRoles(user, userRoles);
if (!hasRole) {
// return response.unauthorized({
// error: `Doesn't have required role(s): ${userRoles.join(',')}`,
// // error: `Doesn't have required role(s)`,
// });
throw new Exception(`Doesn't have required role(s): ${userRoles.join(',')}`, 401);
}
// code for middleware goes here. ABOVE THE NEXT CALL
await next();
}
private async checkHasRoles(user: User, userRoles: string[]): Promise<boolean> {
// await user.load("roles");
// const ok = user.roles.map((role) => role.name);
// const roles = await user.getRoles();
let rolePlaceHolder = '(';
let placeholders = new Array(userRoles.length).fill('?');
rolePlaceHolder += placeholders.join(',');
rolePlaceHolder += ')';
// const roles = await user
// .related('roles')
// .query()
// .count('*') // .select('name')
// .whereIn('name', userRoles);
// // .groupBy('name');
// select count(*) as roleCount
// from gba.roles
// inner join gba.link_accounts_roles
// on "roles"."id" = "link_accounts_roles"."role_id"
// where ("name" in ('administrator', 'editor')) and ("link_accounts_roles"."account_id" = 1)
let {
rows: {
0: { rolecount },
},
} = await Database.rawQuery(
'SELECT count("r"."id") as roleCount FROM ' +
roleTable +
' r INNER JOIN ' +
userRoleTable +
' ur ON r.id=ur.role_id WHERE "ur"."account_id"=? AND "r"."name" in ' +
rolePlaceHolder +
' LIMIT 1',
[user.id, ...userRoles]
);
return rolecount > 0;
}
}