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 : string ) {
15+ const doc = store . sym ( url ) ;
16+ await store . fetcher . load ( doc ) ;
17+ const docNode = store . any ( doc , ACL_LINK ) ;
18+ if ( ! docNode ) {
19+ throw new Error ( `No ACL link discovered for ${ url } ` ) ;
20+ }
21+ return docNode . value ;
4022 }
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' )
23+ /**
24+ * Simple Access Control
25+ *
26+ * This function sets up a simple default ACL for a resource, with
27+ * RWC for the owner, and a specified access (default none) for the public.
28+ * In all cases owner has read write control.
29+ * Parameter lists modes allowed to public
30+ *
31+ * @param options
32+ * @param options.public eg ['Read', 'Write']
33+ *
34+ * @returns Resolves with aclDoc uri on successful write
35+ */
36+ function setACLUserPublic (
37+ docURI : string ,
38+ me : NamedNode ,
39+ options : {
40+ defaultForNew ?: boolean ,
41+ public ?: [ ]
5042 }
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 )
43+ ) : Promise < NamedNode > {
44+ const aclDoc = store . any (
45+ store . sym ( docURI ) ,
46+ ACL_LINK
47+ )
48+
49+ return Promise . resolve ( )
50+ . then ( ( ) => {
51+ if ( aclDoc ) {
52+ return aclDoc as NamedNode
5953 }
6054
61- return aclDoc
55+ return fetchACLRel ( docURI ) . catch ( err => {
56+ throw new Error ( `Error fetching rel=ACL header for ${ docURI } : ${ err } ` )
57+ } )
6258 } )
63- } )
64- }
59+ . then ( aclDoc => {
60+ const aclText = genACLText ( docURI , me , aclDoc . uri , options )
61+ if ( ! store . fetcher ) {
62+ throw new Error ( 'Cannot PUT this, store has no fetcher' )
63+ }
64+ return store . fetcher
65+ . webOperation ( 'PUT' , aclDoc . uri , {
66+ data : aclText ,
67+ contentType : 'text/turtle'
68+ } )
69+ . then ( result => {
70+ if ( ! result . ok ) {
71+ throw new Error ( 'Error writing ACL text: ' + result . error )
72+ }
6573
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' )
74+ return aclDoc
75+ } )
76+ } )
7477 }
7578
76- return fetcher . load ( docURI ) . then ( result => {
77- if ( ! result . ok ) {
78- throw new Error ( 'fetchACLRel: While loading:' + ( result as any ) . error )
79+ /**
80+ * @param docURI
81+ * @returns
82+ */
83+ function fetchACLRel ( docURI : string ) : Promise < NamedNode > {
84+ const fetcher = store . fetcher
85+ if ( ! fetcher ) {
86+ throw new Error ( 'Cannot fetch ACL rel, store has no fetcher' )
7987 }
8088
81- const aclDoc = solidLogicSingleton . store . any (
82- solidLogicSingleton . store . sym ( docURI ) ,
83- ACL_LINK
84- )
89+ return fetcher . load ( docURI ) . then ( result => {
90+ if ( ! result . ok ) {
91+ throw new Error ( 'fetchACLRel: While loading:' + ( result as any ) . error )
92+ }
8593
86- if ( ! aclDoc ) {
87- throw new Error ( 'fetchACLRel: No Link rel=ACL header for ' + docURI )
88- }
94+ const aclDoc = store . any (
95+ store . sym ( docURI ) ,
96+ ACL_LINK
97+ )
8998
90- return aclDoc as NamedNode
91- } )
92- }
99+ if ( ! aclDoc ) {
100+ throw new Error ( 'fetchACLRel: No Link rel=ACL header for ' + docURI )
101+ }
102+
103+ return aclDoc as NamedNode
104+ } )
105+ }
93106
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 )
107+ /**
108+ * @param docURI
109+ * @param me
110+ * @param aclURI
111+ * @param options
112+ *
113+ * @returns Serialized ACL
114+ */
115+ function genACLText (
116+ docURI : string ,
117+ me : NamedNode ,
118+ aclURI : string ,
119+ options : {
120+ defaultForNew ?: boolean ,
121+ public ?: [ ]
122+ } = { }
123+ ) : string | undefined {
124+ const optPublic = options . public || [ ]
125+ const g = graph ( )
126+ const auth = Namespace ( 'http://www.w3.org/ns/auth/acl#' )
127+ let a = g . sym ( `${ aclURI } #a1` )
128+ const acl = g . sym ( aclURI )
129+ const doc = g . sym ( docURI )
130+ g . add ( a , ns . rdf ( 'type' ) , auth ( 'Authorization' ) , acl )
131+ g . add ( a , auth ( 'accessTo' ) , doc , acl )
132+ if ( options . defaultForNew ) {
133+ g . add ( a , auth ( 'default' ) , doc , acl )
134+ }
135+ g . add ( a , auth ( 'agent' ) , me , acl )
136+ g . add ( a , auth ( 'mode' ) , auth ( 'Read' ) , acl )
137+ g . add ( a , auth ( 'mode' ) , auth ( 'Write' ) , acl )
138+ g . add ( a , auth ( 'mode' ) , auth ( 'Control' ) , acl )
126139
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
140+ if ( optPublic . length ) {
141+ a = g . sym ( `${ aclURI } #a2` )
142+ g . add ( a , ns . rdf ( 'type' ) , auth ( 'Authorization' ) , acl )
143+ g . add ( a , auth ( 'accessTo' ) , doc , acl )
144+ g . add ( a , auth ( 'agentClass' ) , ns . foaf ( 'Agent' ) , acl )
145+ for ( let p = 0 ; p < optPublic . length ; p ++ ) {
146+ g . add ( a , auth ( 'mode' ) , auth ( optPublic [ p ] ) , acl ) // Like 'Read' etc
147+ }
148+ }
149+ return serialize ( acl , g , aclURI )
150+ }
151+ return {
152+ findAclDocUrl,
153+ setACLUserPublic,
154+ genACLText
134155 }
135- }
136- return serialize ( acl , g , aclURI )
137- }
156+ }
0 commit comments