55 * @module authorization
66 */
77
8- var hash = require ( 'shorthash' )
98var vocab = require ( 'solid-namespace' )
109
1110/**
@@ -24,12 +23,6 @@ function modes () {
2423 return acl
2524}
2625
27- /**
28- * Inherited authorization (acl:defaultForNew)
29- * @type {Boolean }
30- */
31- var INHERIT = true
32-
3326/**
3427 * Models an individual authorization object, for a single resource and for
3528 * a single webId (either agent or agentClass). See the comments at the top
@@ -54,6 +47,15 @@ class Authorization {
5447 * @type {Object }
5548 */
5649 this . accessModes = { }
50+ /**
51+ * Type of authorization, either for a specific resource ('accessTo'),
52+ * or to be inherited by all downstream resources ('default')
53+ * @property accessType
54+ * @type {String } Either 'accessTo' or 'default'
55+ */
56+ this . accessType = inherited
57+ ? Authorization . DEFAULT
58+ : Authorization . ACCESS_TO
5759 /**
5860 * URL of an agent's WebID (`acl:agent`). Inside an authorization, mutually
5961 * exclusive with the `group` property. Set via `setAgent()`.
@@ -96,6 +98,14 @@ class Authorization {
9698 * @type {String }
9799 */
98100 this . resourceUrl = resourceUrl
101+ /**
102+ * Should this authorization be serialized? (When writing back to an ACL
103+ * resource, for example.) Used for implied (rather than explicit)
104+ * authorization, such as ones that are derived from acl:Control statements.
105+ * @property virtual
106+ * @type {Boolean }
107+ */
108+ this . virtual = false
99109 }
100110
101111 /**
@@ -105,7 +115,7 @@ class Authorization {
105115 */
106116 addMailTo ( agent ) {
107117 if ( typeof agent !== 'string' ) {
108- agent = agent . object . uri
118+ agent = agent . object . value
109119 }
110120 if ( agent . startsWith ( 'mailto:' ) ) {
111121 agent = agent . split ( ':' ) [ 1 ]
@@ -122,15 +132,14 @@ class Authorization {
122132 * @return {Authorization } Returns self, chainable.
123133 */
124134 addMode ( accessMode ) {
125- var self = this
126135 if ( Array . isArray ( accessMode ) ) {
127- accessMode . forEach ( ( ea ) => {
128- self . addModeSingle ( ea )
136+ accessMode . forEach ( ea => {
137+ this . addModeSingle ( ea )
129138 } )
130139 } else {
131- self . addModeSingle ( accessMode )
140+ this . addModeSingle ( accessMode )
132141 }
133- return self
142+ return this
134143 }
135144
136145 /**
@@ -142,7 +151,7 @@ class Authorization {
142151 */
143152 addModeSingle ( accessMode ) {
144153 if ( typeof accessMode !== 'string' ) {
145- accessMode = accessMode . object . uri
154+ accessMode = accessMode . object . value
146155 }
147156 this . accessModes [ accessMode ] = true
148157 return this
@@ -157,15 +166,14 @@ class Authorization {
157166 * @return {Authorization } Returns self, chainable.
158167 */
159168 addOrigin ( origin ) {
160- var self = this
161169 if ( Array . isArray ( origin ) ) {
162170 origin . forEach ( ( ea ) => {
163- self . addOriginSingle ( ea )
171+ this . addOriginSingle ( ea )
164172 } )
165173 } else {
166- self . addOriginSingle ( origin )
174+ this . addOriginSingle ( origin )
167175 }
168- return self
176+ return this
169177 }
170178
171179 /**
@@ -177,7 +185,7 @@ class Authorization {
177185 */
178186 addOriginSingle ( origin ) {
179187 if ( typeof origin !== 'string' ) {
180- origin = origin . object . uri
188+ origin = origin . object . value
181189 }
182190 this . originsAllowed [ origin ] = true
183191 return this
@@ -258,6 +266,16 @@ class Authorization {
258266 return this . accessModes [ Authorization . acl . CONTROL ]
259267 }
260268
269+ /**
270+ * Returns a deep copy of this authorization.
271+ * @return {Authorization }
272+ */
273+ clone ( ) {
274+ let auth = new Authorization ( )
275+ Object . assign ( auth , JSON . parse ( JSON . stringify ( this ) ) )
276+ return auth
277+ }
278+
261279 /**
262280 * Compares this authorization with another one.
263281 * Authorizations are equal iff they:
@@ -303,7 +321,8 @@ class Authorization {
303321 if ( ! this . webId || ! this . resourceUrl ) {
304322 throw new Error ( 'Cannot call hashFragment() on an incomplete authorization' )
305323 }
306- var hashFragment = hashFragmentFor ( this . webId ( ) , this . resourceUrl )
324+ var hashFragment = hashFragmentFor ( this . webId ( ) , this . resourceUrl ,
325+ this . accessType )
307326 return hashFragment
308327 }
309328
@@ -399,6 +418,10 @@ class Authorization {
399418 if ( ! this . webId ( ) || ! this . resourceUrl ) {
400419 return [ ] // This Authorization is invalid, return empty array
401420 }
421+ // Virtual / implied authorizations are not serialized
422+ if ( this . virtual ) {
423+ return [ ]
424+ }
402425 var statement
403426 var fragment = rdf . namedNode ( '#' + this . hashFragment ( ) )
404427 var ns = vocab ( rdf )
@@ -452,15 +475,14 @@ class Authorization {
452475 * @returns {removeMode }
453476 */
454477 removeMode ( accessMode ) {
455- var self = this
456478 if ( Array . isArray ( accessMode ) ) {
457479 accessMode . forEach ( ( ea ) => {
458- self . removeModeSingle ( ea )
480+ this . removeModeSingle ( ea )
459481 } )
460482 } else {
461- self . removeModeSingle ( accessMode )
483+ this . removeModeSingle ( accessMode )
462484 }
463- return self
485+ return this
464486 }
465487
466488 /**
@@ -472,7 +494,7 @@ class Authorization {
472494 */
473495 removeModeSingle ( accessMode ) {
474496 if ( typeof accessMode !== 'string' ) {
475- accessMode = accessMode . object . uri
497+ accessMode = accessMode . object . value
476498 }
477499 delete this . accessModes [ accessMode ]
478500 }
@@ -485,15 +507,14 @@ class Authorization {
485507 * @returns {removeMode }
486508 */
487509 removeOrigin ( accessMode ) {
488- var self = this
489510 if ( Array . isArray ( accessMode ) ) {
490511 accessMode . forEach ( ( ea ) => {
491- self . removeOriginSingle ( ea )
512+ this . removeOriginSingle ( ea )
492513 } )
493514 } else {
494- self . removeOriginSingle ( accessMode )
515+ this . removeOriginSingle ( accessMode )
495516 }
496- return self
517+ return this
497518 }
498519
499520 /**
@@ -505,7 +526,7 @@ class Authorization {
505526 */
506527 removeOriginSingle ( origin ) {
507528 if ( typeof origin !== 'string' ) {
508- origin = origin . object . uri
529+ origin = origin . object . value
509530 }
510531 delete this . originsAllowed [ origin ]
511532 }
@@ -515,12 +536,12 @@ class Authorization {
515536 * setter method to enforce mutual exclusivity with `group` property, until
516537 * ES6 setter methods become available.
517538 * @method setAgent
518- * @param agent {String|Statement } Agent URL (or `acl:agent` RDF triple).
539+ * @param agent {String|Quad } Agent URL (or `acl:agent` RDF triple).
519540 */
520541 setAgent ( agent ) {
521542 if ( typeof agent !== 'string' ) {
522543 // This is an RDF statement
523- agent = agent . object . uri
544+ agent = agent . object . value
524545 }
525546 if ( agent === Authorization . acl . EVERYONE ) {
526547 this . setPublic ( )
@@ -545,7 +566,7 @@ class Authorization {
545566 setGroup ( agentClass ) {
546567 if ( typeof agentClass !== 'string' ) {
547568 // This is an RDF statement
548- agentClass = agentClass . object . uri
569+ agentClass = agentClass . object . value
549570 }
550571 if ( this . agent ) {
551572 throw new Error ( 'Cannot set group, authorization already has an agent set' )
@@ -571,22 +592,33 @@ class Authorization {
571592 }
572593}
573594// --- Standalone (non-instance) functions --
574-
575595/**
576596 * Utility method that creates a hash fragment key for this authorization.
577597 * Used with graph serialization to RDF, and as a key to store authorizations
578598 * in a PermissionSet. Exported (mainly for use in PermissionSet).
579599 * @method hashFragmentFor
580- * @param webId {String}
581- * @param resourceUrl {String}
600+ * @param webId {String} Agent or group web id
601+ * @param resourceUrl {String} Resource or container URL for this authorization
602+ * @param [authType='accessTo'] {String} Either 'accessTo' or 'default'
582603 * @return {String }
583604 */
584- function hashFragmentFor ( webId , resourceUrl ) {
585- var hashKey = webId + '-' + resourceUrl
586- return hash . unique ( hashKey )
605+ function hashFragmentFor ( webId , resourceUrl ,
606+ authType = Authorization . ACCESS_TO ) {
607+ var hashKey = webId + '-' + resourceUrl + '-' + authType
608+ return hashKey
587609}
588610Authorization . acl = modes ( )
611+ Authorization . ALL_MODES = [
612+ Authorization . acl . READ ,
613+ Authorization . acl . WRITE ,
614+ Authorization . acl . CONTROL
615+ ]
589616Authorization . hashFragmentFor = hashFragmentFor
590- Authorization . INHERIT = INHERIT
617+
618+ // Exported constants, for convenience / readability
619+ Authorization . INHERIT = true
620+ Authorization . NOT_INHERIT = ! Authorization . INHERIT
621+ Authorization . ACCESS_TO = 'accessTo'
622+ Authorization . DEFAULT = 'default'
591623
592624module . exports = Authorization
0 commit comments