import { BindingAddress , ClassDecoratorFactory , DecoratorFactory , MetadataAccessor , MetadataInspector , MetadataMap , MethodDecoratorFactory , } from '@loopback/core' ; import { AUTHENTICATED , AuthorizationMetadata , Authorizer , EVERYONE , UNAUTHENTICATED , } from '../types' ; export const AUTHORIZATION_METHOD_KEY = MetadataAccessor . create < AuthorizationMetadata , MethodDecorator > ( 'authorization:method' ) ; export const AUTHORIZATION_CLASS_KEY = MetadataAccessor . create < AuthorizationMetadata , ClassDecorator > ( 'authorization:class' ) ; class AuthorizeClassDecoratorFactory extends ClassDecoratorFactory < AuthorizationMetadata > { } export class AuthorizeMethodDecoratorFactory extends MethodDecoratorFactory < AuthorizationMetadata > { protected mergeWithOwn ( ownMetadata , target , methodName ? , methodDescriptor ? ) { ownMetadata = ownMetadata || { } ; let methodMeta = ownMetadata [ methodName ! ] ; if ( ! methodMeta ) { methodMeta = { ... this . spec } ; ownMetadata [ methodName ! ] = methodMeta ; } if ( this . spec . allowedRoles ) { methodMeta . allowedRoles = this . merge ( methodMeta . allowedRoles , this . spec . allowedRoles ) ; } if ( this . spec . deniedRoles ) { methodMeta . deniedRoles = this . merge ( methodMeta . deniedRoles , this . spec . deniedRoles ) ; } if ( this . spec . scopes ) { methodMeta . scopes = this . merge ( methodMeta . scopes , this . spec . scopes ) ; } if ( this . spec . voters ) { methodMeta . voters = this . merge ( methodMeta . voters , this . spec . voters ) ; } return ownMetadata ; } private merge < T > ( src ? , target ? ) { const list = [ ] ; if ( src === target ) return src ?? list ; const set = new Set < T > ( src ?? [ ] ) ; if ( target ) { for ( const i of target ) { set . add ( i ) ; } } for ( const i of set . values ( ) ) list . push ( i ) ; return list ; } } param spec export function authorize ( spec ) { return function authorizeDecoratorForClassOrMethod ( target , method ? , methodDescriptor ? ) { if ( method && methodDescriptor ) { return AuthorizeMethodDecoratorFactory . createDecorator ( AUTHORIZATION_METHOD_KEY , spec , { decoratorName : '@authorize' } ) ( target , method , methodDescriptor ! ) ; } if ( typeof target === 'function' && ! method && ! methodDescriptor ) { return AuthorizeClassDecoratorFactory . createDecorator ( AUTHORIZATION_CLASS_KEY , spec , { decoratorName : '@authorize' } ) ( target ) ; } throw new Error ( '@intercept cannot be used on a property: ' + DecoratorFactory . getTargetName ( target , method , methodDescriptor ) ) ; } ; } export namespace authorize { param roles export const allow = ( ... roles ) => authorize ( { allowedRoles : roles } ) ; param roles export const deny = ( ... roles ) => authorize ( { deniedRoles : roles } ) ; param scopes export const scope = ( ... scopes ) => authorize ( { scopes } ) ; param voters export const vote = ( ... voters ) => authorize ( { voters } ) ; /**
     * Allows all
     */ export const allowAll = ( ) => allow ( EVERYONE ) ; param roles export const allowAllExcept = ( ... roles ) => authorize ( { deniedRoles : roles , allowedRoles : [ EVERYONE ] , } ) ; /**
     * Deny all
     */ export const denyAll = ( ) => deny ( EVERYONE ) ; param roles export const denyAllExcept = ( ... roles ) => authorize ( { allowedRoles : roles , deniedRoles : [ EVERYONE ] , } ) ; /**
     * Allow authenticated users
     */ export const allowAuthenticated = ( ) => allow ( AUTHENTICATED ) ; /**
     * Deny unauthenticated users
     */ export const denyUnauthenticated = ( ) => deny ( UNAUTHENTICATED ) ; /**
     * Skip authorization
     */ export const skip = ( ) => authorize ( { skip : true } ) ; } param target param methodName export function getAuthorizationMetadata ( target , methodName ) { let targetClass ; if ( typeof target === 'function' ) { targetClass = target ; target = target . prototype ; } else { targetClass = target . constructor ; } const metadata = MetadataInspector . getMethodMetadata < AuthorizationMetadata > ( AUTHORIZATION_METHOD_KEY , target , methodName ) ; if ( metadata ) return metadata ; return MetadataInspector . getClassMetadata < AuthorizationMetadata > ( AUTHORIZATION_CLASS_KEY , targetClass ) ; }