ldp.stat(metaFile, function (err, metaStats) { if (err) { return callback(err) } if (metaStats && metaStats.isFile()) { ldp.readFile(metaFile, function (err, rawMetadata) { if (err) { return callback(err) } var metadataGraph = $rdf.graph() try { $rdf.parse( rawMetadata, metadataGraph, fileBaseUri, 'text/turtle') } catch (dirErr) { return callback(error(err, 'Can\'t parse container metadata')) } return callback(null, metadataGraph) }) } else { return callback(null, $rdf.graph()) } })
// Parses the given N3 patch document async function parsePatchDocument (targetURI, patchURI, patchText) { // Parse the N3 document into triples const patchGraph = $rdf.graph() try { $rdf.parse(patchText, patchGraph, patchURI, 'text/n3') } catch (err) { throw error(400, `Patch document syntax error: ${err}`) } // Query the N3 document for insertions and deletions let firstResult try { firstResult = await queryForFirstResult(patchGraph, `${PREFIXES} SELECT ?insert ?delete ?where WHERE { ?patch solid:patches <${targetURI}>. OPTIONAL { ?patch solid:inserts ?insert. } OPTIONAL { ?patch solid:deletes ?delete. } OPTIONAL { ?patch solid:where ?where. } }`) } catch (err) { throw error(400, `No patch for ${targetURI} found.`, err) } // Return the insertions and deletions as an rdflib patch document const {'?insert': insert, '?delete': deleted, '?where': where} = firstResult if (!insert && !deleted) { throw error(400, 'Patch should at least contain inserts or deletes.') } return {insert, delete: deleted, where} }
.on('end', function () { const graph = $rdf.graph() $rdf.parse(data, graph, baseUri, from, function (err) { if (err) return reject(err) resolve(serialize(graph, baseUri, to)) }) })
async listContainer (container, reqUri, containerData, hostname) { const resourceGraph = $rdf.graph() try { $rdf.parse(containerData, resourceGraph, reqUri, 'text/turtle') } catch (err) { debug.handlers('GET -- Error parsing data: ' + err) throw error(500, "Can't parse container") } try { // add container stats await ldpContainer.addContainerStats(this, reqUri, container, resourceGraph) // read directory const files = await ldpContainer.readdir(container) // iterate through all the files await Promise.all(files.map(async file => { const { url: fileUri } = await this.resourceMapper.mapFileToUrl( { path: join(container, file), hostname }) return await ldpContainer.addFile(this, resourceGraph, reqUri, fileUri, container, file) })) } catch (err) { throw error(500, "Can't list container") } // TODO 'text/turtle' is fixed, should be contentType instead // This forces one more translation turtle -> desired try { return await serialize(resourceGraph, reqUri, 'text/turtle') } catch (err) { debug.handlers('GET -- Error serializing container: ' + err) throw error(500, "Can't serialize container") } }
it('should add certificate data to a graph', () => { let options = { host, multiuser, authMethod: 'oidc' } let accountManager = AccountManager.from(options) let userData = { username: '******' } let userAccount = accountManager.userAccountFrom(userData) let certificate = WebIdTlsCertificate.fromSpkacPost( decodeURIComponent(exampleSpkac), userAccount, host) let graph = rdf.graph() return certificate.generateCertificate() .then(() => { return accountManager.addCertKeyToGraph(certificate, graph) }) .then(graph => { let webId = rdf.namedNode(certificate.webId) let key = rdf.namedNode(certificate.keyUri) expect(graph.anyStatementMatching(webId, ns.cert('key'), key)) .to.exist expect(graph.anyStatementMatching(key, ns.rdf('type'), ns.cert('RSAPublicKey'))) .to.exist expect(graph.anyStatementMatching(key, ns.cert('modulus'))) .to.exist expect(graph.anyStatementMatching(key, ns.cert('exponent'))) .to.exist }) })
ldp.listContainer(path.join(__dirname, '/resources/sampleContainer/'), 'https://server.tld', '', 'text/turtle', function (err, data) { if (err) done(err) var graph = $rdf.graph() $rdf.parse( data, graph, 'https://server.tld/sampleContainer', 'text/turtle') var basicContainerStatements = graph.each( $rdf.sym('https://server.tld/basicContainerFile.ttl'), ns.rdf('type'), undefined) assert.equal(basicContainerStatements.length, 1) var containerStatements = graph.each( $rdf.sym('https://server.tld/containerFile.ttl'), ns.rdf('type'), undefined) assert.equal(containerStatements.length, 1) basicContainerStatements.forEach(function (statement) { assert.equal(statement.uri, ns.ldp('Resource').uri) }) containerStatements.forEach(function (statement) { assert.equal(statement.uri, ns.ldp('Resource').uri) }) rm('sampleContainer/containerFile.ttl') rm('sampleContainer/basicContainerFile.ttl') done() })
jsonld.toRDF(jsonldObj, {format: 'application/nquads'}, function(err, nquads) { var store = rdflib.graph(); if (err) { console.log(err); } else { try { rdflib.parse(nquads, store, null, 'application/n-quads', function(err) { if (err) { console.log(err); } else { // var base = jsonldObj["@context"] && jsonldObj["@context"]["@base"]; // not using base because is not explicitly set in rdf/xml rdflib.serialize( null, store, null, 'application/rdf+xml', function(err, rdfXml) { if (err) { console.log(err); } else { fs.writeFileSync(path.join(ontologiesDir, 'spa.owl'), rdfXml); console.log('Ontology in RDF/XML regenerated successfully.'); } }); } }); } catch (err) { console.log(err); } } });
ldp.listContainer(path.join(__dirname, '/resources/sampleContainer/'), 'https://server.tld/resources/sampleContainer/', 'https://server.tld', '', 'text/turtle', function (err, data) { if (err) done(err) var graph = $rdf.graph() $rdf.parse( data, graph, 'https://server.tld/sampleContainer', 'text/turtle') var statements = graph .each( $rdf.sym('https://server.tld/magicType.ttl'), ns.rdf('type'), undefined) .map(function (d) { return d.uri }) // statements should be: // [ 'http://www.w3.org/ns/iana/media-types/text/turtle#Resource', // 'http://www.w3.org/ns/ldp#MagicType', // 'http://www.w3.org/ns/ldp#Resource' ] assert.equal(statements.length, 3) assert.isAbove(statements.indexOf('http://www.w3.org/ns/ldp#MagicType'), -1) assert.isAbove(statements.indexOf('http://www.w3.org/ns/ldp#Resource'), -1) rm('sampleContainer/magicType.ttl') done() })
function parse (data, baseUri, contentType, callback) { const graph = $rdf.graph() try { return $rdf.parse(data, graph, baseUri, contentType, callback) } catch (err) { return callback(err) } }
// Parses the given SPARQL UPDATE document async function parsePatchDocument (targetURI, patchURI, patchText) { const baseURI = patchURI.replace(/#.*/, '') try { return $rdf.sparqlUpdateParser(patchText, $rdf.graph(), baseURI) } catch (err) { throw error(400, `Patch document syntax error: ${err}`) } }
request.get(options, function (error, response, body) { assert.equal(error, null) assert.equal(response.statusCode, 200) var globGraph = $rdf.graph() $rdf.parse(body, globGraph, address + testDir + '/', 'text/turtle') var authz = globGraph.the(undefined, undefined, ns.acl('Authorization')) assert.equal(authz, null) done() })
function parse (data, baseUri, contentType, callback) { var graph = $rdf.graph() try { $rdf.parse(data, graph, baseUri, contentType) } catch (err) { return callback(err) } return callback(null, graph) }
isValidRdf (body, requestUri, contentType) { const resourceGraph = $rdf.graph() try { $rdf.parse(body, resourceGraph, requestUri, contentType) } catch (err) { debug.ldp('VALIDATE -- Error parsing data: ' + err) return false } return true }
.then((fileContents) => { const graph = $rdf.graph() debug('PATCH -- Reading %s with content type %s', resource.url, resource.contentType) try { $rdf.parse(fileContents, graph, resource.url, resource.contentType) } catch (err) { throw error(500, `Patch: Target ${resource.contentType} file syntax error: ${err}`) } debug('PATCH -- Parsed target file') return graph })
async function getMetadataGraph (ldp, metaFile) { const metaStats = await ldp.stat(metaFile) if (metaStats && metaStats.isFile()) { try { return await ldp.getGraph(metaFile) } catch (err) { throw error(err, 'Can\'t parse container metadata') } } else { return $rdf.graph() } }
fs.readdir(path.join(__dirname, '../resources/sampleContainer/'), function (err, expectedFiles) { const graph = $rdf.graph() $rdf.parse(data, graph, 'https://server.tld/sampleContainer', 'text/turtle') const statements = graph.match(null, ns.ldp('contains'), null) const files = statements .map(s => s.object.value.replace(/.*\//, '')) .map(decodeURIComponent) files.sort() expectedFiles.sort() assert.deepEqual(files, expectedFiles) done(err) })
// Generates a WebID card and add the key if the cert is passed function createCard (options, cert) { var graph = $rdf.graph() graph.add( sym(options.card), sym('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'), sym('http://xmlns.com/foaf/0.1/PersonalProfileDocument')) graph.add( sym(options.card), sym('http://xmlns.com/foaf/0.1/maker'), sym(options.agent)) graph.add( sym(options.card), sym('http://xmlns.com/foaf/0.1/primaryTopic'), sym(options.agent)) graph.add( sym(options.agent), sym('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'), sym('http://xmlns.com/foaf/0.1/Person')) if (options.name && options.name.length > 0) { graph.add( sym(options.agent), sym('http://xmlns.com/foaf/0.1/name'), lit(options.name)) } graph.add( sym(options.agent), sym('http://www.w3.org/ns/pim/space#storage'), sym(options.url)) if (options.preferences) { graph.add( sym(options.agent), sym('http://www.w3.org/ns/pim/space#preferencesFile'), sym(options.preferences)) } if (options.inbox) { graph.add( sym(options.agent), sym('http://www.w3.org/ns/solid/terms#inbox'), sym(options.inbox)) } if (cert) { addKey(graph, options.agent, cert) } return graph }
LDP.prototype.listContainer = function (filename, uri, containerData, contentType, callback) { var ldp = this var host = url.parse(uri).hostname var root = !ldp.idp ? ldp.root : ldp.root + host + '/' var baseUri = utils.filenameToBaseUri(filename, uri, root) var resourceGraph = $rdf.graph() try { $rdf.parse(containerData, resourceGraph, baseUri, 'text/turtle') } catch (err) { debug.handlers('GET -- Error parsing data: ' + err) return callback(error(500, "Can't parse container")) } async.waterfall([ // add container stats function (next) { ldpContainer.addContainerStats(ldp, filename, resourceGraph, next) }, // reading directory function (next) { ldpContainer.readdir(filename, next) }, // Iterate through all the files function (files, next) { async.each( files, function (file, cb) { ldpContainer.addFile(ldp, resourceGraph, baseUri, uri, filename, file, cb) }, next) } ], function (err, data) { if (err) { return callback(error(500, "Can't list container")) } // TODO 'text/turtle' is fixed, should be contentType instead // This forces one more translation turtle -> desired serialize(resourceGraph, null, 'text/turtle', function (err, result) { if (err) { debug.handlers('GET -- Error serializing container: ' + err) return callback(error(500, "Can't serialize container")) } return callback(null, result) }) }) }
async function parse (data, baseUri, contentType) { const graph = $rdf.graph() return new Promise((resolve, reject) => { try { return $rdf.parse(data, graph, baseUri, contentType, (err, str) => { if (err) { return reject(err) } resolve(str) }) } catch (err) { return reject(err) } }) }
getMetadataGraph(ldp, metaFile, baseUri, function (err, metadataGraph) { if (err) { metadataGraph = $rdf.graph() } // Add Container or BasicContainer types if (stats.isDirectory()) { resourceGraph.add( metadataGraph.sym(fileSubject), ns.rdf('type'), ns.ldp('BasicContainer')) resourceGraph.add( metadataGraph.sym(fileSubject), ns.rdf('type'), ns.ldp('Container')) } // Add generic LDP type resourceGraph.add( metadataGraph.sym(fileSubject), ns.rdf('type'), ns.ldp('Resource')) // Add type from metadataGraph metadataGraph .statementsMatching( metadataGraph.sym(baseUri), ns.rdf('type'), undefined) .forEach(function (typeStatement) { // If the current is a file and its type is BasicContainer, // This is not possible, so do not infer its type! if ( ( typeStatement.object.uri !== ns.ldp('BasicContainer').uri && typeStatement.object.uri !== ns.ldp('Container').uri ) || !stats.isFile() ) { resourceGraph.add( resourceGraph.sym(fileSubject), typeStatement.predicate, typeStatement.object) } }) return callback(null) })
function parseLinkedData(req, res, next) { var ldp = req.app.locals.ldp; var filename = utils.uriToFilename(req.path, ldp.root); var uri = utils.uriBase(req); var turtleData = res.locals.turtleData; var accept = header.parseAcceptRDFHeader(req) || 'text/turtle'; var baseUri = utils.filenameToBaseUri(filename, uri, ldp.root); // Handle Turtle Accept header if (accept === 'text/turtle' || accept === 'text/n3' || accept === 'application/turtle' || accept === 'application/n3') { return res.status(200) .set('content-type', accept) .send(turtleData); } //Handle other file types var resourceGraph = $rdf.graph(); try { $rdf.parse(turtleData, resourceGraph, baseUri, 'text/turtle'); } catch (err) { debug("GET/HEAD -- Error parsing data: " + err.message); return next(new HttpError({ message: err.message, status: 500 })); } // Graph to `accept` type $rdf.serialize(undefined, resourceGraph, null, accept, function(err, result) { if (result === undefined || err) { debug("GET/HEAD -- Serialization error: " + err); return next(new HttpError({ message: err.message, status: 500 })); } return res .status(200) .set('content-type', accept) .send(result); }); }
glob(filename, globOptions, function(err, matches) { if (err || matches.length === 0) { debug("GET/HEAD -- No files matching the pattern"); return next(new HttpError({ message: "No files matching glob pattern", status: 404 })); } // Matches found var globGraph = $rdf.graph(); async.each(matches, function(match, done) { var baseUri = utils.filenameToBaseUri(match, uri, ldp.root); fs.readFile(match, {encoding: "utf8"}, function(err, fileData) { if (err) { debug('GET -- Error in globHandler' + err); return done(null); } aclAllow(match, req, res, function (allowed) { if (!S(match).endsWith(".ttl") || !allowed) { return done(null); } try { $rdf.parse( fileData, globGraph, baseUri, 'text/turtle'); } catch(parseErr) { debug('GET -- Error in globHandler' + parseErr); } return done(null); }); }); }, function () { var data = $rdf.serialize( undefined, globGraph, null, 'text/turtle'); // TODO this should be added as a middleware in the routes res.locals.turtleData = data; return parseLinkedData(req, res, next); }); });
ldp.readFile(metaFile, function (err, rawMetadata) { if (err) { return callback(err) } const metadataGraph = $rdf.graph() try { $rdf.parse( rawMetadata, metadataGraph, fileBaseUri, 'text/turtle') } catch (dirErr) { return callback(error(err, 'Can\'t parse container metadata')) } return callback(null, metadataGraph) })
function createAcl (acl, uri, agent, email) { var graph = $rdf.graph() var owner = acl + '#owner' graph.add( sym(owner), sym('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'), sym('http://www.w3.org/ns/auth/acl#Authorization')) graph.add( sym(owner), sym('http://www.w3.org/ns/auth/acl#accessTo'), sym(uri)) graph.add( sym(owner), sym('http://www.w3.org/ns/auth/acl#accessTo'), sym(uri)) graph.add( sym(owner), sym('http://www.w3.org/ns/auth/acl#agent'), sym(agent)) graph.add( sym(owner), sym('http://www.w3.org/ns/auth/acl#defaultForNew'), sym(uri)) graph.add( sym(owner), sym('http://www.w3.org/ns/auth/acl#mode'), sym('http://www.w3.org/ns/auth/acl#Read')) graph.add( sym(owner), sym('http://www.w3.org/ns/auth/acl#mode'), sym('http://www.w3.org/ns/auth/acl#Write')) graph.add( sym(owner), sym('http://www.w3.org/ns/auth/acl#mode'), sym('http://www.w3.org/ns/auth/acl#Control')) if (email && email.length > 0) { graph.add( sym(owner), sym('http://www.w3.org/ns/auth/acl#agent'), sym('mailto:' + email)) } return graph }
async function getQuota (root, serverUri) { const filename = path.join(root, 'settings/serverSide.ttl') var prefs try { prefs = await _asyncReadfile(filename) } catch (error) { debug('Setting no quota. While reading serverSide.ttl, got ' + error) return Infinity } var graph = $rdf.graph() const storageUri = serverUri + '/' try { $rdf.parse(prefs, graph, storageUri, 'text/turtle') } catch (error) { throw new Error('Failed to parse serverSide.ttl, got ' + error) } return Number(graph.anyValue($rdf.sym(storageUri), ns.solid('storageQuota'))) || Infinity }
it('should save the profile graph via the LDP store', () => { let store = { putGraph: sinon.stub().returns(Promise.resolve()) } let webId = 'https://alice.example.com/#me' let profileHostUri = 'https://alice.example.com/' let userData = { webId } let userAccount = UserAccount.from(userData) let options = { host, multiUser: true, store } let accountManager = AccountManager.from(options) let profileGraph = rdf.graph() return accountManager.saveProfileGraph(profileGraph, userAccount) .then(() => { expect(store.putGraph).to.have.been.calledWith(profileGraph, profileHostUri) }) })
fs.readdir(path.join(__dirname, '/resources/sampleContainer/'), function (err, files) { var graph = $rdf.graph() $rdf.parse( data, graph, 'https://server.tld/sampleContainer', 'text/turtle') var statements = graph.each( undefined, ns.ldp('contains'), undefined) assert.notEqual(graph.statements.length, 0) assert.equal(statements.length, files.length) assert.notOk(err) done() })
glob(filename, globOptions, function (err, matches) { if (err || matches.length === 0) { debugGlob('No files matching the pattern') return next(error(404, 'No files matching glob pattern')) } // Matches found const globGraph = $rdf.graph() debugGlob('found matches ' + matches) Promise.all(matches.map(match => new Promise(async (resolve, reject) => { const urlData = await ldp.resourceMapper.mapFileToUrl({ path: match, hostname: req.hostname }) fs.readFile(match, {encoding: 'utf8'}, function (err, fileData) { if (err) { debugGlob('error ' + err) return resolve() } // Files should be Turtle if (urlData.contentType !== 'text/turtle') { return resolve() } // The agent should have Read access to the file hasReadPermissions(match, req, res, function (allowed) { if (allowed) { try { $rdf.parse(fileData, globGraph, urlData.url, 'text/turtle') } catch (parseErr) { debugGlob(`error parsing ${match}: ${parseErr}`) } } return resolve() }) }) }))) .then(() => { const data = $rdf.serialize(undefined, globGraph, requestUri, 'text/turtle') // TODO this should be added as a middleware in the routes res.setHeader('Content-Type', 'text/turtle') debugGlob('returning turtle') res.send(data) return next() }) })
ldp.readFile(pathAcl, function(err, aclData) { if (err) { debug("Error parsing ACL policy: " + err.message); return callback(err); } var aclGraph = $rdf.graph(); try { $rdf.parse(aclData, aclGraph, pathUri, 'text/turtle'); } catch (err) { debug("Error parsing ACL policy: " + err); return callback(new HttpError({ status: 500, message: err.message })); } return callback(null, aclGraph); });
.end(function (err, data) { if (err) { return done(err) } var graph = $rdf.graph() $rdf.parse( data.text, graph, 'https://nicola.' + host + '/.meta', 'text/turtle') var statements = graph.statementsMatching( undefined, $rdf.sym('http://www.w3.org/ns/solid/terms#account'), undefined) if (statements.length === 1) { done() } else { done(new Error('missing link to WebID of account')) } })