import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'; import Config from '@ioc:Adonis/Core/Config'; import Database from '@ioc:Adonis/Lucid/Database'; 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', 'user_roles'); /** * Role authentication to check if user has any of the specified roles * * Should be called after auth middleware */ export default class Is { /** * Handle request */ public async handle({ auth, response }: HttpContextContract, next: () => Promise, roleNames: string[]) { /** * Check if user is logged-in or not. */ let user = await auth.user; if (!user) { return response.unauthorized({ error: 'Must be logged in' }); } let hasRole = await this.checkHasRoles(user, roleNames); if (!hasRole) { return response.unauthorized({ error: `Doesn't have required role(s): ${roleNames.join(',')}`, }); // return new Exception(`Doesn't have required role(s): ${roleNames.join(',')}`, // 401, // "E_INVALID_AUTH_UID"); } await next(); } private async checkHasRoles(user: User, roleNames: Array): Promise { let rolePlaceHolder = '('; let placeholders = new Array(roleNames.length).fill('?'); rolePlaceHolder += placeholders.join(','); rolePlaceHolder += ')'; let { 0: { 0: { roleCount }, }, } = await Database.rawQuery( 'SELECT count(`ur`.`id`) as roleCount FROM ' + userRoleTable + ' ur INNER JOIN ' + roleTable + ' r ON ur.role_id=r.id WHERE `ur`.`user_id`=? AND `r`.`name` in ' + rolePlaceHolder + ' LIMIT 1', [user.id, ...roleNames], ); return roleCount > 0; } }