Skip to content

Commit 47100fc

Browse files
committed
Append with PUT
1 parent 208c67b commit 47100fc

File tree

2 files changed

+46
-34
lines changed

2 files changed

+46
-34
lines changed

lib/handlers/put.js

Lines changed: 7 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ async function handler (req, res, next) {
1212

1313
const contentType = req.get('content-type')
1414
// check for valid rdf content for auxiliary resource and /profile/card
15-
// in future we may check that /profile/card is a minimal valid WebID card
15+
// TODO check that /profile/card is a minimal valid WebID card
1616
if (isAuxiliary(req) || req.originalUrl === '/profile/card') {
1717
if (contentType === 'text/turtle') {
1818
return bodyParser.text({ type: () => true })(req, res, () => putValidRdf(req, res, next))
@@ -30,14 +30,15 @@ async function checkPermission (request, resourceExists) {
3030
let modes = []
3131
// acl:default Write is required for PUT when Resource Exists
3232
if (resourceExists) modes = ['Write']
33+
// if (resourceExists && request.originalUrl.endsWith('.acl')) modes = ['Control']
3334
const { acl, session: { userId } } = request
3435

3536
const allowed = await Promise.all(modes.map(mode => acl.can(userId, mode, request.method, resourceExists)))
3637
const allAllowed = allowed.reduce((memo, allowed) => memo && allowed, true)
3738
if (!allAllowed) {
3839
// check owner with Control
39-
const ldp = request.app.locals.ldp
40-
if (request.path.endsWith('.acl') && userId === await ldp.getOwner(request.hostname)) return Promise.resolve()
40+
// const ldp = request.app.locals.ldp
41+
// if (request.path.endsWith('.acl') && userId === await ldp.getOwner(request.hostname)) return Promise.resolve()
4142

4243
const errors = await Promise.all(modes.map(mode => acl.getError(userId, mode)))
4344
const error = errors.filter(error => !!error)
@@ -47,51 +48,29 @@ async function checkPermission (request, resourceExists) {
4748
return Promise.resolve()
4849
}
4950

51+
// TODO could be renamed as putResource (it now covers container and non-container)
5052
async function putStream (req, res, next, stream = req) {
5153
const ldp = req.app.locals.ldp
5254
// try {
5355
// Obtain details of the target resource
54-
// const ldp = req.app.locals.ldp
55-
// let path, contentType
5656
let resourceExists = true
5757
try {
5858
// First check if the file already exists
59-
// ({ path, contentType } = await ldp.resourceMapper.mapUrlToFile({ url: req }))
60-
await ldp.resourceMapper.mapUrlToFile({ url: req, createIfNotExists: true })
59+
await ldp.resourceMapper.mapUrlToFile({ url: req })
6160
} catch (err) {
62-
// await ldp.checkItemName(req)
6361
resourceExists = false
6462
}
6563
try {
66-
await checkPermission(req, resourceExists)
67-
debug('test ' + req.get('content-type') + getContentType(req.headers))
64+
if (!req.originalUrl.endsWith('.acl')) await checkPermission(req, resourceExists)
6865
await ldp.put(req, stream, getContentType(req.headers))
69-
debug('succeded putting the file/folder')
7066
res.sendStatus(201)
7167
return next()
7268
} catch (err) {
73-
debug('error putting the file/folder:' + err.message)
7469
err.message = 'Can\'t write file/folder: ' + err.message
7570
return next(err)
7671
}
7772
}
7873

79-
// TODO could be renamed as putResource (it now covers container and non-container)
80-
/* async function putStream (req, res, next, stream = req) {
81-
const ldp = req.app.locals.ldp
82-
try {
83-
debug('test ' + req.get('content-type') + getContentType(req.headers))
84-
await ldp.put(req, stream, getContentType(req.headers))
85-
debug('succeded putting the file/folder')
86-
res.sendStatus(201)
87-
return next()
88-
} catch (err) {
89-
debug('error putting the file/folder:' + err.message)
90-
err.message = 'Can\'t write file/folder: ' + err.message
91-
return next(err)
92-
}
93-
} */
94-
9574
// needed to avoid breaking access with bad acl
9675
// or breaking containement triples for meta
9776
function putValidRdf (req, res, next) {

test/integration/acl-oidc-test.js

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ describe('ACL with WebID+OIDC over HTTP', function () {
138138
done()
139139
})
140140
})
141-
it('user1 as solid:owner should let edit the .acl', function (done) {
141+
it('user1 as solid:owner should let edit the .acl', function (done) { // alain
142142
const options = createOptions('/empty-acl/.acl', 'user1', 'text/turtle')
143143
options.body = ''
144144
request.put(options, function (error, response, body) {
@@ -209,7 +209,7 @@ describe('ACL with WebID+OIDC over HTTP', function () {
209209
done()
210210
})
211211
})
212-
it('Should not create empty acl file', function (done) {
212+
it('Should not create empty acl file', function (done) { // alain
213213
const options = createOptions('/write-acl/empty-acl/another-empty-folder/.acl', 'user1', 'text/turtle')
214214
options.body = ''
215215
request.put(options, function (error, response, body) {
@@ -273,7 +273,7 @@ describe('ACL with WebID+OIDC over HTTP', function () {
273273
})
274274

275275
describe('no-control', function () {
276-
it('user1 as owner should edit acl file', function (done) {
276+
it('user1 as owner should edit acl file', function (done) { // alain
277277
const options = createOptions('/no-control/.acl', 'user1', 'text/turtle')
278278
options.body = '<#0>' +
279279
'\n a <http://www.w3.org/ns/auth/acl#Authorization>;' +
@@ -571,6 +571,27 @@ describe('ACL with WebID+OIDC over HTTP', function () {
571571
done()
572572
})
573573
})
574+
it('user1 should be able to PUT (which CREATEs) (non existent resource)', function (done) {
575+
const options = createOptions('/append-inherited/test1.ttl', 'user1')
576+
options.body = '<a> <b> <c> .\n'
577+
options.headers['content-type'] = 'text/turtle'
578+
request.put(options, function (error, response, body) {
579+
assert.equal(error, null)
580+
assert.equal(response.statusCode, 201)
581+
done()
582+
})
583+
})
584+
it('user2 should not be able to PUT with Append (existing resource)', function (done) {
585+
const options = createOptions('/append-inherited/test1.ttl', 'user2')
586+
options.body = '<a> <b> <c> .\n'
587+
options.headers['content-type'] = 'text/turtle'
588+
request.put(options, function (error, response, body) {
589+
assert.equal(error, null)
590+
assert.equal(response.statusCode, 403)
591+
assert.include(response.statusMessage, 'User Unauthorized')
592+
done()
593+
})
594+
})
574595
it('user1 should be able to access test file', function (done) {
575596
const options = createOptions('/append-acl/abc.ttl', 'user1')
576597
request.head(options, function (error, response, body) {
@@ -599,6 +620,16 @@ describe('ACL with WebID+OIDC over HTTP', function () {
599620
done()
600621
})
601622
})
623+
it('user2 should be able to PUT to (which CREATEs) a non existent resource', function (done) { // alain
624+
const options = createOptions('/append-inherited/new1.ttl', 'user1')
625+
options.body = '<a> <b> <c> .\n'
626+
options.headers['content-type'] = 'text/turtle'
627+
request.put(options, function (error, response, body) {
628+
assert.equal(error, null)
629+
assert.equal(response.statusCode, 201)
630+
done()
631+
})
632+
})
602633
it('user2 should not be able to access test file\'s ACL file', function (done) {
603634
const options = createOptions('/append-acl/abc.ttl.acl', 'user2', 'text/turtle')
604635
request.head(options, function (error, response, body) {
@@ -627,13 +658,13 @@ describe('ACL with WebID+OIDC over HTTP', function () {
627658
done()
628659
})
629660
})
630-
it('user2 (with append permission) cannot use PUT to append', function (done) {
661+
it('user2 (with append permission) cannot use PUT on an existing resource', function (done) {
631662
const options = createOptions('/append-acl/abc.ttl', 'user2', 'text/turtle')
632663
options.body = '<d> <e> <f> .\n'
633664
request.put(options, function (error, response, body) {
634665
assert.equal(error, null)
635666
assert.equal(response.statusCode, 403)
636-
assert.equal(response.statusMessage, 'User Unauthorized')
667+
assert.include(response.statusMessage, 'Can\'t write file/folder: User Unauthorized')
637668
done()
638669
})
639670
})
@@ -652,13 +683,15 @@ describe('ACL with WebID+OIDC over HTTP', function () {
652683
request.put(options, function (error, response, body) {
653684
assert.equal(error, null)
654685
assert.equal(response.statusCode, 401)
655-
assert.equal(response.statusMessage, 'Unauthenticated')
686+
assert.include(response.statusMessage, 'Can\'t write file/folder: Unauthenticated')
656687
done()
657688
})
658689
})
659690
after(function () {
660691
rm('/accounts-acl/tim.localhost/append-inherited/test.ttl')
692+
rm('/accounts-acl/tim.localhost/append-inherited/test1.ttl')
661693
rm('/accounts-acl/tim.localhost/append-inherited/new.ttl')
694+
rm('/accounts-acl/tim.localhost/append-inherited/new1.ttl')
662695
})
663696
})
664697

0 commit comments

Comments
 (0)