Skip to content

Commit

Permalink
honor local file permissions in wac-allow headers
Browse files Browse the repository at this point in the history
  • Loading branch information
jeff-zucker committed Nov 28, 2020
1 parent 8b52917 commit 81539e2
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 37 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "solid-rest",
"version": "1.2.8",
"version": "1.2.9",
"author": "Jeff Zucker",
"license": "MIT",
"description": "treat any storage as a mini Solid server",
Expand Down
17 changes: 16 additions & 1 deletion src/file.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,24 @@ async getObjectType(fn,options){
let stat;
try { stat = fs.lstatSync(fn); }
catch(err){ }
let read=true,write=true;
if( stat ) {
try {
fs.accessSync(fn,fs.constants.R_OK);
}
catch(e){read=false}
try {
fs.accessSync(fn,fs.constants.W_OK);
}
catch(e){write=false}
}
let mode = {
read: (read),
write: (write)
}
let type = ( stat && stat.isDirectory()) ? "Container" : "Resource";
if(!stat && fn.endsWith('/')) type = "Container"
return Promise.resolve( [type,stat] )
return Promise.resolve( [type,stat,mode] )
}

async getResource(pathname,options,objectType){
Expand Down
82 changes: 47 additions & 35 deletions src/rest.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ let patch;
class SolidRest {

constructor( options ) {
this.version = "1.2.9";
let handlers;
if(typeof options === "object"){
if( Object.keys(options)[0] === "0" ) {
Expand Down Expand Up @@ -152,20 +153,24 @@ async fetch(uri, options = {}) {
self.storage=()=>{return self.storageHandlers[options.rest_prefix]}
}
}
const [objectType,objectExists] =
await self.storage(options).getObjectType(pathname,options)

const [objectType,objectExists,mode] =
await self.storage(options).getObjectType(pathname,options)
options.objectType = objectType
options.objectExists = objectExists
options.objectMode = mode ? mode : {read:true,write:true};

const notFoundMessage = '404 Not Found'
if (objectType === "Container" && !options.url.endsWith('/')) options.url = `${options.url}/`
const resOptions = Object.assign({}, options)
resOptions.headers = {}


/* GET
*/
if (options.method === 'GET') {
if(!objectExists) return _response(notFoundMessage, resOptions, 404)
if(!objectExists) return _response("", resOptions, 404)
if(!options.objectMode.read) return _response("", resOptions, 401)
if( objectType==="Container"){
let contents = await self.storage(options).getContainer(pathname,options)
const [status, turtleContents, headers] = await _container2turtle(pathname,options,contents)
Expand All @@ -186,6 +191,16 @@ async fetch(uri, options = {}) {
if(!objectExists) return _response(null, resOptions, 404)
else return _response(null, resOptions, 200)
}

if( options.method === 'DELETE'
|| options.method === 'PUT'
|| options.method === 'POST'
|| options.method === 'PATCH'
){
if(objectExists && !options.objectMode.write)
return _response("", resOptions, 401)
}

/* DELETE
*/
if( options.method==="DELETE" ){
Expand Down Expand Up @@ -375,29 +390,27 @@ async fetch(uri, options = {}) {
date from nodejs Date
*/
function _getHeaders(pathname,options){
// cxRes
// path = path || libPath
const fn = options.mungedPath.basename(pathname)
// let fn = encodeURI(pathname.replace(/.*\//,''))

const fn = options.mungedPath.basename(pathname)
let headers = (typeof self.storage(options).getHeaders != "undefined")
? self.storage(options).getHeaders(pathname,options)
: {}
headers.location = headers.url = headers.location || options.url
headers.date = headers.date ||
new Date(Date.now()).toISOString()
headers.allow = headers.allow || (typeof patch !="undefined")
? 'OPTIONS,HEAD,GET,POST,PUT,PATCH,DELETE'
: 'OPTIONS,HEAD,GET,POST,PUT,DELETE'
headers['wac-allow'] = headers['wac-allow'] ||
`user="read write append control",public="read"`

headers.location = headers.url = headers.location
|| options.url

headers.date = headers.date
|| new Date(Date.now()).toISOString()

headers.allow = headers.allow
|| _createAllowHeader(patch,options.objectMode)

let wacAllow = headers['wac-allow']
|| _createWacHeader(options.objectMode)
if( wacAllow ) headers['wac-allow'] = wacAllow;

headers['x-powered-by'] = headers['x-powered-by'] ||
self.storage(options).name
/*
const ext = ( path.basename(pathname).startsWith('.') )
? path.basename(pathname)
: path.extname(pathname)
*/

const ext = _getExtension(pathname,options)

Expand All @@ -414,7 +427,6 @@ async fetch(uri, options = {}) {
headers.link = headers.link;
if( !headers.link ) {
if( ext === '.acl' ) {
// TBD : IS THIS CORRECT? IS THE TYPE OF ACL "resource"?
headers.link =
`<http://www.w3.org/ns/ldp#Resource>; rel="type"`
}
Expand All @@ -436,21 +448,20 @@ async fetch(uri, options = {}) {
}
}
return headers
/*
headers.link = headers.link ||
options.objectType==="Container"
? `<.meta>; rel="describedBy", <.acl>; rel="acl",`
+`<http://www.w3.org/ns/ldp#Container>; rel="type",`
+`<http://www.w3.org/ns/ldp#BasicContainer>; rel="type"`
: `<${fn}.meta>; rel="describedBy", <${fn}.acl>; rel="acl",`
+`<http://www.w3.org/ns/ldp#Resource>; rel="type"`
*/

} // end of getHeaders()
/*
_deleteContainer(pathname,options)
* deletes a container with links
*/
function _createWacHeader( mode ){
if(!mode.read && !mode.write) return null;
if(mode.read && !mode.write) return `user="read",public="read"`
if(!mode.read && mode.write) return `user="append write control",public=""`
return `user="read write append control",public="read"`
}
function _createAllowHeader( patch, mode ){
return 'OPTIONS,HEAD'
+ (mode.read ?',GET' : '')
+ (mode.write ?',POST,PUT,DELETE' : '')
+ (mode.write && patch ?',PATCH' : '')
}

async function _deleteContainer(pathname,options){
let files = await self.storage(options).getContainer(pathname, options)
files = files.filter(file => !isLink(file,options)) // linkExt.find(ext => _getExtension(file,options) === ext))
Expand Down Expand Up @@ -511,6 +522,7 @@ function _normalizeOptions(opts){
} // end of SolidRest()

module.exports = exports = SolidRest
module.exports.SolidRest = SolidRest

/* END */

Expand Down

0 comments on commit 81539e2

Please sign in to comment.