-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: ucp-enforcement stuff for demo
- Loading branch information
1 parent
beb9c14
commit 50c49f2
Showing
8 changed files
with
269 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import { ContainerUCRulesStorage, PolicyExecutor, UCRulesStorage, UconEnforcementDecision, UcpPatternEnforcement, UcpPlugin } from "@solidlab/ucp" | ||
import { App, AppRunner, AppRunnerInput } from "@solid/community-server"; | ||
import * as Path from 'path'; | ||
import { EyeJsReasoner, readText } from "koreografeye"; | ||
|
||
type Demo = { | ||
css: App, | ||
ucpEngine: UconEnforcementDecision, | ||
storage: UCRulesStorage | ||
} | ||
|
||
export async function initEngine(portNumber = 3123): Promise<Demo> { | ||
const containerURL = `http://localhost:${portNumber}/` | ||
// code to start css server somewhere | ||
const css = await configSolidServer(portNumber) | ||
|
||
// initiating | ||
// load plugin(s) | ||
const plugins = { "http://example.org/dataUsage": new UcpPlugin() } | ||
// Initialise koreografeye policy executor | ||
const policyExecutor = new PolicyExecutor(plugins) | ||
// load N3 Rules from a directory | ||
const rulesDirectory = Path.join(__dirname) | ||
const n3Rules: string[] = [readText(Path.join(rulesDirectory, 'purpose-time.n3'))!] | ||
// Initialise Usage Control Rule Storage | ||
const uconRulesStorage = new ContainerUCRulesStorage(containerURL); | ||
const ucpEngine = new UcpPatternEnforcement(uconRulesStorage, n3Rules, new EyeJsReasoner([ | ||
"--quiet", | ||
"--nope", | ||
"--pass"]), policyExecutor) | ||
return {css, ucpEngine, storage: uconRulesStorage} | ||
} | ||
|
||
|
||
// utils | ||
async function configSolidServer(port: number): Promise<App> { | ||
const input: AppRunnerInput = { | ||
config: Path.join(__dirname, "memory.json"), | ||
variableBindings: { | ||
'urn:solid-server:default:variable:port': port, | ||
'urn:solid-server:default:variable:baseUrl': `http://localhost:${port}/`, | ||
'urn:solid-server:default:variable:loggingLevel': 'warn', | ||
} | ||
} | ||
const cssRunner = await new AppRunner().create(input) | ||
return cssRunner | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import { createContext, storeToString } from "@solidlab/ucp"; | ||
import { initEngine } from "./demoEngine"; | ||
import { demoPolicy } from "./policyCreation"; | ||
|
||
async function main(){ | ||
const {css, ucpEngine, storage} = await initEngine(); | ||
|
||
const target = "urn:wout:age" | ||
const requestingParty = "https://pod.rubendedecker.be/profile/card#me" | ||
|
||
const request = { | ||
subject: requestingParty, | ||
action: ["http://www.w3.org/ns/auth/acl#Read"], | ||
resource: target, | ||
owner: "https://pod.woutslabbinck.com/profile/card#me" | ||
} | ||
const policy = demoPolicy(target, requestingParty) | ||
// start server | ||
await css.start(); | ||
|
||
|
||
const noAccessModes = await ucpEngine.calculateAccessModes(request); | ||
console.log("Access modes retrieved when no policy in storage", noAccessModes); | ||
|
||
// Add following Policy to storage: | ||
// Wout gives access to Ruben regarding Wout his age | ||
// constraints: two weeks from now on + purpose= "age-verification" | ||
await storage.addRule(policy.representation) | ||
|
||
|
||
const accessModes = await ucpEngine.calculateAccessModes(request); | ||
console.log("Access modes retrieved when policy in storage", accessModes); | ||
|
||
// debug logs | ||
// console.log(storeToString(createContext(request))); // Note: request -> which is also what is expected in the uma server at that stage | ||
// console.log(storeToString(policy.representation)); // Note: log ODRL rule | ||
console.log("Right now 'storage' is used to PUT the demo policy to 'http://localhost:3123/'. A normal HTTP request can also be used to do that."); | ||
|
||
} | ||
|
||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
{ | ||
"@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", | ||
"import": [ | ||
"css:config/app/init/initialize-root.json", | ||
"css:config/app/main/default.json", | ||
"css:config/app/variables/default.json", | ||
"css:config/http/handler/default.json", | ||
"css:config/http/middleware/default.json", | ||
"css:config/http/notifications/all.json", | ||
"css:config/http/server-factory/http.json", | ||
"css:config/http/static/default.json", | ||
"css:config/identity/access/public.json", | ||
"css:config/identity/email/default.json", | ||
"css:config/identity/handler/disabled.json", | ||
"css:config/identity/oidc/disabled.json", | ||
"css:config/identity/ownership/token.json", | ||
"css:config/identity/pod/static.json", | ||
"css:config/ldp/authentication/dpop-bearer.json", | ||
"css:config/ldp/authorization/webacl.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/memory.json", | ||
"css:config/storage/key-value/resource-store.json", | ||
"css:config/storage/location/root.json", | ||
"css:config/storage/middleware/default.json", | ||
"css:config/util/auxiliary/acl.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/memory.json", | ||
"css:config/util/variables/default.json" | ||
], | ||
"@graph": [] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
/** | ||
* create ODRL policy with three constraints -> basically a function that prints that as output | ||
- constraints | ||
- start time | ||
- end time | ||
- purpose: string -> "age-verification" | ||
- target: SHACL shape? | ||
*/ | ||
|
||
import { SimplePolicy, UCPPolicy, basicPolicy, storeToString } from '@solidlab/ucp' | ||
|
||
export const agePurpose = "age-verification" | ||
/** | ||
* Create demo ODRL policy: | ||
* | ||
* Read access for requestingparty to target under constraints (temporal + purpose) | ||
* @param targetIRI - an IRI representing the target -> the resource | ||
* @param requestingPartyIRI - an IRI representing the entity requesting access | ||
* @param constraints | ||
*/ | ||
export function demoPolicy(targetIRI, requestingPartyIRI, constraints?: { startDate?: Date, endDate?: Date, purpose?: string }): SimplePolicy { | ||
const startDate = constraints?.startDate ?? new Date() | ||
const endDate = constraints?.endDate ?? new Date(startDate.valueOf()+ 86_400 * 14 * 1000) | ||
const purpose = constraints?.purpose ?? agePurpose | ||
|
||
const policy: UCPPolicy = { | ||
rules: [{ | ||
requestingParty: requestingPartyIRI, | ||
action: "http://www.w3.org/ns/odrl/2/read", // msut be odrl | ||
resource: targetIRI, | ||
owner: "https://pod.woutslabbinck.com/profile/card#me", // can lead to bugs, depending on whether we use owner or not | ||
constraints: [ | ||
{ | ||
type: "temporal", | ||
operator: "http://www.w3.org/ns/odrl/2/gt", | ||
value: startDate | ||
}, | ||
{ | ||
type: "temporal", | ||
operator: "http://www.w3.org/ns/odrl/2/lt", | ||
value: endDate | ||
}, | ||
{ | ||
type: "purpose", | ||
operator: "http://www.w3.org/ns/odrl/2/eq", | ||
value: purpose | ||
}, | ||
] | ||
}] | ||
} | ||
|
||
const policyObject = basicPolicy(policy); | ||
// console.log(storeToString(policyObject.representation)); | ||
return policyObject | ||
} | ||
|
||
// example: Wout gives access to Ruben regarding Wout his age | ||
// demoPolicy("urn:wout:age", "https://pod.rubendedecker.be/profile/card#me") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . | ||
@prefix odrl: <http://www.w3.org/ns/odrl/2/> . | ||
@prefix : <http://example.org/> . | ||
@prefix acl: <http://www.w3.org/ns/auth/acl#>. | ||
@prefix fno: <https://w3id.org/function/ontology#> . | ||
@prefix log: <http://www.w3.org/2000/10/swap/log#> . | ||
@prefix string: <http://www.w3.org/2000/10/swap/string#> . | ||
@prefix list: <http://www.w3.org/2000/10/swap/list#> . | ||
@prefix time: <http://www.w3.org/2000/10/swap/time#> . | ||
@prefix math: <http://www.w3.org/2000/10/swap/math#> . | ||
# Create ODRL Rule: doesn't exist (`odrl:write` and `odrl:append` are deprecated) | ||
{ :currentTime :is ?currentTime } <= { "" time:localTime ?currentTime }. | ||
|
||
# Read ODRL rule | ||
{ | ||
?permission a odrl:Permission; | ||
odrl:action ?action ; | ||
odrl:target ?targetResource ; | ||
odrl:assignee ?requestedParty; | ||
odrl:assigner ?resourceOwner . | ||
|
||
?action list:in (odrl:use odrl:read) . # multiple options | ||
|
||
# context of a request | ||
?context | ||
:resourceOwner ?resourceOwner; | ||
:requestingParty ?requestedParty; | ||
:target ?targetResource; | ||
:requestPermission acl:Read. | ||
|
||
:uuid5 log:uuid ?uuidStringdataUsagePolicyExecution. | ||
( "urn:uuid:" ?uuidStringdataUsagePolicyExecution) string:concatenation ?urnUuidStringdataUsagePolicyExecution. | ||
?dataUsagePolicyExecution log:uri ?urnUuidStringdataUsagePolicyExecution . | ||
|
||
# Constraint checking | ||
# number of constraints must be two (temporal needs lower and upper bound) | ||
(?template {?permission odrl:constraint _:s} ?L) log:collectAllIn ?SCOPE. | ||
?L list:length 3 . | ||
|
||
:currentTime :is ?currentTime . | ||
|
||
# lower bound | ||
?permission odrl:constraint ?lowerBoundIRI . | ||
?lowerBoundIRI odrl:leftOperand odrl:dateTime ; | ||
odrl:operator odrl:gt ; | ||
odrl:rightOperand ?lowerBound . | ||
|
||
# greater bound | ||
?permission odrl:constraint ?upperBoundIRI . | ||
?upperBoundIRI odrl:leftOperand odrl:dateTime ; | ||
odrl:operator odrl:lt ; | ||
odrl:rightOperand ?upperBound . | ||
|
||
# ?lowerBound < ?currentTime < ?upperBound | ||
?currentTime math:greaterThan ?lowerBound . | ||
?currentTime math:lessThan ?upperBound . | ||
|
||
# purpose constraint | ||
?permission odrl:constraint ?purposeConstraint . | ||
?purposeConstraint odrl:leftOperand odrl:purpose ; | ||
odrl:operator odrl:eq ; | ||
odrl:rightOperand ?purposeValue | ||
# Note: nothing is done with the purpose right now TODO: needs checking | ||
} => | ||
{ | ||
?dataUsagePolicyExecution a fno:Execution; | ||
fno:executes <http://example.org/dataUsage> ; | ||
:accessModesAllowed acl:Read. | ||
?dataUsagePolicyExecution <http://purl.org/dc/terms/issued> ?currentTime . | ||
|
||
}. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters