From 1a043aca3f1ca828ee1cb28b97b510ccd15bb965 Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Fri, 27 Nov 2020 13:46:53 +0100 Subject: [PATCH] feat: integrate pod creation --- config/config-default.json | 1 + config/config-file.json | 1 + config/config-path-routing.json | 1 + config/config-rdf-to-sparql-endpoint.json | 1 + config/config-sparql-endpoint.json | 1 + config/presets/cli-params.json | 4 ++ config/presets/http.json | 3 ++ config/presets/pod-management.json | 51 +++++++++++++++++++++ index.ts | 18 ++++++++ src/init/CliRunner.ts | 3 ++ templates/.acl | 26 +++++++++++ templates/profile/card$.ttl | 10 ++++ test/configs/middleware.json | 4 ++ test/configs/websockets.json | 1 + test/integration/Middleware.test.ts | 1 + test/integration/WebSocketsProtocol.test.ts | 1 + test/unit/init/CliRunner.test.ts | 5 ++ 17 files changed, 132 insertions(+) create mode 100644 config/presets/pod-management.json create mode 100644 templates/.acl create mode 100644 templates/profile/card$.ttl diff --git a/config/config-default.json b/config/config-default.json index 0940ce089..08451604a 100644 --- a/config/config-default.json +++ b/config/config-default.json @@ -13,6 +13,7 @@ "files-scs:config/presets/ldp/websockets.json", "files-scs:config/presets/logging.json", "files-scs:config/presets/middleware.json", + "files-scs:config/presets/pod-management.json", "files-scs:config/presets/representation-conversion.json", "files-scs:config/presets/setup.json", "files-scs:config/presets/storage/backend/storage-memory.json", diff --git a/config/config-file.json b/config/config-file.json index fe93fb6c2..e06692afc 100644 --- a/config/config-file.json +++ b/config/config-file.json @@ -13,6 +13,7 @@ "files-scs:config/presets/ldp/websockets.json", "files-scs:config/presets/logging.json", "files-scs:config/presets/middleware.json", + "files-scs:config/presets/pod-management.json", "files-scs:config/presets/representation-conversion.json", "files-scs:config/presets/setup.json", "files-scs:config/presets/storage/backend/storage-filesystem.json", diff --git a/config/config-path-routing.json b/config/config-path-routing.json index 7d9d4423a..e7f9dcbbd 100644 --- a/config/config-path-routing.json +++ b/config/config-path-routing.json @@ -13,6 +13,7 @@ "files-scs:config/presets/ldp/websockets.json", "files-scs:config/presets/logging.json", "files-scs:config/presets/middleware.json", + "files-scs:config/presets/pod-management.json", "files-scs:config/presets/representation-conversion.json", "files-scs:config/presets/setup.json", "files-scs:config/presets/storage/backend/storage-filesystem.json", diff --git a/config/config-rdf-to-sparql-endpoint.json b/config/config-rdf-to-sparql-endpoint.json index 8671d54fa..e27450b64 100644 --- a/config/config-rdf-to-sparql-endpoint.json +++ b/config/config-rdf-to-sparql-endpoint.json @@ -13,6 +13,7 @@ "files-scs:config/presets/ldp/websockets.json", "files-scs:config/presets/logging.json", "files-scs:config/presets/middleware.json", + "files-scs:config/presets/pod-management.json", "files-scs:config/presets/representation-conversion.json", "files-scs:config/presets/setup.json", "files-scs:config/presets/storage/backend/storage-filesystem.json", diff --git a/config/config-sparql-endpoint.json b/config/config-sparql-endpoint.json index 945f5b254..e43705dcf 100644 --- a/config/config-sparql-endpoint.json +++ b/config/config-sparql-endpoint.json @@ -13,6 +13,7 @@ "files-scs:config/presets/ldp/websockets.json", "files-scs:config/presets/logging.json", "files-scs:config/presets/middleware.json", + "files-scs:config/presets/pod-management.json", "files-scs:config/presets/representation-conversion.json", "files-scs:config/presets/setup.json", "files-scs:config/presets/storage/backend/storage-sparql-endpoint.json", diff --git a/config/presets/cli-params.json b/config/presets/cli-params.json index 260b76994..d5541b452 100644 --- a/config/presets/cli-params.json +++ b/config/presets/cli-params.json @@ -20,6 +20,10 @@ { "@id": "urn:solid-server:default:variable:loggingLevel", "@type": "Variable" + }, + { + "@id": "urn:solid-server:default:variable:podTemplateFolder", + "@type": "Variable" } ] } diff --git a/config/presets/http.json b/config/presets/http.json index d960bbe1b..108128927 100644 --- a/config/presets/http.json +++ b/config/presets/http.json @@ -25,6 +25,9 @@ { "@id": "urn:solid-server:default:Middleware" }, + { + "@id": "urn:solid-server:default:PodManagerHandler" + }, { "@id": "urn:solid-server:default:LdpHandler" } diff --git a/config/presets/pod-management.json b/config/presets/pod-management.json new file mode 100644 index 000000000..8df51e85a --- /dev/null +++ b/config/presets/pod-management.json @@ -0,0 +1,51 @@ +{ + "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^1.0.0/components/context.jsonld", + "@graph": [ + { + "@id": "urn:solid-server:default:ResourcesGenerator", + "@type": "TemplatedResourcesGenerator", + "TemplatedResourcesGenerator:_templateFolder": { + "@id": "urn:solid-server:default:variable:podTemplateFolder" + }, + "TemplatedResourcesGenerator:_factory": { + "@type": "ExtensionBasedMapperFactory" + }, + "TemplatedResourcesGenerator:_engine": { + "@type": "HandlebarsTemplateEngine" + } + }, + { + "@id": "urn:solid-server:default:PodManager", + "@type": "GeneratedPodManager", + "GeneratedPodManager:_store": { + "@id": "urn:solid-server:default:ResourceStore" + }, + "GeneratedPodManager:_idGenerator": { + "@type": "SuffixIdentifierGenerator", + "SuffixIdentifierGenerator:_base": { + "@id": "urn:solid-server:default:variable:baseUrl" + } + }, + "GeneratedPodManager:_resourcesGenerator": { + "@id": "urn:solid-server:default:ResourcesGenerator" + } + }, + { + "@id": "urn:solid-server:default:PodManagerHandler", + "@type": "PodManagerHttpHandler", + "PodManagerHttpHandler:_args_requestPath": "/pods", + "PodManagerHttpHandler:_args_requestParser": { + "@id": "urn:solid-server:default:RequestParser" + }, + "PodManagerHttpHandler:_args_agentParser": { + "@type": "AgentJsonParser" + }, + "PodManagerHttpHandler:_args_manager": { + "@id": "urn:solid-server:default:PodManager" + }, + "PodManagerHttpHandler:_args_responseWriter": { + "@id": "urn:solid-server:default:ResponseWriter" + } + } + ] +} diff --git a/index.ts b/index.ts index fd960e730..fe7732544 100644 --- a/index.ts +++ b/index.ts @@ -86,6 +86,24 @@ export * from './src/logging/LogUtil'; export * from './src/logging/VoidLoggerFactory'; export * from './src/logging/WinstonLoggerFactory'; +// Pods/Agent +export * from './src/pods/agent/Agent'; +export * from './src/pods/agent/AgentJsonParser'; +export * from './src/pods/agent/AgentParser'; + +// Pods/Generate +export * from './src/pods/generate/HandlebarsTemplateEngine'; +export * from './src/pods/generate/IdentifierGenerator'; +export * from './src/pods/generate/ResourcesGenerator'; +export * from './src/pods/generate/SuffixIdentifierGenerator'; +export * from './src/pods/generate/TemplateEngine'; +export * from './src/pods/generate/TemplatedResourcesGenerator'; + +// Pods +export * from './src/pods/GeneratedPodManager'; +export * from './src/pods/PodManager'; +export * from './src/pods/PodManagerHttpHandler'; + // Server export * from './src/server/ExpressHttpServerFactory'; export * from './src/server/HttpHandler'; diff --git a/src/init/CliRunner.ts b/src/init/CliRunner.ts index bd6fa4023..8e73c4bcc 100644 --- a/src/init/CliRunner.ts +++ b/src/init/CliRunner.ts @@ -37,6 +37,7 @@ export const runCli = function({ port: { type: 'number', alias: 'p', default: 3000 }, rootFilePath: { type: 'string', alias: 'f' }, sparqlEndpoint: { type: 'string', alias: 's' }, + podTemplateFolder: { type: 'string', alias: 't' }, }) .help(); @@ -58,6 +59,8 @@ export const runCli = function({ 'urn:solid-server:default:variable:port': params.port, 'urn:solid-server:default:variable:rootFilePath': params.rootFilePath ?? process.cwd(), 'urn:solid-server:default:variable:sparqlEndpoint': params.sparqlEndpoint, + 'urn:solid-server:default:variable:podTemplateFolder': + params.podTemplateFolder ?? path.join(__dirname, '../../templates'), }, }) as Setup; return await setup.setup(); diff --git a/templates/.acl b/templates/.acl new file mode 100644 index 000000000..86d27703c --- /dev/null +++ b/templates/.acl @@ -0,0 +1,26 @@ +# Root ACL resource for the agent account +@prefix acl: . +@prefix foaf: . + +# The homepage is readable by the public +<#public> + a acl:Authorization; + acl:agentClass foaf:Agent; + acl:accessTo ; + acl:mode acl:Read. + +# The owner has full access to every resource in their pod. +# Other agents have no access rights, +# unless specifically authorized in other .acl resources. +<#owner> + a acl:Authorization; + acl:agent <{{webId}}>; + # Optional owner email, to be used for account recovery: + {{#if email}}acl:agent ;{{/if}} + # Set the access to the root storage folder itself + acl:accessTo ; + # All resources will inherit this authorization, by default + acl:default ; + # The owner has all of the access modes allowed + acl:mode + acl:Read, acl:Write, acl:Control. diff --git a/templates/profile/card$.ttl b/templates/profile/card$.ttl new file mode 100644 index 000000000..77489553a --- /dev/null +++ b/templates/profile/card$.ttl @@ -0,0 +1,10 @@ +@prefix foaf: . + +<> + a foaf:PersonalProfileDocument; + foaf:maker <{{webId}}>; + foaf:primaryTopic <{{webId}}>. + +<{{webId}}> + a foaf:Person; + foaf:name "{{name}}". diff --git a/test/configs/middleware.json b/test/configs/middleware.json index e123dc0df..f67631ca0 100644 --- a/test/configs/middleware.json +++ b/test/configs/middleware.json @@ -6,6 +6,10 @@ "files-scs:config/presets/cli-params.json" ], "@graph": [ + { + "@id": "urn:solid-server:default:PodManagerHandler", + "@type": "Variable" + }, { "@id": "urn:solid-server:default:LdpHandler", "@type": "Variable" diff --git a/test/configs/websockets.json b/test/configs/websockets.json index 651a6cf1a..3efda7a98 100644 --- a/test/configs/websockets.json +++ b/test/configs/websockets.json @@ -10,6 +10,7 @@ "files-scs:config/presets/ldp/request-parser.json", "files-scs:config/presets/ldp/websockets.json", "files-scs:config/presets/middleware.json", + "files-scs:config/presets/pod-management.json", "files-scs:config/presets/representation-conversion.json", "files-scs:config/presets/storage/backend/storage-memory.json", "files-scs:config/presets/storage/routing/no-routing.json", diff --git a/test/integration/Middleware.test.ts b/test/integration/Middleware.test.ts index 7e2b1888d..962d87a38 100644 --- a/test/integration/Middleware.test.ts +++ b/test/integration/Middleware.test.ts @@ -21,6 +21,7 @@ describe('An Express server with middleware', (): void => { beforeAll(async(): Promise => { const factory = await instantiateFromConfig( 'urn:solid-server:default:ExpressHttpServerFactory', 'middleware.json', { + 'urn:solid-server:default:PodManagerHandler': new SimpleHttpHandler(), 'urn:solid-server:default:LdpHandler': new SimpleHttpHandler(), 'urn:solid-server:default:variable:port': port, 'urn:solid-server:default:variable:baseUrl': 'https://example.pod/', diff --git a/test/integration/WebSocketsProtocol.test.ts b/test/integration/WebSocketsProtocol.test.ts index b12094d09..064cfbee7 100644 --- a/test/integration/WebSocketsProtocol.test.ts +++ b/test/integration/WebSocketsProtocol.test.ts @@ -16,6 +16,7 @@ describe('A server with the Solid WebSockets API behind a proxy', (): void => { 'urn:solid-server:default:ServerFactory', 'websockets.json', { 'urn:solid-server:default:variable:port': port, 'urn:solid-server:default:variable:baseUrl': 'https://example.pod/', + 'urn:solid-server:default:variable:podTemplateFolder': 'templates', }, ) as HttpServerFactory; server = factory.startServer(port); diff --git a/test/unit/init/CliRunner.test.ts b/test/unit/init/CliRunner.test.ts index 9a8376d08..595445a5c 100644 --- a/test/unit/init/CliRunner.test.ts +++ b/test/unit/init/CliRunner.test.ts @@ -44,6 +44,7 @@ describe('CliRunner', (): void => { 'urn:solid-server:default:variable:rootFilePath': process.cwd(), 'urn:solid-server:default:variable:sparqlEndpoint': undefined, 'urn:solid-server:default:variable:loggingLevel': 'info', + 'urn:solid-server:default:variable:podTemplateFolder': path.join(__dirname, '../../../templates'), }, }, ); @@ -63,6 +64,7 @@ describe('CliRunner', (): void => { '-f', '/root', '-s', 'http://localhost:5000/sparql', '-l', 'debug', + '-t', 'templates', ], }); await mockSetup.setup(); @@ -78,6 +80,7 @@ describe('CliRunner', (): void => { 'urn:solid-server:default:variable:rootFilePath': '/root', 'urn:solid-server:default:variable:sparqlEndpoint': 'http://localhost:5000/sparql', 'urn:solid-server:default:variable:loggingLevel': 'debug', + 'urn:solid-server:default:variable:podTemplateFolder': 'templates', }, }, ); @@ -93,6 +96,7 @@ describe('CliRunner', (): void => { '--rootFilePath', '/root', '--sparqlEndpoint', 'http://localhost:5000/sparql', '--loggingLevel', 'debug', + '--podTemplateFolder', 'templates', ], }); await mockSetup.setup(); @@ -108,6 +112,7 @@ describe('CliRunner', (): void => { 'urn:solid-server:default:variable:rootFilePath': '/root', 'urn:solid-server:default:variable:sparqlEndpoint': 'http://localhost:5000/sparql', 'urn:solid-server:default:variable:loggingLevel': 'debug', + 'urn:solid-server:default:variable:podTemplateFolder': 'templates', }, }, );