Skip to content

Commit

Permalink
Merge pull request #1726 from nodeSolidServer/resourceName
Browse files Browse the repository at this point in the history
checkItmName recursively & reject resource with $.ext
  • Loading branch information
bourgeoa authored Apr 6, 2023
2 parents 31b4ed4 + 74a3d61 commit bbb8d78
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 13 deletions.
27 changes: 22 additions & 5 deletions lib/ldp.js
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,14 @@ class LDP {
'PUT request requires a content-type via the Content-Type header')
}

// reject resource with percent-encoded $ extension
const dollarExtensionRegex = /%(?:24)\.[^%(?:24)]*$/ // /\$\.[^$]*$/
if ((url.url || url).match(dollarExtensionRegex)) {
throw error(400, 'Resource with a $.ext is not allowed by the server')
}

// check if a folder or file with same name exists
// const urlItem = url.url || url
await this.checkItemName(url)

// First check if we are above quota
Expand Down Expand Up @@ -350,17 +357,27 @@ class LDP {

async checkItemName (url) {
let testName
const itemUrl = (url.url || url)
const { hostname, pathname } = this.resourceMapper._parseUrl(url) // (url.url || url)
let itemUrl = this.resourceMapper.resolveUrl(hostname, pathname)
const container = itemUrl.endsWith('/')
try {
const testUrl = container ? itemUrl.slice(0, -1) : itemUrl + '/'
const { path: testPath } = await this.resourceMapper.mapUrlToFile({ url: testUrl })
// testName = fs.lstatSync(testPath).isDirectory()
testName = container ? fs.lstatSync(testPath).isFile() : fs.lstatSync(testPath).isDirectory()
} catch (err) { testName = false }

} catch (err) {
testName = false

// item does not exist, check one level up the tree
if (itemUrl.endsWith('/')) itemUrl = itemUrl.substring(0, itemUrl.length - 1)
itemUrl = itemUrl.substring(0, itemUrl.lastIndexOf('/') + 1)
const { pathname } = this.resourceMapper._parseUrl(itemUrl) // (url.url || url)
// check not at root
if (pathname !== '/') {
await this.checkItemName(itemUrl)
}
}
if (testName) {
throw error(200, 'Container and resource cannot have the same name in URI')
throw error(404, 'Container and resource cannot have the same name in URI')
}
}

Expand Down
28 changes: 22 additions & 6 deletions test/integration/http-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -535,13 +535,29 @@ describe('HTTP APIs', function () {
.expect(hasHeader('acl', 'baz.ttl' + suffixAcl))
.expect(201, done)
})
it('should not create new resource if folder with same name exists', function (done) {
server.put('/foo/bar')
it('should not create a resource with percent-encoded $.ext', function (done) {
server.put('/foo/bar/baz%24.ttl')
.send(putRequestBody)
.set('content-type', 'text/turtle')
.expect(hasHeader('describedBy', 'bar' + suffixMeta))
.expect(hasHeader('acl', 'bar' + suffixAcl))
.expect(200, done)
// .expect(hasHeader('describedBy', 'baz.ttl' + suffixMeta))
// .expect(hasHeader('acl', 'baz.ttl' + suffixAcl))
.expect(400, done) // 404
})
it('should create a resource without extension', function (done) {
server.put('/foo/bar/baz')
.send(putRequestBody)
.set('content-type', 'text/turtle')
.expect(hasHeader('describedBy', 'baz' + suffixMeta))
.expect(hasHeader('acl', 'baz' + suffixAcl))
.expect(201, done)
})
it('should not create new resource if a folder/resource with same name will exist in tree', function (done) {
server.put('/foo/bar/baz/test.ttl')
.send(putRequestBody)
.set('content-type', 'text/turtle')
.expect(hasHeader('describedBy', 'test.ttl' + suffixMeta))
.expect(hasHeader('acl', 'test.ttl' + suffixAcl))
.expect(404, done)
})
it('should return 201 when trying to put to a container without content-type',
function (done) {
Expand Down Expand Up @@ -587,7 +603,7 @@ describe('HTTP APIs', function () {
return Promise.all([
rm('/false-file-48484848'),
createTestResource('/.acl'),
createTestResource('/profile/card$.ttl'),
createTestResource('/profile/card'),
createTestResource('/delete-test-empty-container/.meta.acl'),
createTestResource('/put-resource-1.ttl'),
createTestResource('/put-resource-with-acl.ttl'),
Expand Down
4 changes: 2 additions & 2 deletions test/integration/ldp-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -162,13 +162,13 @@ describe('LDP', function () {

it.skip('with a larger file to exceed allowed quota', function () {
const randstream = stringToStream(randomBytes(2100))
return ldp.put('localhost', '/resources/testQuota.txt', randstream).catch((err) => {
return ldp.put('/localhost', '/resources/testQuota.txt', randstream).catch((err) => {
assert.notOk(err)
})
})
it('should fail if a over quota', function () {
const hellostream = stringToStream('hello world')
return ldp.put('localhost', '/resources/testOverQuota.txt', hellostream).catch((err) => {
return ldp.put('/localhost', '/resources/testOverQuota.txt', hellostream).catch((err) => {
assert.equal(err.status, 413)
})
})
Expand Down

0 comments on commit bbb8d78

Please sign in to comment.