1+ import { HttpHandlerRequest , HttpHandlerResponse } from "../../http/models/HttpHandler" ;
2+ import { Quad , Store , Writer } from "n3" ;
3+ import { odrlAssigner , relations , namedNode } from "./PolicyUtil" ;
4+ import { MethodNotAllowedHttpError } from "@solid/community-server" ;
5+
6+ /**
7+ * Handling of the GET /uma/policies endpoint
8+ *
9+ * @param request will give all policies when no <id> is fixed in the URL, otherwise it will give the required policy (if allowed)
10+ */
11+ export async function getPolicies ( request : HttpHandlerRequest , store : Store , clientId : string ) : Promise < HttpHandlerResponse < any > > {
12+ if ( request . url . pathname === '/uma/policies' )
13+ return getAllPolicies ( store , clientId ) ;
14+
15+ // If asked for a policy, validate the policy ID
16+ const args = request . url . pathname . split ( '/' ) ;
17+ if ( args . length === 4 && isPolicy ( args [ - 1 ] ) )
18+ return getOnePolicy ( args [ - 1 ] , store , clientId ) ;
19+
20+ throw new MethodNotAllowedHttpError ( ) ;
21+ }
22+
23+ /**
24+ * Function to determine the validity of the <id> of the GET /uma/policies/<id> endpoint (not implemented yet)
25+ *
26+ * @param policyId
27+ * @returns the validity of policyId
28+ */
29+ function isPolicy ( policyId : string ) : boolean {
30+ // TODO
31+ return true ;
32+ }
33+
34+ /**
35+ * Function to implement the GET /uma/policies/<id> endpoint, it retrieves all information about a certain
36+ * policy if available. Yet to be implemented.
37+ */
38+ function getOnePolicy ( policyId : string , store : Store , clientId : string ) : Promise < HttpHandlerResponse < any > > {
39+ // TODO
40+ return getAllPolicies ( store , clientId ) ;
41+ }
42+
43+
44+ /**
45+ * Get all policy information relevant to the client in the request.
46+ * This iplementation searches for all subjects in relation with the policy with depth 1, a deeper algorithm is required.
47+ *
48+ * @param param0 a request with the clients webID as authorization header.
49+ * @returns all policy information (depth 1) relevant to the client
50+ */
51+ function getAllPolicies ( store : Store , clientId : string ) : Promise < HttpHandlerResponse < any > > {
52+
53+ // Keep track of all the matching policies
54+ const policyDetails : Set < Quad > = new Set ( ) ;
55+
56+ for ( const relation of relations ) {
57+ // Collect every quad that matches with the relation (one of Permission, Prohibition or Duty)
58+ const matchingRules = store . getQuads ( null , relation , null , null ) ;
59+
60+ // Every quad will represent a policy in relation with a rule
61+ for ( const quad of matchingRules ) {
62+ // Extract the policy and rule out the quad
63+ const policy = quad . subject ;
64+ const rule = quad . object ;
65+
66+ // Only go on if the rule is assigned by the client
67+ if ( store . getQuads ( rule , odrlAssigner , namedNode ( clientId ) , null ) . length > 0 ) {
68+
69+ // Because an ODRL policy may only have one assigner, we can now add all policy and rule information
70+ store . getQuads ( policy , null , null , null ) . forEach ( quad => policyDetails . add ( quad ) ) ;
71+ store . getQuads ( rule , null , null , null ) . forEach ( quad => policyDetails . add ( quad ) ) ;
72+ }
73+ }
74+ }
75+
76+
77+ // Serialize as Turtle
78+ const writer = new Writer ( { format : 'Turtle' } ) ;
79+ writer . addQuads ( Array . from ( policyDetails ) ) ;
80+
81+ return new Promise < HttpHandlerResponse < any > > ( ( resolve , reject ) => {
82+ writer . end ( ( error , result ) => {
83+ if ( error ) {
84+ reject ( error ) ;
85+ } else {
86+ resolve ( {
87+ status : 200 ,
88+ headers : { 'content-type' : 'text/turtle' } ,
89+ body : result
90+ } ) ;
91+ }
92+ } ) ;
93+ } ) ;
94+ }
0 commit comments