Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*.swp
node_modules/
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

run-for-test:
NODE_PATH=.:../tabulator-firefox/content/js/rdf/dist/ node server.js \
-v --uriBase http://localhost:3000/test/ --fileBase `pwd`/test/
-v --uriBase http://localhost:3000/test/ -p 3000 --fileBase `pwd`/test/



Expand Down
78 changes: 78 additions & 0 deletions acl.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
var acl = require('acl');
var fs = require('fs');
var path = require('path');

var file = require('./fileStore.js');
var options = require('./options.js');

var permissionExtension = '.permissions';
var aclEnabled = false;

module.exports.readPermissions = function() {
var permissionFile = options.fileBase + permissionExtension;
fs.readFile(permissionFile, readPermissionsCallback);

function readPermissionsCallback(err, rawPermissions) {
if (err) {
return;
} else {
var jsonPermissions;
try {
jsonPermissions = JSON.parse(rawPermissions);
} catch (parseErr) {
return;
}
if ('roles' in jsonPermissions && 'users' in jsonPermissions) {
try {
acl = new acl(new acl.memoryBackend());
for (var rIndex = 0; rIndex < jsonPermissions.roles.length; rIndex++) {
acl.allow(jsonPermissions.roles[rIndex][0],
jsonPermissions.roles[rIndex][1],
jsonPermissions.roles[rIndex][2]);
}
for (var uIndex = 0; uIndex < jsonPermissions.users.length; uIndex++) {
acl.addUserRoles(jsonPermissions.users[uIndex][0],
jsonPermissions.users[uIndex][1]);
}
aclEnabled = true;
return;
} catch (permissionErr) {
return;
}
} else {
return;
}
}
}
};

module.exports.isAllowed = function(userId, resource, permissions, callback) {
if (aclEnabled) {
acl.isAllowed(userId, resource, permissions, callback);
} else {
callback(undefined, true);
}
};

module.exports.aclHandler = function(req, res, next) {
//TODO authentication
var filename = file.uriToFilename(req.path);
var resource = path.relative(options.fileBase, filename);

//TODO complete this line
// acl.isAllowed(userId, resource, req.method);
next();

function aclCallback(err, allowed) {
if (err) {
return res.sendStatus(500);
} else {
if (allowed) {
next();
} else {
return res.sendStatus(403);
}
}

}
};
228 changes: 228 additions & 0 deletions container.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
var fs = require('fs');
var $rdf = require('rdflib');
var path = require('path');
var uuid = require('node-uuid');

var logging = require('./logging.js');
var metadata = require('./metadata.js');
var options = require('./options.js');

var rdfVocab = require('./vocab/rdf.js');
var ldpVocab = require('./vocab/ldp.js');

var addUriTriple = function(kb, s, o, p) {
kb.add(kb.sym(s), kb.sym(o), kb.sym(p));
};

var usedURIs = {};

module.exports.createRootContainer = function() {
if (!metadata.hasMetadata(options.fileBase)) {
logging.log("Creating root metadata");
var rootMetadata = new metadata.Metadata();
rootMetadata.filename = options.fileBase;
rootMetadata.isResource = true;
rootMetadata.isContainer = true;
rootMetadata.isSourceResource = true;
rootMetadata.isBasicContainer = true;
metadata.writeMetadata(options.fileBase, rootMetadata,
writeCallback);
}
//TODO handle case when .container file does not exist

function writeCallback(err) {
logging.log(options.pathStart);
if (err) {
process.exit(1);
} else if (!metadata.hasContainerMetadata(options.fileBase)) {
var rootContainer = $rdf.graph();
addUriTriple(rootContainer, options.pathStart, rdfVocab.type,
ldpVocab.Resource);
addUriTriple(rootContainer, options.pathStart, rdfVocab.type,
ldpVocab.RDFSource);
addUriTriple(rootContainer, options.pathStart, rdfVocab.type,
ldpVocab.Container);
addUriTriple(rootContainer, options.pathStart, rdfVocab.type,
ldpVocab.BasicContainer);
rootContainer.add(rootContainer.sym(options.pathStart),
rootContainer.sym('http://purl.org/dc/terms/title'),
'"Root Container"');
var serializedContainer = $rdf.serialize(undefined, rootContainer,
options.pathStart, 'text/turtle');
logging.log("Root container: ", serializedContainer);
metadata.writeContainerMetadata(options.fileBase,
serializedContainer, function(err) {
if (err) {
//TODO handle error
logging.log("Could not write root container");
} else {
logging.log("Wrote root container");
}
});
}
}
};

module.exports.createNewContainer = function(container, type, callback) {
fs.mkdir(container, function(err) {
if (err) {
this.releaseResourceUri(container);
callback(err);
} else {
var containerMetadata = new metadata.Metadata();
containerMetadata.filename = container;
containerMetadata.isResource = true;
containerMetadata.isContainer = true;
containerMetadata.isSourceResource = true;
if (type === ldpVocab.BasicContainer)
containerMetadata.isBasicContainer = true;
if (type === ldpVocab.DirectContainer)
containerMetadata.isDirectContainer = true;
metadata.writeMetadata(options.fileBase, rootMetadata, writeCallback);
}
});

function writeCallback(err) {
if (err) {
this.releaseResourceUri(container);
callback(err);
} else {
var newContainer = $rdf.graph();
addUriTriple(newContainer, options.pathStart, rdfVocab.type,
ldpVocab.Resource);
addUriTriple(newContainer, options.pathStart, rdfVocab.type,
ldpVocab.RDFSource);
addUriTriple(newContainer, options.pathStart, rdfVocab.type,
ldpVocab.Container);
if (type === ldpVocab.BasicContainer)
addUriTriple(newContainer, options.pathStart, rdfVocab.type,
ldpVocab.BasicContainer);
else if (type === ldpVocab.DirectContainer)
addUriTriple(newContainer, options.pathStart, rdfVocab.type,
ldpVocab.DirectContainer);

newContainer.add(newContainer.sym(options.pathStart),
newContainer.sym('http://purl.org/dc/terms/title'),
container);
var serializedContainer = $rdf.serialize(undefined, newContainer,
container, 'text/turtle');
metadata.writeContainerMetadata(container, serializedContainer,
function(err) {
this.releaseResourceUri(container);
if (err) {
callback(err);
} else {
logging.log("Wrote new container");
callback(err);
}
});
}
}

};

