import { Enforcer } from 'casbin' ; import { Request , Response , NextFunction } from 'express' ; export interface Authorizer { checkPermission ( ) : Promise < boolean > ; } interface AuthorizerConstructor { new ( req , res , enforcer ) : Authorizer ; } class BasicAuthorizer implements Authorizer { req : Request ; res : Response ; enforcer : Enforcer ; constructor ( req , res , enforcer ) { this . req = req ; this . res = res ; this . enforcer = enforcer ; } getUserName ( ) { if ( this . res . locals . username != undefined ) return this . res . locals . username ; try { const header = this . req . get ( 'Authorization' ) ; if ( ! header ) return '' ; const arr = header . split ( ' ' ) ; if ( arr [ 0 ] . trim ( ) != 'Basic' ) return '' ; const value = Buffer . from ( arr [ 1 ] , 'base64' ) . toString ( 'ascii' ) ; const tempArr = value . split ( ':' ) ; return tempArr [ 0 ] ; } catch ( e ) { console . log ( e ) ; return '' ; } } async checkPermission ( ) { const { req , enforcer } = this ; const { originalUrl : path , method } = req ; const user = this . getUserName ( ) ; return enforcer . enforce ( user , path , method ) ; } } interface AuthzOptions { newEnforcer : Promise < Enforcer > ; authorizer ? : Authorizer | AuthorizerConstructor ; } export function authz ( opt ) { return async ( req , res , next ) : Promise < void > => { const enforcer = await opt . newEnforcer ; if ( ! ( enforcer instanceof Enforcer ) ) { res . status ( 500 ) . json ( { 500 : 'Invalid enforcer' } ) ; return ; } const authorizer = opt . authorizer ? ( typeof opt . authorizer === 'function' ? new opt . authorizer ( req , res , enforcer ) : opt . authorizer ) : new BasicAuthorizer ( req , res , enforcer ) ; const isAllowed = await authorizer . checkPermission ( ) ; if ( ! isAllowed ) { res . status ( 403 ) . json ( { 403 : 'Forbidden' } ) ; return ; } next ( ) ; } ; }