import { Inject , Service , EventManager } from "@bluelibs/core" ; import { PermissionGraph } from "./PermissionGraph" ; import { UserBeforeRemovePermissionEvent , UserAfterRemovePermissionEvent , } from "../events" ; import { UserBeforeAddPermissionEvent , UserAfterAddPermissionEvent , } from "../events" ; import { IPermissionPersistance , IPermissionService , IPermission , IPermissionSearchFilter , IPermissionSearchFilters , UserId , } from "../defs" ; import { PERMISSION_DEFAULT_DOMAIN , PERMISSION_PERSISTANCE_LAYER , } from "../constants" ; import { SecurityService } from "./SecurityService" ; @ Service ( ) export class PermissionService implements IPermissionService { constructor ( @ Inject ( PERMISSION_PERSISTANCE_LAYER ) public readonly persistance , public readonly permissionGraph , protected readonly eventManager , protected readonly securityService ) { } async has ( filter ) { if ( filter . userId === null || filter . userId === undefined ) { throw new Error ( `You are required to provide an 'userId' to be able to verify permissions.` ) ; } const filters = this . transformToFilters ( filter ) ; const permissions = filters . permission ; if ( filters . permission ) { const parentPermissions = this . permissionGraph . getParentRolesOf ( filters . permission ) ; permissions . push ( ... parentPermissions ) ; } /**
         * We treat roles as "app" level roles that are very simple to use.
         */ if ( filter . domain === PERMISSION_DEFAULT_DOMAIN && filter . userId ) { if ( Array . isArray ( filter . userId ) ) { } else { const roles = await this . securityService . getRoles ( filter . userId as UserId ) ; if ( roles . length ) { if ( permissions . some ( ( permission ) => roles . includes ( permission ) ) ) { return true ; } } } } const result = await this . persistance . countPermissions ( { userId : filters . userId , permission : permissions , domain : filters . domain , domainIdentifier : filters . domainIdentifier , } ) ; return result > 0 ; } param userId param roles returns async hasRole ( userId , roles ) { return this . has ( { userId , domain : PERMISSION_DEFAULT_DOMAIN , permission : roles , } ) ; } async add ( permission ) { await this . eventManager . emit ( new UserBeforeAddPermissionEvent ( { permission , } ) ) ; await this . persistance . insertPermission ( permission ) ; await this . eventManager . emit ( new UserAfterAddPermissionEvent ( { permission , } ) ) ; } async remove ( filter ) { const filters = this . transformToFilters ( filter ) ; await this . eventManager . emit ( new UserBeforeRemovePermissionEvent ( { filters , } ) ) ; await this . persistance . removePermission ( filters ) ; await this . eventManager . emit ( new UserAfterRemovePermissionEvent ( { filters , } ) ) ; } /**
     * Search permissions
     */ async findPermissions ( search = { } ) { const newSearch = this . transformToFilters ( search ) ; return this . persistance . findPermissions ( newSearch ) ; } /**
     * Finds a single permission
     */ async findPermission ( search = { } ) { const newSearch = this . transformToFilters ( search ) ; return this . persistance . findPermission ( newSearch ) ; } param object protected transformToFilters ( object ) { const newObject = { } ; [ "userId" , "permission" , "domain" , "domainIdentifier" ] . forEach ( ( key ) => { if ( object [ key ] ) { newObject [ key ] = Array . isArray ( object [ key ] ) ? object [ key ] : [ object [ key ] ] ; } } ) ; return newObject ; } param userId async findDomains ( userId ) { return this . persistance . findDomains ( userId ) ; } }