module.exports.createResourceUri = function(containerURI, slug) {
var newPath;
if (slug) {
newPath = path.join(containerURI, slug);
} else {
newPath = path.join(containerURI, uuid.v1());
}
if (!(fs.existsSync(newPath) || containerURI in usedURIs)) {
usedURIs[newPath] = true;
} else {
return null;
}
return newPath;
};

module.exports.releaseResourceUri = function(uri) {
delete usedURIs[uri];
};

module.exports.verify = function(containerGraph, type) {
//TODO work on this method
var results = containerGraph.each(undefined, "a", type);
if (results.length === 1) {
return true;
} else {
return false;
}
};

module.exports.verifyDirectContainer = function(containerGraph) {

};

module.exports.createNewResource = function(containerPath, containerGraph,
resourcePath, resourceGraph, resourceMetadata, callback) {
var containerURI = path.relative(options.fileBase, containerPath);
var resourceURI = path.relative(options.fileBase, resourcePath);
//TODO replace url with resource url
var rawResource = $rdf.serialize(undefined,
resourceGraph, options.baseUri + resourceURI, 'text/turtle');
logging.log("Writing new resource to ", resourcePath);
logging.log(rawResource);
fs.writeFile(resourcePath, rawResource, writeResourceCallback);

function writeResourceCallback(err) {
if (err) {
container.releaseResourceUri(resoucePath);
callback(err);
} else {
addUriTriple(containerGraph, containerURI, ldpVocab.contains,
resourceURI);
var rawContainer = $rdf.serialize(undefined, containerGraph,
options.uriBase, 'text/turtle');
metadata.writeContainerMetadata(containerPath, rawContainer,
writeContainerCallback);
}
}

function writeContainerCallback(err) {
if (err) {
module.exports.releaseResourceUri(resourcePath);
return callback(err);
} else {
metadata.writeMetadata(resourcePath, resourceMetadata,
writeMetadataCallback);
}
}

function writeMetadataCallback(err) {
module.exports.releaseResourceUri(resourcePath);
return callback(err);
}
};

module.exports.createNewContainer = function(containerPath, containerGraph,
containerMetadata, callback) {
fs.mkdir(containerPath, mkdirCallback);

function mkdirCallback(err) {
if (err) {
module.exports.releaseResourceUri(containerPath);
return callback(err);
} else {
var rawContainer = $rdf.serialize(undefined, containerGraph,
options.uriBase, 'text/turtle');
metadata.writeContainerMetadata(containerPath, rawContainer,
writeContainerCallback);
}
}

function writeContainerCallback(err) {
if (err) {
module.exports.releaseResourceUri(containerPath);
return callback(err);
} else {
metadata.writeMetadata(containerPath, containerMetadata,
writeMetadataCallback);
}
}

function writeMetadataCallback(err) {
module.exports.releaseResourceUri(containerPath);
return callback(err);
}
};
14 changes: 14 additions & 0 deletions fileStore.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
var path = require('path');

var options = require('./options.js');
var logging = require('./logging.js');

module.exports.uriToFilename = function(uri) {
//if (uri.slice(0, options.pathStart.length) !== options.pathStart) {
//throw "Path '" + uri + "'not starting with base '" + options.pathStart + "'.";
//}
//var filename = options.fileBase + uri.slice(options.pathStart.length);
var filename = path.join(options.fileBase, uri);
logging.log(' -- filename ' +filename);
return filename;
};
47 changes: 47 additions & 0 deletions handlers/delete.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
var fs = require('fs');
var rimraf = require('rimraf');

var file = require('../fileStore.js');
var logging = require('../logging.js');
var metadata = require('../metadata.js');

module.exports.handler = function(req, res) {
logging.log('DELETE -- ' + req.path);
// res.header('MS-Author-Via' , 'SPARQL' );
var filename = file.uriToFilename(req.path);
fs.stat(filename, function(err, stats) {
if (err) {
logging.log(" ### DELETE unlink() error: " + err);
return res.status(404).send("Can't delete file: " + err);
} else if (stats.isDirectory()) {
if (filename.charAt(filename.length - 1) !== '/')
filename += '/';
metadata.deleteContainerMetadata(filename, containerCallback);
} else {
fs.unlink(filename, fileCallback);
}
});

function fileCallback(err) {
if (err) {
logging.log(" ### DELETE unlink() error: " + err);
return res.status(404).send("Can't delete file: " + err); // @@ best
} else {
//TODO remove file from container
metadata.deleteMetadata(filename, function(err) {});
logging.log(" -- delete Ok " + req.text.length);
res.sendStatus(200);
}
}

function containerCallback(err) {
if (err) {
logging.log("DELETE unlink() error: " + err);
return res.status(404).send("Can't delete container: " + err);
} else {
metadata.deleteMetadata(filename, function(err) {});
logging.log(" -- delete Ok " + req.text.length);
res.sendStatus(200);
}
}
};
Loading