From db680740b57a82bac90cb50b26b91395064dc4c0 Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Tue, 16 Aug 2022 16:06:31 +0200 Subject: [PATCH] feat: Create configs for server with ACP authorization --- config/default.json | 2 +- config/dynamic.json | 5 ++- config/file-acp.json | 40 +++++++++++++++++ config/file-no-setup.json | 5 ++- config/file.json | 2 +- config/ldp/authorization/acp.json | 45 +++++++++++++++++++ config/ldp/authorization/readers/acl.json | 4 +- config/ldp/authorization/readers/acp.json | 27 +++++++++++ .../ldp/authorization/readers/ownership.json | 1 - config/ldp/authorization/webacl.json | 6 ++- config/sparql-endpoint-no-setup.json | 5 ++- config/sparql-endpoint.json | 2 +- config/util/auxiliary/acr.json | 18 ++++++++ config/util/auxiliary/strategies/acl.json | 2 +- config/util/auxiliary/strategies/acr.json | 37 +++++++++++++++ ...iliaryReader.ts => AuthAuxiliaryReader.ts} | 41 +++++++++-------- src/authorization/OwnerPermissionReader.ts | 20 ++++----- src/index.ts | 2 +- ...er.test.ts => AuthAuxiliaryReader.test.ts} | 8 ++-- 19 files changed, 227 insertions(+), 45 deletions(-) create mode 100644 config/file-acp.json create mode 100644 config/ldp/authorization/acp.json create mode 100644 config/ldp/authorization/readers/acp.json create mode 100644 config/util/auxiliary/acr.json create mode 100644 config/util/auxiliary/strategies/acr.json rename src/authorization/{WebAclAuxiliaryReader.ts => AuthAuxiliaryReader.ts} (59%) rename test/unit/authorization/{WebAclAuxiliaryReader.test.ts => AuthAuxiliaryReader.test.ts} (93%) diff --git a/config/default.json b/config/default.json index 43ebb0d47..2be78b1b1 100644 --- a/config/default.json +++ b/config/default.json @@ -34,7 +34,7 @@ ], "@graph": [ { - "comment": "A Solid server that stores its resources in memory." + "comment": "A Solid server that stores its resources in memory and uses WAC for authorization." } ] } diff --git a/config/dynamic.json b/config/dynamic.json index 23c08c3ff..4c613ebb8 100644 --- a/config/dynamic.json +++ b/config/dynamic.json @@ -34,7 +34,10 @@ ], "@graph": [ { - "comment": "A multi-pod server that allows for the creation of dynamic pods through pod provisioning." + "comment": [ + "A Solid server that allows for the creation of dynamic pods through pod provisioning.", + "Dynamic pods each have their own Components.js configuration." + ] } ] } diff --git a/config/file-acp.json b/config/file-acp.json new file mode 100644 index 000000000..b63837436 --- /dev/null +++ b/config/file-acp.json @@ -0,0 +1,40 @@ +{ + "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^5.0.0/components/context.jsonld", + "import": [ + "css:config/app/main/default.json", + "css:config/app/init/default.json", + "css:config/app/setup/required.json", + "css:config/app/variables/default.json", + "css:config/http/handler/default.json", + "css:config/http/middleware/websockets.json", + "css:config/http/server-factory/websockets.json", + "css:config/http/static/default.json", + "css:config/identity/access/public.json", + "css:config/identity/email/default.json", + "css:config/identity/handler/default.json", + "css:config/identity/ownership/token.json", + "css:config/identity/pod/static.json", + "css:config/identity/registration/enabled.json", + "css:config/ldp/authentication/dpop-bearer.json", + "css:config/ldp/authorization/acp.json", + "css:config/ldp/handler/default.json", + "css:config/ldp/metadata-parser/default.json", + "css:config/ldp/metadata-writer/default.json", + "css:config/ldp/modes/default.json", + "css:config/storage/backend/file.json", + "css:config/storage/key-value/resource-store.json", + "css:config/storage/middleware/default.json", + "css:config/util/auxiliary/acr.json", + "css:config/util/identifiers/suffix.json", + "css:config/util/index/default.json", + "css:config/util/logging/winston.json", + "css:config/util/representation-conversion/default.json", + "css:config/util/resource-locker/file.json", + "css:config/util/variables/default.json" + ], + "@graph": [ + { + "comment": "A Solid server that stores its resources on disk and uses ACP for authorization." + } + ] +} diff --git a/config/file-no-setup.json b/config/file-no-setup.json index 69f4d167d..909a0d16d 100644 --- a/config/file-no-setup.json +++ b/config/file-no-setup.json @@ -34,7 +34,10 @@ ], "@graph": [ { - "comment": "A single-pod server that stores its resources on disk." + "comment": [ + "A Solid server that stores its resources on disk and uses WAC for authorization.", + "No setup is required and the root container is initialized to allow full access for everyone so make sure to change this." + ] } ] } diff --git a/config/file.json b/config/file.json index 59ba4f720..b2308bb5f 100644 --- a/config/file.json +++ b/config/file.json @@ -34,7 +34,7 @@ ], "@graph": [ { - "comment": "A Solid server that stores its resources on disk." + "comment": "A Solid server that stores its resources on disk and uses WAC for authorization." } ] } diff --git a/config/ldp/authorization/acp.json b/config/ldp/authorization/acp.json new file mode 100644 index 000000000..2b3ed750c --- /dev/null +++ b/config/ldp/authorization/acp.json @@ -0,0 +1,45 @@ +{ + "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^5.0.0/components/context.jsonld", + "import": [ + "css:config/ldp/authorization/readers/acp.json", + "css:config/ldp/authorization/readers/ownership.json" + ], + "@graph": [ + { + "comment": "Requests permissions on subject resources for auxiliary resources.", + "@id": "urn:solid-server:default:PermissionReader", + "@type": "AuxiliaryReader", + "auxiliaryStrategy": { "@id": "urn:solid-server:default:AuxiliaryStrategy" }, + "reader": { + "@type": "UnionPermissionReader", + "readers": [ + { + "comment": "This PermissionReader will be used to prevent external access to containers used for internal storage.", + "@id": "urn:solid-server:default:PathBasedReader", + "@type": "PathBasedReader", + "baseUrl": { "@id": "urn:solid-server:default:variable:baseUrl" } + }, + { + "@id": "urn:solid-server:default:OwnerPermissionReader", + "@type": "OwnerPermissionReader", + "authStrategy": { "@id": "urn:solid-server:default:AcrStrategy" } + }, + { + "comment": "Uses Web Access Control for authorization.", + "@id": "urn:solid-server:default:WrappedAcpReader" + } + ] + } + }, + { + "comment": "In case of ACP authorization the ACR resources determine authorization.", + "@id": "urn:solid-server:default:AuthResourceHttpHandler", + "@type": "RouterHandler", + "args_baseUrl": { "@id": "urn:solid-server:default:variable:baseUrl" }, + "args_targetExtractor": { "@id": "urn:solid-server:default:TargetExtractor" }, + "args_allowedMethods": [ "*" ], + "args_allowedPathNames": [ "^/.*\\.acr$" ], + "args_handler": { "@id": "urn:solid-server:default:LdpHandler" } + } + ] +} diff --git a/config/ldp/authorization/readers/acl.json b/config/ldp/authorization/readers/acl.json index 734ac42bf..68b4fdac7 100644 --- a/config/ldp/authorization/readers/acl.json +++ b/config/ldp/authorization/readers/acl.json @@ -16,8 +16,8 @@ { "comment": "Reinterprets Control permissions as Read/Write on the ACL document.", "@id": "urn:solid-server:default:WebAclAuxiliaryReader", - "@type": "WebAclAuxiliaryReader", - "aclStrategy": { "@id": "urn:solid-server:default:AclStrategy" }, + "@type": "AuthAuxiliaryReader", + "authStrategy": { "@id": "urn:solid-server:default:AclStrategy" }, "reader": { "@id": "urn:solid-server:default:WebAclReader" } }, { diff --git a/config/ldp/authorization/readers/acp.json b/config/ldp/authorization/readers/acp.json new file mode 100644 index 000000000..bf0564380 --- /dev/null +++ b/config/ldp/authorization/readers/acp.json @@ -0,0 +1,27 @@ +{ + "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^5.0.0/components/context.jsonld", + "@graph": [ + { + "comment": "Adds parent container checks needed for create/delete permissions.", + "@id": "urn:solid-server:default:WrappedAcpReader", + "@type": "ParentContainerReader", + "identifierStrategy": { "@id": "urn:solid-server:default:IdentifierStrategy" }, + "reader": { "@id": "urn:solid-server:default:AcrAuxiliaryReader" } + }, + { + "comment": "Reinterprets Control permissions as Read/Write on the ACR document.", + "@id": "urn:solid-server:default:AcrAuxiliaryReader", + "@type": "AuthAuxiliaryReader", + "authStrategy": { "@id": "urn:solid-server:default:AcrStrategy" }, + "reader": { "@id": "urn:solid-server:default:AcpReader" } + }, + { + "comment": "Reads out permissions from ACR documents for subject resources.", + "@id": "urn:solid-server:default:AcpReader", + "@type": "AcpReader", + "acrStrategy": { "@id": "urn:solid-server:default:AcrStrategy" }, + "acrStore": { "@id": "urn:solid-server:default:ResourceStore" }, + "identifierStrategy": { "@id": "urn:solid-server:default:IdentifierStrategy" } + } + ] +} diff --git a/config/ldp/authorization/readers/ownership.json b/config/ldp/authorization/readers/ownership.json index f3cee17d1..7fc569410 100644 --- a/config/ldp/authorization/readers/ownership.json +++ b/config/ldp/authorization/readers/ownership.json @@ -6,7 +6,6 @@ "@id": "urn:solid-server:default:OwnerPermissionReader", "@type": "OwnerPermissionReader", "accountStore": { "@id": "urn:solid-server:auth:password:AccountStore" }, - "aclStrategy": { "@id": "urn:solid-server:default:AclStrategy" }, "identifierStrategy": { "@id": "urn:solid-server:default:IdentifierStrategy" } } ] diff --git a/config/ldp/authorization/webacl.json b/config/ldp/authorization/webacl.json index 1c99d93ee..4a49ee4bd 100644 --- a/config/ldp/authorization/webacl.json +++ b/config/ldp/authorization/webacl.json @@ -19,7 +19,11 @@ "@type": "PathBasedReader", "baseUrl": { "@id": "urn:solid-server:default:variable:baseUrl" } }, - { "@id": "urn:solid-server:default:OwnerPermissionReader" }, + { + "@id": "urn:solid-server:default:OwnerPermissionReader", + "@type": "OwnerPermissionReader", + "authStrategy": { "@id": "urn:solid-server:default:AclStrategy" } + }, { "comment": "Uses Web Access Control for authorization.", "@id": "urn:solid-server:default:WrappedWebAclReader" diff --git a/config/sparql-endpoint-no-setup.json b/config/sparql-endpoint-no-setup.json index 442e54a63..1206054a8 100644 --- a/config/sparql-endpoint-no-setup.json +++ b/config/sparql-endpoint-no-setup.json @@ -35,8 +35,9 @@ "@graph": [ { "comment": [ - "A single-pod server that stores its resources in a SPARQL endpoint.", - "This server only supports RDF data. For this reason it can not use its resource store for internal key/value storage." + "A single-pod server that stores its resources in a SPARQL endpoint and uses WAC for authorization.", + "This server only supports RDF data. For this reason it can not use its resource store for internal key/value storage.", + "No setup is required and the root container is initialized to allow full access for everyone so make sure to change this." ] } ] diff --git a/config/sparql-endpoint.json b/config/sparql-endpoint.json index 139cd41b8..08fb27ffe 100644 --- a/config/sparql-endpoint.json +++ b/config/sparql-endpoint.json @@ -35,7 +35,7 @@ "@graph": [ { "comment": [ - "A Solid server that stores its resources in a SPARQL endpoint.", + "A Solid server that stores its resources in a SPARQL endpoint and uses WAC for authorization.", "This server only supports RDF data. For this reason it can not use its resource store for internal key/value storage." ] } diff --git a/config/util/auxiliary/acr.json b/config/util/auxiliary/acr.json new file mode 100644 index 000000000..07bc00001 --- /dev/null +++ b/config/util/auxiliary/acr.json @@ -0,0 +1,18 @@ +{ + "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^5.0.0/components/context.jsonld", + "import": [ + "css:config/util/auxiliary/strategies/acr.json", + "css:config/util/auxiliary/strategies/meta.json" + ], + "@graph": [ + { + "comment": "This will contain references to all the auxiliary strategies (such as the acr one) if they are needed.", + "@id": "urn:solid-server:default:AuxiliaryStrategy", + "@type": "RoutingAuxiliaryStrategy", + "sources": [ + { "@id": "urn:solid-server:default:AcrStrategy" }, + { "@id": "urn:solid-server:default:MetadataStrategy" } + ] + } + ] +} diff --git a/config/util/auxiliary/strategies/acl.json b/config/util/auxiliary/strategies/acl.json index 8f4e4dd27..2cc50006c 100644 --- a/config/util/auxiliary/strategies/acl.json +++ b/config/util/auxiliary/strategies/acl.json @@ -2,7 +2,7 @@ "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^5.0.0/components/context.jsonld", "@graph": [ { - "comment": "Contains all features of acl auxiliary resources (suffix, link header, etc.).", + "comment": "Contains all features of acl auxiliary resources (suffix, etc.).", "@id": "urn:solid-server:default:AclStrategy", "@type": "ComposedAuxiliaryStrategy", "identifierStrategy": { "@id": "urn:solid-server:default:AclIdentifierStrategy" }, diff --git a/config/util/auxiliary/strategies/acr.json b/config/util/auxiliary/strategies/acr.json new file mode 100644 index 000000000..923c93594 --- /dev/null +++ b/config/util/auxiliary/strategies/acr.json @@ -0,0 +1,37 @@ +{ + "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^5.0.0/components/context.jsonld", + "@graph": [ + { + "comment": "Contains all features of acr auxiliary resources (suffix, etc.).", + "@id": "urn:solid-server:default:AcrStrategy", + "@type": "ComposedAuxiliaryStrategy", + "identifierStrategy": { "@id": "urn:solid-server:default:AcrIdentifierStrategy" }, + "validator": { + "@type": "RdfValidator", + "converter": { "@id": "urn:solid-server:default:RepresentationConverter" } + }, + "ownAuthorization": true, + "requiredInRoot": true + }, + { + "@id": "urn:solid-server:default:AcrIdentifierStrategy", + "@type": "SuffixAuxiliaryIdentifierStrategy", + "suffix": ".acr" + }, + { + "comment": "Creates the Link header for the acr resources (which also use 'acl').", + "@id": "urn:solid-server:default:MetadataWriter_LinkRelAcr", + "@type": "AuxiliaryLinkMetadataWriter", + "auxiliaryStrategy": { "@id": "urn:solid-server:default:AuxiliaryStrategy" }, + "specificStrategy": { "@id": "urn:solid-server:default:AcrStrategy" }, + "relationType" : "acl" + }, + { + "@id": "urn:solid-server:default:MetadataWriter", + "@type": "ParallelHandler", + "handlers": [ + { "@id": "urn:solid-server:default:MetadataWriter_LinkRelAcr" } + ] + } + ] +} diff --git a/src/authorization/WebAclAuxiliaryReader.ts b/src/authorization/AuthAuxiliaryReader.ts similarity index 59% rename from src/authorization/WebAclAuxiliaryReader.ts rename to src/authorization/AuthAuxiliaryReader.ts index e6b53b321..08c263a58 100644 --- a/src/authorization/WebAclAuxiliaryReader.ts +++ b/src/authorization/AuthAuxiliaryReader.ts @@ -12,32 +12,36 @@ import type { AclPermission } from './permissions/AclPermission'; import type { AccessMap, AccessMode, PermissionMap, PermissionSet } from './permissions/Permissions'; /** - * Determines the permission for ACL auxiliary resources. - * This is done by looking for control permissions on the subject resource. + * Determines the permission for authorization resources (such as ACL or ACR). + * In contrast to the regular resource mechanism, read/write access to authorization resources + * is obtained by setting Control permissions on the corresponding subject resource + * rather than directly setting permissions for the authorization resource itself. + * Hence, this class transforms Control permissions on the subject resource + * to Read/Write permissions on the authorization resource. */ -export class WebAclAuxiliaryReader extends PermissionReader { +export class AuthAuxiliaryReader extends PermissionReader { protected readonly logger = getLoggerFor(this); private readonly reader: PermissionReader; - private readonly aclStrategy: AuxiliaryStrategy; + private readonly authStrategy: AuxiliaryStrategy; - public constructor(reader: PermissionReader, aclStrategy: AuxiliaryStrategy) { + public constructor(reader: PermissionReader, authStrategy: AuxiliaryStrategy) { super(); this.reader = reader; - this.aclStrategy = aclStrategy; + this.authStrategy = authStrategy; } public async handle({ requestedModes, credentials }: PermissionReaderInput): Promise { // Finds all the ACL identifiers - const aclMap = new Map(this.findAcl(requestedModes)); + const authMap = new Map(this.findAuth(requestedModes)); // Replaces the ACL identifies with the corresponding subject identifiers const updatedMap = modify(new IdentifierSetMultiMap(requestedModes), - { add: aclMap.values(), remove: aclMap.keys() }); + { add: authMap.values(), remove: authMap.keys() }); const result = await this.reader.handleSafe({ requestedModes: updatedMap, credentials }); - // Extracts the ACL permissions based on the subject control permissions - for (const [ identifier, [ subject ]] of aclMap) { + // Extracts the permissions based on the subject control permissions + for (const [ identifier, [ subject ]] of authMap) { this.logger.debug(`Mapping ${subject.path} control permission to all permissions for ${identifier.path}`); result.set(identifier, this.interpretControl(identifier, result.get(subject))); } @@ -45,12 +49,12 @@ export class WebAclAuxiliaryReader extends PermissionReader { } /** - * Finds all ACL identifiers and maps them to their subject identifier and the requested modes. + * Finds all authorization resource identifiers and maps them to their subject identifier and the requested modes. */ - private* findAcl(accessMap: AccessMap): Iterable<[ResourceIdentifier, MapEntry]> { + private* findAuth(accessMap: AccessMap): Iterable<[ResourceIdentifier, MapEntry]> { for (const [ identifier ] of accessMap) { - if (this.aclStrategy.isAuxiliaryIdentifier(identifier)) { - const subject = this.aclStrategy.getSubjectIdentifier(identifier); + if (this.authStrategy.isAuxiliaryIdentifier(identifier)) { + const subject = this.authStrategy.getSubjectIdentifier(identifier); // Unfortunately there is no enum inheritance so we have to cast like this yield [ identifier, [ subject, new Set([ AclMode.control ] as unknown as AccessMode[]) ]]; } @@ -58,19 +62,20 @@ export class WebAclAuxiliaryReader extends PermissionReader { } /** - * Updates the permissions for an ACL resource by interpreting the Control access mode as allowing full access. + * Updates the permissions for an authorization resource + * by interpreting the Control access mode as allowing full access. */ protected interpretControl(identifier: ResourceIdentifier, permissionSet: PermissionSet = {}): PermissionSet { - const aclSet: PermissionSet = {}; + const authSet: PermissionSet = {}; for (const [ group, permissions ] of Object.entries(permissionSet) as [ CredentialGroup, AclPermission ][]) { const { control } = permissions; - aclSet[group] = { + authSet[group] = { read: control, append: control, write: control, control, } as AclPermission; } - return aclSet; + return authSet; } } diff --git a/src/authorization/OwnerPermissionReader.ts b/src/authorization/OwnerPermissionReader.ts index 5a43ed888..a2ef68d92 100644 --- a/src/authorization/OwnerPermissionReader.ts +++ b/src/authorization/OwnerPermissionReader.ts @@ -21,23 +21,23 @@ export class OwnerPermissionReader extends PermissionReader { protected readonly logger = getLoggerFor(this); private readonly accountStore: AccountStore; - private readonly aclStrategy: AuxiliaryIdentifierStrategy; + private readonly authStrategy: AuxiliaryIdentifierStrategy; private readonly identifierStrategy: IdentifierStrategy; - public constructor(accountStore: AccountStore, aclStrategy: AuxiliaryIdentifierStrategy, + public constructor(accountStore: AccountStore, authStrategy: AuxiliaryIdentifierStrategy, identifierStrategy: IdentifierStrategy) { super(); this.accountStore = accountStore; - this.aclStrategy = aclStrategy; + this.authStrategy = authStrategy; this.identifierStrategy = identifierStrategy; } public async handle(input: PermissionReaderInput): Promise { const result: PermissionMap = new IdentifierMap(); const requestedResources = input.requestedModes.distinctKeys(); - const acls = [ ...filter(requestedResources, (id): boolean => this.aclStrategy.isAuxiliaryIdentifier(id)) ]; - if (acls.length === 0) { - this.logger.debug(`No ACL resources found that need an ownership check.`); + const auths = [ ...filter(requestedResources, (id): boolean => this.authStrategy.isAuxiliaryIdentifier(id)) ]; + if (auths.length === 0) { + this.logger.debug(`No authorization resources found that need an ownership check.`); return result; } @@ -49,10 +49,10 @@ export class OwnerPermissionReader extends PermissionReader { return result; } - for (const acl of acls) { - if (this.identifierStrategy.contains(podBaseUrl, acl, true)) { - this.logger.debug(`Granting Control permissions to owner on ${acl.path}`); - result.set(acl, { [CredentialGroup.agent]: { + for (const auth of auths) { + if (this.identifierStrategy.contains(podBaseUrl, auth, true)) { + this.logger.debug(`Granting Control permissions to owner on ${auth.path}`); + result.set(auth, { [CredentialGroup.agent]: { read: true, write: true, append: true, diff --git a/src/index.ts b/src/index.ts index 0ca8ff2bb..9e99e1402 100644 --- a/src/index.ts +++ b/src/index.ts @@ -35,7 +35,7 @@ export * from './authorization/PathBasedReader'; export * from './authorization/PermissionBasedAuthorizer'; export * from './authorization/PermissionReader'; export * from './authorization/UnionPermissionReader'; -export * from './authorization/WebAclAuxiliaryReader'; +export * from './authorization/AuthAuxiliaryReader'; export * from './authorization/WebAclReader'; // HTTP/Auxiliary diff --git a/test/unit/authorization/WebAclAuxiliaryReader.test.ts b/test/unit/authorization/AuthAuxiliaryReader.test.ts similarity index 93% rename from test/unit/authorization/WebAclAuxiliaryReader.test.ts rename to test/unit/authorization/AuthAuxiliaryReader.test.ts index 379c1327a..eea4baa6c 100644 --- a/test/unit/authorization/WebAclAuxiliaryReader.test.ts +++ b/test/unit/authorization/AuthAuxiliaryReader.test.ts @@ -1,16 +1,16 @@ import type { CredentialSet } from '../../../src/authentication/Credentials'; +import { AuthAuxiliaryReader } from '../../../src/authorization/AuthAuxiliaryReader'; import type { PermissionReader } from '../../../src/authorization/PermissionReader'; import { AclMode } from '../../../src/authorization/permissions/AclPermission'; import type { AccessMap, PermissionMap, PermissionSet } from '../../../src/authorization/permissions/Permissions'; import { AccessMode } from '../../../src/authorization/permissions/Permissions'; -import { WebAclAuxiliaryReader } from '../../../src/authorization/WebAclAuxiliaryReader'; import type { AuxiliaryStrategy } from '../../../src/http/auxiliary/AuxiliaryStrategy'; import type { ResourceIdentifier } from '../../../src/http/representation/ResourceIdentifier'; import { IdentifierMap, IdentifierSetMultiMap } from '../../../src/util/map/IdentifierMap'; import { joinUrl } from '../../../src/util/PathUtil'; import { compareMaps } from '../../util/Util'; -describe('A WebAclAuxiliaryReader', (): void => { +describe('An AuthAuxiliaryReader', (): void => { const baseUrl = 'http://example.com/'; const subject1 = { path: joinUrl(baseUrl, 'foo/') }; const acl1 = { path: joinUrl(subject1.path, '.acl') }; @@ -21,7 +21,7 @@ describe('A WebAclAuxiliaryReader', (): void => { let sourceResult: PermissionMap; let aclStrategy: jest.Mocked; let source: jest.Mocked; - let reader: WebAclAuxiliaryReader; + let reader: AuthAuxiliaryReader; beforeEach(async(): Promise => { requestedModes = new IdentifierSetMultiMap(); @@ -34,7 +34,7 @@ describe('A WebAclAuxiliaryReader', (): void => { } as any; source = { handleSafe: jest.fn().mockResolvedValue(sourceResult) } as any; - reader = new WebAclAuxiliaryReader(source, aclStrategy); + reader = new AuthAuxiliaryReader(source, aclStrategy); }); it('requires control permissions on the subject resource to do everything.', async(): Promise => {