From 564990322630c5b8ff0180efbd2839bc5210569c Mon Sep 17 00:00:00 2001 From: Ruben Taelman Date: Tue, 25 Aug 2020 11:11:29 +0200 Subject: [PATCH] fix: Move ACL init into dedicated Setup component --- bin/server.ts | 37 ++-------------------- index.ts | 3 ++ src/init/Setup.ts | 61 ++++++++++++++++++++++++++++++++++++ test/unit/init/Setup.test.ts | 31 ++++++++++++++++++ 4 files changed, 98 insertions(+), 34 deletions(-) create mode 100644 src/init/Setup.ts create mode 100644 test/unit/init/Setup.test.ts diff --git a/bin/server.ts b/bin/server.ts index 6408ddb74..acfaeaeb1 100644 --- a/bin/server.ts +++ b/bin/server.ts @@ -1,6 +1,4 @@ #!/usr/bin/env node -import { DATA_TYPE_BINARY } from '../src/util/ContentTypes'; -import streamifyArray from 'streamify-array'; import yargs from 'yargs'; import { AcceptPreferenceParser, @@ -13,6 +11,7 @@ import { QuadToTurtleConverter, Representation, RepresentationConvertingStore, + Setup, SimpleAclAuthorizer, SimpleBodyParser, SimpleCredentialsExtractor, @@ -98,38 +97,8 @@ const httpHandler = new AuthenticatedLdpHandler({ const httpServer = new ExpressHttpServer(httpHandler); -// Set up acl so everything can still be done by default -// Note that this will need to be adapted to go through all the correct channels later on -const aclSetup = async(): Promise => { - const acl = `@prefix acl: . -@prefix foaf: . - -<#authorization> - a acl:Authorization; - acl:agentClass foaf:Agent; - acl:mode acl:Read; - acl:mode acl:Write; - acl:mode acl:Append; - acl:mode acl:Delete; - acl:mode acl:Control; - acl:accessTo <${base}>; - acl:default <${base}>.`; - await store.setRepresentation( - await aclManager.getAcl({ path: base }), - { - dataType: DATA_TYPE_BINARY, - data: streamifyArray([ acl ]), - metadata: { - raw: [], - profiles: [], - contentType: 'text/turtle', - }, - }, - ); -}; -aclSetup().then((): void => { - httpServer.listen(port); - +const setup = new Setup(httpServer, store, aclManager); +setup.setup(port, base).then((): void => { process.stdout.write(`Running at ${base}\n`); }).catch((error): void => { process.stderr.write(`${error}\n`); diff --git a/index.ts b/index.ts index a811b8483..7b57a8b8d 100644 --- a/index.ts +++ b/index.ts @@ -10,6 +10,9 @@ export * from './src/authorization/SimpleAclAuthorizer'; export * from './src/authorization/SimpleAuthorizer'; export * from './src/authorization/SimpleExtensionAclManager'; +// Init +export * from './src/init/Setup'; + // LDP/HTTP export * from './src/ldp/http/AcceptPreferenceParser'; export * from './src/ldp/http/BodyParser'; diff --git a/src/init/Setup.ts b/src/init/Setup.ts new file mode 100644 index 000000000..9aa3d9a18 --- /dev/null +++ b/src/init/Setup.ts @@ -0,0 +1,61 @@ +import { AclManager } from '../authorization/AclManager'; +import { DATA_TYPE_BINARY } from '../util/ContentTypes'; +import { ExpressHttpServer } from '../server/ExpressHttpServer'; +import { ResourceStore } from '../storage/ResourceStore'; +import streamifyArray from 'streamify-array'; + +/** + * Invokes all logic to setup a server. + */ +export class Setup { + private readonly httpServer: ExpressHttpServer; + private readonly store: ResourceStore; + private readonly aclManager: AclManager; + + public constructor(httpServer: ExpressHttpServer, store: ResourceStore, aclManager: AclManager) { + this.httpServer = httpServer; + this.store = store; + this.aclManager = aclManager; + } + + /** + * Set up a server at the given port and base URL. + * @param port - A port number. + * @param base - A base URL. + */ + public async setup(port: number, base: string): Promise { + // Set up acl so everything can still be done by default + // Note that this will need to be adapted to go through all the correct channels later on + const aclSetup = async(): Promise => { + const acl = `@prefix acl: . +@prefix foaf: . + +<#authorization> + a acl:Authorization; + acl:agentClass foaf:Agent; + acl:mode acl:Read; + acl:mode acl:Write; + acl:mode acl:Append; + acl:mode acl:Delete; + acl:mode acl:Control; + acl:accessTo <${base}>; + acl:default <${base}>.`; + await this.store.setRepresentation( + await this.aclManager.getAcl({ path: base }), + { + dataType: DATA_TYPE_BINARY, + data: streamifyArray([ acl ]), + metadata: { + raw: [], + profiles: [], + contentType: 'text/turtle', + }, + }, + ); + }; + + await aclSetup(); + + this.httpServer.listen(port); + } +} diff --git a/test/unit/init/Setup.test.ts b/test/unit/init/Setup.test.ts new file mode 100644 index 000000000..230c70901 --- /dev/null +++ b/test/unit/init/Setup.test.ts @@ -0,0 +1,31 @@ +import { Setup } from '../../../src/init/Setup'; + +describe('Setup', (): void => { + let httpServer: any; + let store: any; + let aclManager: any; + let setup: Setup; + beforeEach(async(): Promise => { + store = { + setRepresentation: jest.fn(async(): Promise => undefined), + }; + aclManager = { + getAcl: jest.fn(async(): Promise => undefined), + }; + httpServer = { + listen: jest.fn(), + }; + setup = new Setup(httpServer, store, aclManager); + }); + + it('starts an HTTP server.', async(): Promise => { + await setup.setup(3000, 'http://localhost:3000/'); + expect(httpServer.listen).toHaveBeenCalledWith(3000); + }); + + it('invokes ACL initialization.', async(): Promise => { + await setup.setup(3000, 'http://localhost:3000/'); + expect(aclManager.getAcl).toHaveBeenCalledWith({ path: 'http://localhost:3000/' }); + expect(store.setRepresentation).toHaveBeenCalledTimes(1); + }); +});