solid-permissions
Version:
Web Access Control based permissions library
159 lines (135 loc) • 5.33 kB
JavaScript
;
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var vocab = require('solid-namespace');
var debug = require('debug')('solid:permissions');
/**
* ACL Group Listing
* @see https://github.com/solid/web-access-control-spec#groups-of-agents
* @class GroupListing
*/
var GroupListing = function () {
/**
* @constructor
* @param [options={}] {Object} Options hashmap
* @param [options.uri] {string|NamedNode} Group URI as appears in ACL file
* (e.g. `https://example.com/groups#management`)
* @param [options.uid] {string} Value of `vcard:hasUID` object
* @param [options.members={}] {Set} Set of group members, by webId
* @param [options.listing] {string|NamedNode} Group listing document URI
* @param [options.rdf] {RDF} RDF library
* @param [options.graph] {Graph} Parsed graph of the group listing document
*/
function GroupListing() {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
_classCallCheck(this, GroupListing);
this.uri = options.uri;
this.uid = options.uid;
this.members = options.members || new Set();
this.listing = options.listing;
this.rdf = options.rdf;
this.graph = options.graph;
if (this.rdf && this.graph) {
this.initFromGraph(this.graph, this.rdf);
}
}
/**
* Factory function, returns a group listing, loaded and initialized
* with the graph from its uri. Will return null if parsing fails,
* which can be used to deny access to the resource.
* @static
* @param uri {string}
* @param fetchGraph {Function}
* @param rdf {RDF}
* @param options {Object} Options hashmap, passed through to fetchGraph()
* @return {Promise<GroupListing|null>}
*/
_createClass(GroupListing, [{
key: 'addMember',
/**
* Adds a member's web id uri to the listing
* @param webId {string|NamedNode}
* @return {GroupListing} Chainable
*/
value: function addMember(webId) {
if (webId.value) {
webId = webId.value;
}
this.members.add(webId);
return this;
}
/**
* Returns the number of members in this listing
* @return {Number}
*/
}, {
key: 'hasMember',
/**
* Tests if a webId uri is present in the members list
* @param webId {string|NamedNode}
* @return {Boolean}
*/
value: function hasMember(webId) {
if (webId.value) {
webId = webId.value;
}
return this.members.has(webId);
}
/**
* @method initFromGraph
* @param [uri] {string|NamedNode} Group URI as appears in ACL file
* (e.g. `https://example.com/groups#management`)
* @param [graph] {Graph} Parsed graph
* @param [rdf] {RDF}
* @throws {Error}
* @return {GroupListing} Chainable
*/
}, {
key: 'initFromGraph',
value: function initFromGraph() {
var uri = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.uri;
var _this = this;
var graph = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.graph;
var rdf = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.rdf;
if (!uri) {
throw new Error('Group URI required to init from graph');
}
if (!graph || !rdf) {
throw new Error('initFromGraph() - graph or rdf library missing');
}
var ns = vocab(rdf);
var group = rdf.namedNode(uri);
var rdfType = graph.any(group, null, ns.vcard('Group'));
if (!rdfType) {
console.warn('Possibly invalid group \'' + uri + '\', missing type vcard:Group');
}
this.uid = graph.anyValue(group, ns.vcard('hasUID'));
debug('Found Group Listing with ' + group);
graph.match(group, ns.vcard('hasMember')).forEach(function (memberMatch) {
_this.addMember(memberMatch.object);
});
return this;
}
}, {
key: 'count',
get: function get() {
return this.members.size;
}
}], [{
key: 'loadFrom',
value: function loadFrom(uri, fetchGraph, rdf) {
var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
debug('Trying to find a Group Listing in ' + uri);
var group = new GroupListing({ uri: uri, rdf: rdf });
return fetchGraph(uri, options).then(function (graph) {
return group.initFromGraph(uri, graph);
}).catch(function (err) {
// Returning null will result in deny, which is suitable in this case
console.error(err);
return null;
});
}
}]);
return GroupListing;
}();
module.exports = GroupListing;