diff --git a/lib/acl-checker.js b/lib/acl-checker.js index 0ab18c4f7..8cda9d396 100644 --- a/lib/acl-checker.js +++ b/lib/acl-checker.js @@ -117,8 +117,9 @@ class ACLChecker { debug(`${mode} access permitted to ${user}`) return callback() } else { - debug(`${mode} access not permitted to ${user}`) - return callback(new Error('Acl found but policy not found')) + debug(`${mode} access NOT permitted to ${user}` + + aclOptions.strictOrigin ? ` and origin ${options.origin}` : '') + return callback(new Error('ACL file found but no matching policy found')) } }) .catch(err => { diff --git a/lib/ldp-container.js b/lib/ldp-container.js index bb313c7f1..a9320770b 100644 --- a/lib/ldp-container.js +++ b/lib/ldp-container.js @@ -10,7 +10,7 @@ var error = require('./http-error') var fs = require('fs') var ns = require('solid-namespace')($rdf) var S = require('string') -var turtleExtension = '.ttl' +// var turtleExtension = '.ttl' var mime = require('mime-types') function addContainerStats (ldp, reqUri, filename, resourceGraph, next) { @@ -58,9 +58,9 @@ function addFile (ldp, resourceGraph, containerUri, reqUri, uri, container, file resourceGraph.sym(memberUri)) // Set up a metaFile path - var metaFile = container + file + - (stats.isDirectory() ? '/' : '') + - (S(file).endsWith(turtleExtension) ? '' : ldp.suffixMeta) + // Earlier code used a .ttl file as its own meta file, which + // caused massive data files to parsed as part of deirectory listings just looking for type triples + var metaFile = container + file + ldp.suffixMeta getMetadataGraph(ldp, metaFile, memberUri, function (err, metadataGraph) { if (err) { @@ -147,7 +147,7 @@ function readdir (filename, callback) { return callback(error(err, 'Can\'t read container')) } - debug.handlers('Files in directory: ' + files) + debug.handlers('Files in directory: ' + files.toString().slice(0, 100)) return callback(null, files) }) } diff --git a/lib/ldp.js b/lib/ldp.js index 0b3cfd748..93ba279b4 100644 --- a/lib/ldp.js +++ b/lib/ldp.js @@ -157,7 +157,7 @@ class LDP { async.each( files, function (file, cb) { - let fileUri = reqUri + file + let fileUri = reqUri + encodeURIComponent(file) ldpContainer.addFile(ldp, resourceGraph, reqUri, fileUri, uri, filename, file, cb) }, @@ -185,7 +185,11 @@ class LDP { debug.handlers('POST -- On parent: ' + containerPath) // prepare slug if (slug) { - slug = encodeURIComponent(slug) + slug = decodeURIComponent(slug) + if (slug.match(/\/|\||:/)) { + callback(error(400, 'The name of new file POSTed may not contain : | or /')) + return + } } // TODO: possibly package this in ldp.post ldp.getAvailablePath(hostname, containerPath, slug, function (resourcePath) { @@ -293,7 +297,7 @@ class LDP { ldp.stat(filename, function (err, stats) { // File does not exist if (err) { - return callback(error(err, "Can't find resource requested")) + return callback(error(err, 'Can\'t find file requested: ' + filename)) } // Just return, since resource exists diff --git a/lib/utils.js b/lib/utils.js index 1ec040912..d54c025d4 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -33,7 +33,8 @@ function debrack (s) { } function uriToFilename (uri, base) { - var filename = path.join(base, uri) + var decoded = uri.split('/').map(decodeURIComponent).join('/') + var filename = path.join(base, decoded) // Make sure filename ends with '/' if filename exists and is a directory. // TODO this sync operation can be avoided and can be left // to do, to other components, see `ldp.get` diff --git a/test/http.js b/test/http.js index 717184d11..8306e11af 100644 --- a/test/http.js +++ b/test/http.js @@ -546,6 +546,29 @@ describe('HTTP APIs', function () { .expect(200, done) }) + it('should create a container with a name hex decoded from the slug', (done) => { + let containerName = 'Film%4011' + let expectedDirName = '/post-tests/Film@11/' + server.post('/post-tests/') + .set('slug', containerName) + .set('content-type', 'text/turtle') + .set('link', '; rel="type"') + .expect(201) + .end((err, res) => { + if (err) return done(err) + try { + assert.equal(res.headers.location, expectedDirName, + 'Uri container names should be encoded') + let createdDir = fs.statSync(path.join(__dirname, 'resources', expectedDirName)) + assert(createdDir.isDirectory(), 'Container should have been created') + } catch (err) { + return done(err) + } + done() + }) + }) + + /* No, URLs are NOT ex-encoded to make filenames -- the other way around. it('should create a container with a url name', (done) => { let containerName = 'https://example.com/page' let expectedDirName = '/post-tests/https%3A%2F%2Fexample.com%2Fpage/' @@ -574,6 +597,7 @@ describe('HTTP APIs', function () { .expect('content-type', /text\/turtle/) .expect(200, done) }) + */ after(function () { // Clean up after POST API tests diff --git a/test/ldp.js b/test/ldp.js index e19e54bb7..27832f82f 100644 --- a/test/ldp.js +++ b/test/ldp.js @@ -109,6 +109,7 @@ describe('LDP', function () { }) }) describe('listContainer', function () { + /* it('should inherit type if file is .ttl', function (done) { write('@prefix dcterms: .' + '@prefix o: .' + @@ -145,7 +146,7 @@ describe('LDP', function () { done() }) }) - +*/ it('should not inherit type of BasicContainer/Container if type is File', function (done) { write('@prefix dcterms: .' + '@prefix o: .' + diff --git a/test/utils.js b/test/utils.js index 4b05a47eb..6da738ec9 100644 --- a/test/utils.js +++ b/test/utils.js @@ -19,8 +19,16 @@ describe('Utility functions', function () { it('should return empty as relative path for undefined path', function () { assert.equal(utils.pathBasename(undefined), '') }) - it('should not decode uris', function () { - assert.equal(utils.uriToFilename('uri%20', 'base/'), 'base/uri%20') + }) + describe('uriToFilename', function () { + it('should decode hex-encoded space', function () { + assert.equal(utils.uriToFilename('uri%20', 'base/'), 'base/uri ') + }) + it('should decode hex-encoded at sign', function () { + assert.equal(utils.uriToFilename('film%4011', 'base/'), 'base/film@11') + }) + it('should decode hex-encoded single quote', function () { + assert.equal(utils.uriToFilename('quote%27', 'base/'), 'base/quote\'') }) }) })