Skip to content

Commit

Permalink
feat: derived resources (#36)
Browse files Browse the repository at this point in the history
Signed-off-by: Wouter Termont <[email protected]>
Co-authored-by: Wout Slabbinck <[email protected]>
  • Loading branch information
termontwouter and woutslabbinck authored Mar 25, 2024
1 parent 94e8cf4 commit 1839a7c
Show file tree
Hide file tree
Showing 22 changed files with 709 additions and 56 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,11 @@
"start:all": "yarn workspaces foreach --exclude . -A -pi run start",
"script:public": "yarn exec ts-node ./scripts/test-public.ts",
"script:private": "yarn exec ts-node ./scripts/test-private.ts",
"script:derived": "yarn exec ts-node ./scripts/test-derived.ts",
"script:registration": "yarn exec ts-node ./scripts/test-registration.ts",
"script:ucp-enforcement": "yarn exec ts-node ./scripts/test-ucp-enforcement.ts",
"script:uma-ucp": "yarn exec ts-node ./scripts/test-uma-ucp.ts",
"script:flow": "yarn run script:public && yarn run script:private && yarn run script:uma-ucp && yarn run script:registration && yarn run script:ucp-enforcement"
"script:flow": "yarn run script:public && yarn run script:private && yarn run script:derived && yarn run script:uma-ucp && yarn run script:registration && yarn run script:ucp-enforcement"
},
"devDependencies": {
"@commitlint/cli": "^16.1.0",
Expand Down
22 changes: 22 additions & 0 deletions packages/css/config/demo.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"@context": [
"https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld",
"https://linkedsoftwaredependencies.org/bundles/npm/@solidlab/derived-resources-component/^1.0.0/components/context.jsonld"
],
"@graph": [
{
"@id": "urn:solid-server:derived:PodResourcesOverride",
"@type": "Override",
"overrideInstance": {
"@id": "urn:solid-server:default:PodResourcesGenerator"
},
"overrideParameters": {
"@type": "StaticFolderGenerator",
"templateFolder": "templates/pod",
"resourcesGenerator": {
"@id": "urn:solid-server:default:TemplatedResourcesGenerator"
}
}
}
]
}
72 changes: 72 additions & 0 deletions packages/css/config/derived.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
{
"@context": [
"https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld",
"https://linkedsoftwaredependencies.org/bundles/npm/@solidlab/derived-resources-component/^1.0.0/components/context.jsonld"
],
"@graph": [
{
"comment": "We need to disable the index store as it might accidentally return derived template resources.",
"@id": "urn:solid-server:default:ResourceStore_Index",
"@type": "IndexRepresentationStore",
"mediaRange": ""
},
{
"comment": "A second converting store",
"@id": "urn:solid-server:derived:RepresentationConvertingStore",
"@type": "RepresentationConvertingStore",
"metadataStrategy": { "@id": "urn:solid-server:default:MetadataStrategy" },
"options_inConverter": { "@id": "urn:solid-server:default:RepresentationConverter" },
"options_outConverter": { "@id": "urn:solid-server:default:UiEnabledConverter" },
"source": { "@id": "urn:solid-server:derived:DerivedResourceStore" }
},
{
"comment": "The store responsible for generating derived resources.",
"@id": "urn:solid-server:derived:DerivedResourceStore",
"@type": "DerivedResourceStore",
"manager": {
"@id": "urn:solid-server:derived:DerivationManager",
"@type": "MetadataDerivationManager",
"identifierStrategy": { "@id": "urn:solid-server:default:IdentifierStrategy" },
"store": { "@id": "urn:solid-server:default:ResourceStore_Patching" },
"derivationMatcher": {
"@type": "PresetDerivationMatcher",
"source": { "@type": "TemplateDerivationMatcher" }
},
"selectorHandler": {
"@id": "urn:solid-server:default:SelectorHandler",
"@type": "GlobSelectorHandler",
"store": { "@id": "urn:solid-server:default:ResourceStore_Patching" }
},
"filterHandler": {
"@id": "urn:solid-server:default:FilterHandler",
"@type": "SparqlFilterHandler",
"store": { "@id": "urn:solid-server:default:ResourceStore_Patching" }
}
},
"source": { "@id": "urn:solid-server:default:ResourceStore_Patching" }
},
{
"comment": "Insert our new stores in front of the original converting store.",
"@id": "urn:solid-server:derived:PatchOverride",
"@type": "Override",
"overrideInstance": { "@id": "urn:solid-server:default:ResourceStore_Locking" },
"overrideParameters": {
"@type": "PatchingStore",
"source": { "@id": "urn:solid-server:derived:RepresentationConvertingStore" }
}
},
{
"comment": [
"Keep query parameters in identifiers.",
"This makes it so that any query parameters can cause issues with normal resources so we might want a more robust solution."
],
"@id": "urn:solid-server:derived:TargetExtractorOverride",
"@type": "Override",
"overrideInstance": { "@id": "urn:solid-server:default:TargetExtractor" },
"overrideParameters": {
"@type": "OriginalUrlExtractor",
"includeQueryString": true
}
}
]
}
34 changes: 32 additions & 2 deletions packages/css/config/seed.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,44 @@
"authz": {
"server": "http://localhost:4000/uma"
},
"pods": [ { "name": "alice" } ]
"pods": [{
"name": "alice",
"settings": {
"name": "Alice",
"umaServer": "http://localhost:4000/uma"
}
}]
},
{
"email": "[email protected]",
"password": "abc123",
"authz": {
"server": "http://localhost:4000/uma"
},
"pods": [ { "name": "bob" } ]
"pods": [
{
"name": "bob",
"settings": {
"name": "Bob",
"umaServer": "http://localhost:4000/uma"
}
}
]
},
{
"email": "[email protected]",
"password": "abc123",
"authz": {
"server": "http://localhost:4000/uma"
},
"pods": [
{
"name": "demo",
"settings": {
"name": "Demo",
"umaServer": "http://localhost:4000/uma"
}
}
]
}
]
3 changes: 2 additions & 1 deletion packages/css/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,11 @@
"build:ts": "yarn run -T tsc",
"build:components": "yarn run -T componentsjs-generator -r uma-css -s src/ -c dist/components -i .componentsignore --lenient",
"test": "yarn run -T jest --coverage",
"start": "yarn run community-solid-server -m . -c ./config/default.json --seedConfig ./config/seed.json"
"start": "yarn run community-solid-server -m . -c ./config/default.json ./config/derived.json ./config/demo.json --seedConfig ./config/seed.json"
},
"dependencies": {
"@solid/community-server": "^7.0.2",
"@solidlab/derived-resources-component": "^1.0.1",
"@solidlab/uma": "workspace:^",
"componentsjs": "^5.4.2",
"cross-fetch": "^4.0.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/css/src/uma/ResourceRegistrar.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { UmaClient } from '../uma/UmaClient';
import type { ResourceIdentifier, MonitoringStore } from '@solid/community-server';
import { AS, getLoggerFor, StaticHandler } from '@solid/community-server';
import { OwnerUtil } from '../util/OwnerUtil';
import type { UmaClient } from '../uma/UmaClient';

export class ResourceRegistrar extends StaticHandler {
protected readonly logger = getLoggerFor(this);
Expand Down
17 changes: 9 additions & 8 deletions packages/css/src/uma/UmaClient.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import type { KeyValueStorage, Representation, ResourceIdentifier } from "@solid/community-server";
import { AccessMap, getLoggerFor, InternalServerError, JwkGenerator, NotFoundHttpError } from "@solid/community-server";
import { JWTPayload, decodeJwt, createRemoteJWKSet, jwtVerify, JWTVerifyOptions } from "jose";
import { httpbis, type SigningKey, type Request as SignRequest } from 'http-message-signatures';
import fetch from 'cross-fetch';
import type { Fetcher } from "../util/fetch/Fetcher";
import crypto from 'node:crypto';
import type { ResourceDescription } from "@solidlab/uma";
import {
type KeyValueStorage, type ResourceIdentifier,
AccessMap, getLoggerFor, InternalServerError, JwkGenerator,
} from "@solid/community-server";
import type { Fetcher } from "../util/fetch/Fetcher";
import type { ResourceDescription } from '@solidlab/uma';
import { httpbis, type SigningKey, type Request as SignRequest } from 'http-message-signatures';
import { JWTPayload, decodeJwt, createRemoteJWKSet, jwtVerify, JWTVerifyOptions } from "jose";

export interface Claims {
[key: string]: unknown;
Expand Down Expand Up @@ -71,9 +72,9 @@ export class UmaClient {
*/
constructor(
protected baseUrl: string,
protected umaIdStore: KeyValueStorage<string, string>,
protected fetcher: Fetcher,
protected keyGen: JwkGenerator,
protected umaIdStore: KeyValueStorage<string, string>,
protected options: UmaVerificationOptions = {},
) {}

Expand Down
3 changes: 3 additions & 0 deletions packages/css/templates/pod/base/.meta
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@prefix pim: <http://www.w3.org/ns/pim/space#>.

<> a pim:Storage.
27 changes: 27 additions & 0 deletions packages/css/templates/pod/base/README$.md.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Welcome to your pod

## A place to store your data
Your pod is a **secure storage space** for your documents and data.
<br>
You can choose to share those with other people and apps.

As the owner of this pod,
identified by <a href="{{webId}}">{{webId}}</a>,
you have access to all of your documents.

## Working with your pod
The easiest way to interact with pods
is through Solid apps.
<br>
For example,
you can open your pod in [Databrowser](https://solidos.github.io/mashlib/dist/browse.html?uri={{base.path}}).

## Accessing your account
To keep track of your pods, webIDs and any other resources,
you can [log in]({{oidcIssuer}}.account/) to your account.
There you can, for example, update the owners of this pod.

## Learn more
The [Solid website](https://solidproject.org/)
and the people on its [forum](https://forum.solidproject.org/)
will be glad to help you on your journey.
22 changes: 22 additions & 0 deletions packages/css/templates/pod/base/private/.meta
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
@prefix derived: <urn:npm:solid:derived-resources:> .

<>
derived:derivedResource [
derived:template "derived/bday";
derived:selector <./data>;
derived:filter <../public/filters/bday>
].

<>
derived:derivedResource [
derived:template "derived/age";
derived:selector <./data>;
derived:filter <../public/filters/age>
].

# <>
# derived:derivedResource [
# derived:template "query{?var}";
# derived:selector <selectors/data>;
# derived:filter <filters/var>
# ].
20 changes: 20 additions & 0 deletions packages/css/templates/pod/base/private/data$.ttl
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
@prefix ruben: <https://ruben.verborgh.org/profile/#me>.
@prefix con: <http://www.w3.org/2000/10/swap/pim/contact#>.
@prefix dbo: <http://dbpedia.org/ontology/>.
@prefix dbp: <http://dbpedia.org/resource/>.
@prefix foaf: <http://xmlns.com/foaf/0.1/>.
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.
@prefix vcard: <http://www.w3.org/2006/vcard/ns#>.
@prefix xsd: <http://www.w3.org/2001/XMLSchema#>.

ruben: a foaf:Person;
foaf:name "Ruben Verborgh"@en, "Ruben Verborgh"@nl;
rdfs:label "Ruben Verborgh"@en, "Ruben Verborgh"@nl;
vcard:fn "Ruben Verborgh"@en, "Ruben Verborgh"@nl;
con:preferredURI "https://ruben.verborgh.org/profile/#me";
foaf:givenName "Ruben"@en, "Ruben"@nl;
foaf:familyName "Verborgh"@en, "Verborgh"@nl;
rdfs:label "Ruben Verborgh"@en, "Ruben Verborgh"@nl;
dbo:birthPlace dbp:Ostend;
dbo:birthDate "1987-02-28"^^xsd:date;
foaf:gender "male"@en.
13 changes: 13 additions & 0 deletions packages/css/templates/pod/base/profile/card$.ttl.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
@prefix foaf: <http://xmlns.com/foaf/0.1/>.
@prefix solid: <http://www.w3.org/ns/solid/terms#>.

<>
a foaf:PersonalProfileDocument;
foaf:maker <{{webId}}>;
foaf:primaryTopic <{{webId}}>.

<{{webId}}>
{{#if name}}foaf:name "{{name}}";{{/if}}
{{#if umaServer}}solid:umaServer "{{umaServer}}";{{/if}}
{{#if oidcIssuer}}solid:oidcIssuer <{{oidcIssuer}}>;{{/if}}
a foaf:Person.
25 changes: 25 additions & 0 deletions packages/css/templates/pod/base/public/.meta
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#
# THIS IS A COPY OF ../private/.meta

@prefix derived: <urn:npm:solid:derived-resources:> .

<>
derived:derivedResource [
derived:template "derived/bday";
derived:selector <./data>;
derived:filter <filters/bday>
].

<>
derived:derivedResource [
derived:template "derived/age";
derived:selector <./data>;
derived:filter <filters/age>
].

# <>
# derived:derivedResource [
# derived:template "query{?var}";
# derived:selector <selectors/data>;
# derived:filter <filters/var>
# ].
23 changes: 23 additions & 0 deletions packages/css/templates/pod/base/public/data$.ttl
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#
# THIS IS A COPY OF ../private/data

@prefix ruben: <https://ruben.verborgh.org/profile/#me>.
@prefix con: <http://www.w3.org/2000/10/swap/pim/contact#>.
@prefix dbo: <http://dbpedia.org/ontology/>.
@prefix dbp: <http://dbpedia.org/resource/>.
@prefix foaf: <http://xmlns.com/foaf/0.1/>.
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.
@prefix vcard: <http://www.w3.org/2006/vcard/ns#>.
@prefix xsd: <http://www.w3.org/2001/XMLSchema#>.

ruben: a foaf:Person;
foaf:name "Ruben Verborgh"@en, "Ruben Verborgh"@nl;
rdfs:label "Ruben Verborgh"@en, "Ruben Verborgh"@nl;
vcard:fn "Ruben Verborgh"@en, "Ruben Verborgh"@nl;
con:preferredURI "https://ruben.verborgh.org/profile/#me";
foaf:givenName "Ruben"@en, "Ruben"@nl;
foaf:familyName "Verborgh"@en, "Verborgh"@nl;
rdfs:label "Ruben Verborgh"@en, "Ruben Verborgh"@nl;
dbo:birthPlace dbp:Ostend;
dbo:birthDate "1987-02-28"^^xsd:date;
foaf:gender "male"@en.
18 changes: 18 additions & 0 deletions packages/css/templates/pod/base/public/filters/age$.sparql
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
PREFIX dbo: <http://dbpedia.org/ontology/>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>

CONSTRUCT {
?s foaf:age ?age .
} WHERE {
?s dbo:birthDate ?bday .
BIND(now() AS ?now)
BIND(year(?bday) AS ?bday_year)
BIND(month(?bday) AS ?bday_month)
BIND(day(?bday) AS ?bday_day)
BIND(year(?now) AS ?now_year)
BIND(month(?now) AS ?now_month)
BIND(day(?now) AS ?now_day)
BIND(IF (?now_day - ?bday_day < 0, 1, 0) AS ?extra_month)
BIND(IF (?now_month - ?bday_month - ?extra_month < 0, 1, 0) AS ?extra_year)
BIND(?now_year - ?bday_year - ?extra_year AS ?age)
}
7 changes: 7 additions & 0 deletions packages/css/templates/pod/base/public/filters/bday$.sparql
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
PREFIX dbo: <http://dbpedia.org/ontology/>

CONSTRUCT {
?s dbo:birthDate ?bday .
} WHERE {
?s dbo:birthDate ?bday .
}
4 changes: 3 additions & 1 deletion packages/uma/src/dialog/BaseNegotiator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,9 @@ export class BaseNegotiator implements Negotiator {
return stored;
}

if (!permissions) this.error(BadRequestHttpError, 'The provided ticket is not valid.');
if (!permissions) {
this.error(BadRequestHttpError, 'A token request without existing ticket should include requested permissions.');
}

return await this.ticketingStrategy.initializeTicket(permissions);
}
Expand Down
2 changes: 1 addition & 1 deletion packages/uma/src/dialog/Input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Permission } from "../views/Permission";
* A ReType constant for {@link DialogInput:type}.
*/
export const DialogInput = ({
ticket: string,
ticket: $(string),
claim_token: $(string),
claim_token_format: $(string), // TODO: switch to array of claims objects with unknown structure
pct: $(string),
Expand Down
Loading

0 comments on commit 1839a7c

Please sign in to comment.