1- // Access control logic
1+ /**
2+ * Non-UI functions for access control.
3+ * See https://github.com/solid/web-access-control-spec
4+ * for the spec that defines how ACL documents work.
5+ * @packageDocumentation
6+ */
27
38import * as $rdf from 'rdflib'
49import ns from '../ns'
510import kb from '../store.js'
611import utils from '../utils'
712import { AgentMapMap , ComboList } from './types'
813
9- // //////////////////////////////////// Solid ACL non-UI functions
10- //
11-
12- // Take the "defaultForNew" ACL and convert it into the equivlent ACL
13- // which the resource would have had. Return it as a new separate store .
14-
14+ /**
15+ * Take the "default" ACL and convert it into the equivlent ACL
16+ * which the resource would have had. Return it as a new separate store.
17+ * The "defaultForNew" predicate is also accepted, as a deprecated
18+ * synonym for "default" .
19+ */
1520export function adoptACLDefault (
1621 doc : $rdf . NamedNode ,
1722 aclDoc : $rdf . NamedNode ,
@@ -63,10 +68,11 @@ export function adoptACLDefault (
6368 return kb2
6469}
6570
66- // Read and canonicalize the ACL for x in aclDoc
67- //
68- // Accumulate the access rights which each agent or class has
69-
71+ /**
72+ * Read and canonicalize the ACL for x in aclDoc
73+ *
74+ * Accumulate the access rights which each agent or class has
75+ */
7076export function readACL (
7177 x : $rdf . NamedNode ,
7278 aclDoc : $rdf . NamedNode ,
@@ -104,7 +110,9 @@ export function readACL (
104110 }
105111}
106112
107- // Compare two ACLs
113+ /**
114+ * Compare two ACLs
115+ */
108116export function sameACL ( a : AgentMapMap , b : AgentMapMap ) : boolean {
109117 const contains = function ( a , b ) {
110118 for ( const pred in {
@@ -129,7 +137,9 @@ export function sameACL (a: AgentMapMap, b: AgentMapMap): boolean {
129137 return contains ( a , b ) && contains ( b , a )
130138}
131139
132- // Union N ACLs
140+ /**
141+ * Union N ACLs
142+ */
133143export function ACLunion ( list : Array < AgentMapMap > ) : AgentMapMap {
134144 const b = list [ 0 ]
135145 let a , ag
@@ -151,8 +161,9 @@ export function ACLunion (list: Array<AgentMapMap>): AgentMapMap {
151161 return b
152162}
153163
154- // Merge ACLs lists from things to form union
155-
164+ /**
165+ * Merge ACLs lists from things to form union
166+ */
156167export function loadUnionACL ( subjectList : Array < $rdf . NamedNode > , callbackFunction : Function ) : void {
157168 const aclList : Array < AgentMapMap > = [ ]
158169 const doList = function ( list ) {
@@ -182,11 +193,12 @@ export function loadUnionACL (subjectList: Array<$rdf.NamedNode>, callbackFuncti
182193 doList ( subjectList )
183194}
184195
185- // Represents these as a RDF graph by combination of modes
186- //
187- // Each agent can only be in one place in this model, one combination of modes.
188- // Combos are like full control, read append, read only etc.
189- //
196+ /**
197+ * Represents these as an RDF graph by combination of modes
198+ *
199+ * Each agent can only be in one place in this model, one combination of modes.
200+ * Combos are like full control, read append, read only etc.
201+ */
190202export function ACLbyCombination ( ac : AgentMapMap ) : ComboList {
191203 const byCombo = { }
192204 ; [ 'agent' , 'agentClass' , 'agentGroup' , 'origin' , 'originClass' ] . map ( function ( pred ) {
@@ -204,15 +216,17 @@ export function ACLbyCombination (ac: AgentMapMap): ComboList {
204216 return byCombo
205217}
206218
207- // Write ACL graph to store from AC
208- //
219+ /**
220+ * Write ACL graph to store from AC
221+ */
209222export function makeACLGraph ( kb : $rdf . IndexedFormula , x : $rdf . NamedNode , ac : AgentMapMap , aclDoc : $rdf . NamedNode ) : void {
210223 const byCombo = ACLbyCombination ( ac )
211224 return makeACLGraphbyCombo ( kb , x , byCombo , aclDoc )
212225}
213226
214- // Write ACL graph to store from combo
215- //
227+ /**
228+ * Write ACL graph to store from combo
229+ */
216230export function makeACLGraphbyCombo (
217231 kb : $rdf . IndexedFormula ,
218232 x : $rdf . NamedNode ,
@@ -250,13 +264,17 @@ export function makeACLGraphbyCombo (
250264 }
251265}
252266
253- // Debugging short strings for dumping ACL
254- // and who knows maybe in the UI
255- //
267+ /**
268+ * Debugging short strings for dumping ACL
269+ * and possibly in the UI
270+ */
256271export function ACLToString ( ac : AgentMapMap ) : string {
257272 return comboToString ( ACLbyCombination ( ac ) )
258273}
259274
275+ /**
276+ * Convert a [[ComboList]] to a string
277+ */
260278export function comboToString ( byCombo : ComboList ) : string {
261279 let str = ''
262280 for ( const combo in byCombo ) {
@@ -280,17 +298,19 @@ export function comboToString (byCombo: ComboList): string {
280298 return '{' + str . slice ( 0 , - 1 ) + '}' // drop extra semicolon
281299}
282300
283- // Write ACL graph to string
284- //
301+ /**
302+ * Write ACL graph as Turtle
303+ */
285304export function makeACLString ( x : $rdf . NamedNode , ac : AgentMapMap , aclDoc : $rdf . NamedNode ) : string {
286305 const kb2 = $rdf . graph ( )
287306 makeACLGraph ( kb2 , x , ac , aclDoc )
288307 // @@ TODO Remove casting
289308 return ( $rdf as any ) . serialize ( aclDoc , kb2 , aclDoc . uri , 'text/turtle' )
290309}
291310
292- // Write ACL graph to web
293- //
311+ /**
312+ * Write ACL graph to web
313+ */
294314export function putACLObject (
295315 kb : $rdf . IndexedFormula ,
296316 x : $rdf . NamedNode ,
@@ -302,8 +322,9 @@ export function putACLObject (
302322 return putACLbyCombo ( kb , x , byCombo , aclDoc , callbackFunction )
303323}
304324
305- // Write ACL graph to web from combo
306- //
325+ /**
326+ * Write ACL graph to web from a [[ComboList]]
327+ */
307328export function putACLbyCombo (
308329 kb : $rdf . IndexedFormula ,
309330 x : $rdf . NamedNode ,
@@ -333,11 +354,11 @@ export function putACLbyCombo (
333354 )
334355}
335356
336- // Fix the ACl for an individual card as a function of the groups it is in
337- //
338- // All group files must be loaded first
339- //
340-
357+ /**
358+ * Fix the ACl for an individual card as a function of the groups it is in
359+ *
360+ * All group files must be loaded first
361+ */
341362export function fixIndividualCardACL ( person : $rdf . NamedNode , log : Function , callbackFunction : Function ) : void {
342363 const groups = kb . each ( undefined , ns . vcard ( 'hasMember' ) , person )
343364 // const doc = person.doc()
@@ -350,6 +371,9 @@ export function fixIndividualCardACL (person: $rdf.NamedNode, log: Function, cal
350371 // @@ if no groups, then use default for People container or the book top container.?
351372}
352373
374+ /**
375+ * This function is used by [[fixIndividualCardACL]]
376+ */
353377export function fixIndividualACL ( item : $rdf . NamedNode , subjects : Array < $rdf . NamedNode > , log : Function , callbackFunction : Function ) : void {
354378 log = log || console . log
355379 const doc = item . doc ( )
@@ -388,6 +412,9 @@ export function fixIndividualACL (item: $rdf.NamedNode, subjects: Array<$rdf.Nam
388412 } )
389413}
390414
415+ /**
416+ * Set an ACL
417+ */
391418export function setACL (
392419 docURI : $rdf . NamedNode ,
393420 aclText : string ,
@@ -427,13 +454,15 @@ export function setACL (
427454 }
428455}
429456
430- // Get ACL file or default if necessary
431- //
432- // callbackFunction(true, true, doc, aclDoc) The ACL did exist
433- // callbackFunction(true, false, doc, aclDoc, defaultHolder, defaultACLDoc) ACL file did not exist but a default did
434- // callbackFunction(false, false, status, message) error getting original
435- // callbackFunction(false, true, status, message) error getting default
436-
457+ /**
458+ * Get ACL file or default if necessary
459+ *
460+ * @param callbackFunction Will be called in the following ways, in the following cases:
461+ * * `callbackFunction(true, true, doc, aclDoc)` if the ACL did exist
462+ * * `callbackFunction(true, false, doc, aclDoc, defaultHolder, defaultACLDoc)` if the ACL file did not exist but a default did
463+ * * `callbackFunction(false, false, status, message)` when there was an error getting the original
464+ * * `callbackFunction(false, true, status, message)` when there was an error getting the default
465+ */
437466export function getACLorDefault (
438467 doc : $rdf . NamedNode ,
439468 callbackFunction : (
@@ -536,15 +565,16 @@ export function getACLorDefault (
536565 return callbackFunction ( true , true , doc , aclDoc as $rdf . NamedNode )
537566 }
538567 } ) // Call to getACL
539- } // getACLorDefault
568+ }
540569
541- // Calls back (ok, status, acldoc, message)
542- //
543- // (false, 900, errormessage) no link header
544- // (true, 403, documentSymbol, fileaccesserror) not authorized
545- // (true, 404, documentSymbol, fileaccesserror) if does not exist
546- // (true, 200, documentSymbol) if file exitss and read OK
547- //
570+ /**
571+ * Calls back `(ok, status, acldoc, message)` as follows
572+ *
573+ * * `(false, 900, errormessage)` if no link header
574+ * * `(true, 403, documentSymbol, fileaccesserror)` if not authorized
575+ * * `(true, 404, documentSymbol, fileaccesserror)` if does not exist
576+ * * `(true, 200, documentSymbol)` if file exists and read OK
577+ */
548578export function getACL (
549579 doc : $rdf . NamedNode ,
550580 callbackFunction : (
@@ -593,6 +623,9 @@ export function getACL (
593623 } )
594624}
595625
626+ /**
627+ * Calls [[getACLorDefault]] and then (?)
628+ */
596629export async function getProspectiveHolder ( targetDirectory : string ) : Promise < $rdf . NamedNode | undefined > {
597630 return new Promise ( ( resolve , reject ) => getACLorDefault ( $rdf . sym ( targetDirectory ) , (
598631 ok ,
0 commit comments