1- /**
2- * Simple Access Control
3- *
4- * This function sets up a simple default ACL for a resource, with
5- * RWC for the owner, and a specified access (default none) for the public.
6- * In all cases owner has read write control.
7- * Parameter lists modes allowed to public
8- *
9- * @param options
10- * @param options.public eg ['Read', 'Write']
11- *
12- * @returns Resolves with aclDoc uri on successful write
13- */
1+ import { graph , NamedNode , Namespace , serialize , sym } from "rdflib"
2+ import { AclLogic } from "../types" ;
3+ import { ns as namespace } from '../util/ns'
144
15- import { graph , NamedNode , Namespace , serialize } from "rdflib"
16- import solidNamespace from 'solid-namespace'
17- import * as $rdf from 'rdflib'
18- import { solidLogicSingleton } from "../logic/solidLogicSingleton"
19- import { ACL_LINK } from "../util/UtilityLogic"
205
21- export const ns = solidNamespace ( $rdf )
6+ export const ACL_LINK = sym (
7+ "http://www.iana.org/assignments/link-relations/acl"
8+ ) ;
229
23- export function setACLUserPublic (
24- docURI : string ,
25- me : NamedNode ,
26- options : {
27- defaultForNew ?: boolean ,
28- public ?: [ ]
29- }
30- ) : Promise < NamedNode > {
31- const aclDoc = solidLogicSingleton . store . any (
32- solidLogicSingleton . store . sym ( docURI ) ,
33- ACL_LINK
34- )
10+ export function createAclLogic ( store ) : AclLogic {
3511
36- return Promise . resolve ( )
37- . then ( ( ) => {
38- if ( aclDoc ) {
39- return aclDoc as NamedNode
12+ const ns = namespace
13+
14+ async function findAclDocUrl ( url : NamedNode ) {
15+ await store . fetcher . load ( url ) ;
16+ const docNode = store . any ( url , ACL_LINK ) ;
17+ if ( ! docNode ) {
18+ throw new Error ( `No ACL link discovered for ${ url } ` ) ;
19+ }
20+ return docNode . value ;
4021 }
41-
42- return fetchACLRel ( docURI ) . catch ( err => {
43- throw new Error ( `Error fetching rel=ACL header for ${ docURI } : ${ err } ` )
44- } )
45- } )
46- . then ( aclDoc => {
47- const aclText = genACLText ( docURI , me , aclDoc . uri , options )
48- if ( ! solidLogicSingleton . store . fetcher ) {
49- throw new Error ( 'Cannot PUT this, store has no fetcher' )
22+ /**
23+ * Simple Access Control
24+ *
25+ * This function sets up a simple default ACL for a resource, with
26+ * RWC for the owner, and a specified access (default none) for the public.
27+ * In all cases owner has read write control.
28+ * Parameter lists modes allowed to public
29+ *
30+ * @param options
31+ * @param options.public eg ['Read', 'Write']
32+ *
33+ * @returns Resolves with aclDoc uri on successful write
34+ */
35+ function setACLUserPublic (
36+ docURI : string ,
37+ me : NamedNode ,
38+ options : {
39+ defaultForNew ?: boolean ,
40+ public ?: [ ]
5041 }
51- return solidLogicSingleton . store . fetcher
52- . webOperation ( 'PUT' , aclDoc . uri , {
53- data : aclText ,
54- contentType : 'text/turtle'
55- } )
56- . then ( result => {
57- if ( ! result . ok ) {
58- throw new Error ( 'Error writing ACL text: ' + result . error )
42+ ) : Promise < NamedNode > {
43+ const aclDoc = store . any (
44+ store . sym ( docURI ) ,
45+ ACL_LINK
46+ )
47+
48+ return Promise . resolve ( )
49+ . then ( ( ) => {
50+ if ( aclDoc ) {
51+ return aclDoc as NamedNode
5952 }
6053
61- return aclDoc
54+ return fetchACLRel ( docURI ) . catch ( err => {
55+ throw new Error ( `Error fetching rel=ACL header for ${ docURI } : ${ err } ` )
56+ } )
6257 } )
63- } )
64- }
58+ . then ( aclDoc => {
59+ const aclText = genACLText ( docURI , me , aclDoc . uri , options )
60+ if ( ! store . fetcher ) {
61+ throw new Error ( 'Cannot PUT this, store has no fetcher' )
62+ }
63+ return store . fetcher
64+ . webOperation ( 'PUT' , aclDoc . uri , {
65+ data : aclText ,
66+ contentType : 'text/turtle'
67+ } )
68+ . then ( result => {
69+ if ( ! result . ok ) {
70+ throw new Error ( 'Error writing ACL text: ' + result . error )
71+ }
6572
66- /**
67- * @param docURI
68- * @returns
69- */
70- function fetchACLRel ( docURI : string ) : Promise < NamedNode > {
71- const fetcher = solidLogicSingleton . store . fetcher
72- if ( ! fetcher ) {
73- throw new Error ( 'Cannot fetch ACL rel, store has no fetcher' )
73+ return aclDoc
74+ } )
75+ } )
7476 }
7577
76- return fetcher . load ( docURI ) . then ( result => {
77- if ( ! result . ok ) {
78- throw new Error ( 'fetchACLRel: While loading:' + ( result as any ) . error )
78+ /**
79+ * @param docURI
80+ * @returns
81+ */
82+ function fetchACLRel ( docURI : string ) : Promise < NamedNode > {
83+ const fetcher = store . fetcher
84+ if ( ! fetcher ) {
85+ throw new Error ( 'Cannot fetch ACL rel, store has no fetcher' )
7986 }
8087
81- const aclDoc = solidLogicSingleton . store . any (
82- solidLogicSingleton . store . sym ( docURI ) ,
83- ACL_LINK
84- )
88+ return fetcher . load ( docURI ) . then ( result => {
89+ if ( ! result . ok ) {
90+ throw new Error ( 'fetchACLRel: While loading:' + ( result as any ) . error )
91+ }
8592
86- if ( ! aclDoc ) {
87- throw new Error ( 'fetchACLRel: No Link rel=ACL header for ' + docURI )
88- }
93+ const aclDoc = store . any (
94+ store . sym ( docURI ) ,
95+ ACL_LINK
96+ )
8997
90- return aclDoc as NamedNode
91- } )
92- }
98+ if ( ! aclDoc ) {
99+ throw new Error ( 'fetchACLRel: No Link rel=ACL header for ' + docURI )
100+ }
101+
102+ return aclDoc as NamedNode
103+ } )
104+ }
93105
94- /**
95- * @param docURI
96- * @param me
97- * @param aclURI
98- * @param options
99- *
100- * @returns Serialized ACL
101- */
102- export function genACLText (
103- docURI : string ,
104- me : NamedNode ,
105- aclURI : string ,
106- options : {
107- defaultForNew ?: boolean ,
108- public ?: [ ]
109- } = { }
110- ) : string | undefined {
111- const optPublic = options . public || [ ]
112- const g = graph ( )
113- const auth = Namespace ( 'http://www.w3.org/ns/auth/acl#' )
114- let a = g . sym ( `${ aclURI } #a1` )
115- const acl = g . sym ( aclURI )
116- const doc = g . sym ( docURI )
117- g . add ( a , ns . rdf ( 'type' ) , auth ( 'Authorization' ) , acl )
118- g . add ( a , auth ( 'accessTo' ) , doc , acl )
119- if ( options . defaultForNew ) {
120- g . add ( a , auth ( 'default' ) , doc , acl )
121- }
122- g . add ( a , auth ( 'agent' ) , me , acl )
123- g . add ( a , auth ( 'mode' ) , auth ( 'Read' ) , acl )
124- g . add ( a , auth ( 'mode' ) , auth ( 'Write' ) , acl )
125- g . add ( a , auth ( 'mode' ) , auth ( 'Control' ) , acl )
106+ /**
107+ * @param docURI
108+ * @param me
109+ * @param aclURI
110+ * @param options
111+ *
112+ * @returns Serialized ACL
113+ */
114+ function genACLText (
115+ docURI : string ,
116+ me : NamedNode ,
117+ aclURI : string ,
118+ options : {
119+ defaultForNew ?: boolean ,
120+ public ?: [ ]
121+ } = { }
122+ ) : string | undefined {
123+ const optPublic = options . public || [ ]
124+ const g = graph ( )
125+ const auth = Namespace ( 'http://www.w3.org/ns/auth/acl#' )
126+ let a = g . sym ( `${ aclURI } #a1` )
127+ const acl = g . sym ( aclURI )
128+ const doc = g . sym ( docURI )
129+ g . add ( a , ns . rdf ( 'type' ) , auth ( 'Authorization' ) , acl )
130+ g . add ( a , auth ( 'accessTo' ) , doc , acl )
131+ if ( options . defaultForNew ) {
132+ g . add ( a , auth ( 'default' ) , doc , acl )
133+ }
134+ g . add ( a , auth ( 'agent' ) , me , acl )
135+ g . add ( a , auth ( 'mode' ) , auth ( 'Read' ) , acl )
136+ g . add ( a , auth ( 'mode' ) , auth ( 'Write' ) , acl )
137+ g . add ( a , auth ( 'mode' ) , auth ( 'Control' ) , acl )
126138
127- if ( optPublic . length ) {
128- a = g . sym ( `${ aclURI } #a2` )
129- g . add ( a , ns . rdf ( 'type' ) , auth ( 'Authorization' ) , acl )
130- g . add ( a , auth ( 'accessTo' ) , doc , acl )
131- g . add ( a , auth ( 'agentClass' ) , ns . foaf ( 'Agent' ) , acl )
132- for ( let p = 0 ; p < optPublic . length ; p ++ ) {
133- g . add ( a , auth ( 'mode' ) , auth ( optPublic [ p ] ) , acl ) // Like 'Read' etc
139+ if ( optPublic . length ) {
140+ a = g . sym ( `${ aclURI } #a2` )
141+ g . add ( a , ns . rdf ( 'type' ) , auth ( 'Authorization' ) , acl )
142+ g . add ( a , auth ( 'accessTo' ) , doc , acl )
143+ g . add ( a , auth ( 'agentClass' ) , ns . foaf ( 'Agent' ) , acl )
144+ for ( let p = 0 ; p < optPublic . length ; p ++ ) {
145+ g . add ( a , auth ( 'mode' ) , auth ( optPublic [ p ] ) , acl ) // Like 'Read' etc
146+ }
147+ }
148+ return serialize ( acl , g , aclURI )
149+ }
150+ return {
151+ findAclDocUrl,
152+ setACLUserPublic,
153+ genACLText
134154 }
135- }
136- return serialize ( acl , g , aclURI )
137- }
155+ }
0 commit comments