import { AuthenticationRequiredError , MissingRoleError , NoUserCorrespondingToIdpUserError , } from "../common/errors" ; import IUsersStorage from "../dependencies/IUsersStorage" ; import { oneOfRolesMatchesRole , RoleName , RoleTuple } from "../entities/Role" ; import { IUser , IUserWithRoles } from "../entities/User" ; import Authenticator from "./Authenticator" ; export default class Authorizer { private currentUser : IUserWithRoles | null = null ; constructor ( private users , private authenticator , private enforceAuth ) { } async canSeeHealtCheckDetails ( ) { try { await this . ensureAuthenticated ( ) ; return true ; } catch { return false ; } } async getCurrentUser ( ) { await this . ensureAuthenticated ( ) ; return this . currentUser ; } ensureCanCreateApp ( ) { return this . ensureAuthorized ( ( ) => this . matchesRole ( [ RoleName . Root ] ) ) ; } ensureCanUpdateApp ( appName ) { return this . ensureAuthorized ( ( ) => this . matchesRole ( [ RoleName . Root ] ) || this . matchesRole ( [ RoleName . AppManager , appName ] ) ) ; } ensureCanDeleteApp ( appName ) { return this . ensureAuthorized ( ( ) => this . matchesRole ( [ RoleName . Root ] ) || this . matchesRole ( [ RoleName . AppManager , appName ] ) ) ; } ensureCanGetApps ( ) { return this . ensureAuthenticated ( ) ; } ensureCanCreateBundle ( bundleName ) { return this . ensureAuthorized ( ( ) => this . matchesRole ( [ RoleName . Root ] ) || this . matchesRole ( [ RoleName . BundleManager , bundleName ] ) ) ; } ensureCanDeleteBundles ( bundlesName ) { return this . ensureAuthorized ( ( ) => this . matchesRole ( [ RoleName . Root ] ) || this . matchesRole ( [ RoleName . BundleManager , bundlesName ] ) ) ; } ensureCanGetBundles ( ) { return this . ensureAuthenticated ( ) ; } ensureCanCreateEntrypoint ( entrypointUrlMatcher , entrypointAppName ) { return this . ensureAuthorized ( ( ) => this . matchesRole ( [ RoleName . Root ] ) || ( this . matchesRole ( [ RoleName . AppManager , entrypointAppName ] ) && this . matchesRole ( [ RoleName . EntrypointManager , entrypointUrlMatcher , ] ) ) ) ; } ensureCanUpdateEntrypoint ( entrypointUrlMatcher ) { return this . ensureAuthorized ( ( ) => this . matchesRole ( [ RoleName . Root ] ) || this . matchesRole ( [ RoleName . EntrypointManager , entrypointUrlMatcher , ] ) ) ; } ensureCanDeleteEntrypoint ( entrypointUrlMatcher ) { return this . ensureAuthorized ( ( ) => this . matchesRole ( [ RoleName . Root ] ) || this . matchesRole ( [ RoleName . EntrypointManager , entrypointUrlMatcher , ] ) ) ; } ensureCanGetEntrypoints ( ) { return this . ensureAuthenticated ( ) ; } ensureCanCreateGroup ( ) { return this . ensureAuthorized ( ( ) => this . matchesRole ( [ RoleName . Root ] ) ) ; } ensureCanUpdateGroup ( ) { return this . ensureAuthorized ( ( ) => this . matchesRole ( [ RoleName . Root ] ) ) ; } ensureCanDeleteGroup ( ) { return this . ensureAuthorized ( ( ) => this . matchesRole ( [ RoleName . Root ] ) ) ; } ensureCanGetGroups ( ) { return this . ensureAuthenticated ( ) ; } ensureCanGetOperationLogs ( ) { return this . ensureAuthenticated ( ) ; } ensureCanCreateUser ( ) { return this . ensureAuthorized ( ( ) => this . matchesRole ( [ RoleName . Root ] ) ) ; } ensureCanUpdateUser ( ) { return this . ensureAuthorized ( ( ) => this . matchesRole ( [ RoleName . Root ] ) ) ; } ensureCanDeleteUser ( ) { return this . ensureAuthorized ( ( ) => this . matchesRole ( [ RoleName . Root ] ) ) ; } ensureCanGetUsers ( ) { return this . ensureAuthenticated ( ) ; } private async ensureAuthenticated ( ) { if ( ! this . enforceAuth || this . currentUser ) { return ; } const idpUser = await this . authenticator . getIdpUser ( ) ; if ( ! idpUser ) { throw new AuthenticationRequiredError ( ) ; } this . currentUser = await this . users . findOneWithRolesByIdpAndIdpId ( idpUser . idp , idpUser . id ) ; if ( ! this . currentUser ) { throw new NoUserCorrespondingToIdpUserError ( idpUser ) ; } } private async ensureAuthorized ( hasRequiredRoles ) { if ( ! this . enforceAuth ) { return ; } await this . ensureAuthenticated ( ) ; if ( hasRequiredRoles && ! hasRequiredRoles ( ) ) { throw new MissingRoleError ( ) ; } } private matchesRole ( targetRole ) { return oneOfRolesMatchesRole ( this . currentUser ! . roles , targetRole ) ; } }