import { HttpContext } from '@adonisjs/core/http'; // import Config from '@ioc:Adonis/Core/Config'; import config from '@adonisjs/core/services/config' import db from '@adonisjs/lucid/services/db'; import User from '#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 }: HttpContext, 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(); return 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 db.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; } }