X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=src%2Ffiles.js;h=1af4a18a3ece1f215342cd2b90fda8fa871d28ff;hb=HEAD;hp=520127dc7826502dbea5baeddabc531c0924935f;hpb=130809800e6e3fa33e5fc207dd6e1d963231f2a9;p=perso%2FImmae%2FProjets%2FNodejs%2FSurfer.git diff --git a/src/files.js b/src/files.js index 520127d..1af4a18 100644 --- a/src/files.js +++ b/src/files.js @@ -17,6 +17,7 @@ exports = module.exports = function (basePath) { return { get: get, put: put, + post: post, del: del }; }; @@ -54,6 +55,17 @@ function copyFile(source, target, cb) { }); } +function createDirectory(targetPath, callback) { + mkdirp(targetPath, function (error) { + if (error) return callback(error); + callback(null); + }); +} + +function isProtected(targetPath) { + return targetPath.indexOf(getAbsolutePath('_admin')) === 0; +} + function getAbsolutePath(filePath) { var absoluteFilePath = path.resolve(path.join(gBasePath, filePath)); @@ -66,7 +78,7 @@ function removeBasePath(filePath) { } function get(req, res, next) { - var filePath = req.params[0]; + var filePath = decodeURIComponent(req.params[0]); var absoluteFilePath = getAbsolutePath(filePath); if (!absoluteFilePath) return next(new HttpError(403, 'Path not allowed')); @@ -76,7 +88,7 @@ function get(req, res, next) { debug('get', absoluteFilePath); if (!result.isDirectory() && !result.isFile()) return next(new HttpError(500, 'unsupported type')); - if (result.isFile()) return res.sendFile(absoluteFilePath); + if (result.isFile()) return res.download(absoluteFilePath); async.map(fs.readdirSync(absoluteFilePath), function (filePath, callback) { fs.stat(path.join(absoluteFilePath, filePath), function (error, result) { @@ -100,21 +112,29 @@ function get(req, res, next) { }); } -function put(req, res, next) { - var filePath = req.params[0]; +function post(req, res, next) { + var filePath = decodeURIComponent(req.params[0]); - if (!req.files.file) return next(new HttpError(400, 'missing file')); + if (!(req.files && req.files.file) && !req.query.directory) return next(new HttpError(400, 'missing file or directory')); + if ((req.files && req.files.file) && req.query.directory) return next(new HttpError(400, 'either file or directory')); + + debug('post:', filePath); var absoluteFilePath = getAbsolutePath(filePath); - if (!absoluteFilePath) return next(new HttpError(403, 'Path not allowed')); + if (!absoluteFilePath || isProtected(absoluteFilePath)) return next(new HttpError(403, 'Path not allowed')); fs.stat(absoluteFilePath, function (error, result) { if (error && error.code !== 'ENOENT') return next(new HttpError(500, error)); - debug('put', absoluteFilePath, req.files.file); + if (result && req.query.directory) return next(new HttpError(409, 'name already exists')); + if (result && result.isDirectory()) return next(new HttpError(409, 'cannot post on directories')); - if (result && result.isDirectory()) return next(new HttpError(409, 'cannot put on directories')); - if (!result || result.isFile()) { + if (req.query.directory) { + return createDirectory(absoluteFilePath, function (error) { + if (error) return next(new HttpError(500, error)); + next(new HttpSuccess(201, {})); + }); + } else if (!result || result.isFile()) { return copyFile(req.files.file.path, absoluteFilePath, function (error) { if (error) return next(new HttpError(500, error)); next(new HttpSuccess(201, {})); @@ -125,14 +145,40 @@ function put(req, res, next) { }); } +function put(req, res, next) { + var oldFilePath = decodeURIComponent(req.params[0]); + + if (!req.body || !req.body.newFilePath) return next(new HttpError(400, 'missing newFilePath')); + + var newFilePath = decodeURIComponent(req.body.newFilePath); + + debug('put: %s -> %s', oldFilePath, newFilePath); + + var absoluteOldFilePath = getAbsolutePath(oldFilePath); + if (!absoluteOldFilePath || isProtected(absoluteOldFilePath)) return next(new HttpError(403, 'Path not allowed')); + + var absoluteNewFilePath = getAbsolutePath(newFilePath); + if (!absoluteNewFilePath || isProtected(absoluteNewFilePath)) return next(new HttpError(403, 'Path not allowed')); + + fs.rename(absoluteOldFilePath, absoluteNewFilePath, function (error) { + if (error) return next (new HttpError(500, error)); + + debug('put: successful'); + + return next(new HttpSuccess(200, {})); + }); +} + function del(req, res, next) { - var filePath = req.params[0]; + var filePath = decodeURIComponent(req.params[0]); var recursive = !!req.query.recursive; var dryRun = !!req.query.dryRun; var absoluteFilePath = getAbsolutePath(filePath); if (!absoluteFilePath) return next(new HttpError(404, 'Not found')); + if (isProtected(absoluteFilePath)) return next(new HttpError(403, 'Path not allowed')); + // absoltueFilePath has to have the base path prepended if (absoluteFilePath.length <= gBasePath.length) return next(new HttpError(404, 'Not found')); @@ -144,7 +190,7 @@ function del(req, res, next) { // add globs to get file listing if (result.isDirectory()) absoluteFilePath += '/**'; - rm(absoluteFilePath, { dryRun: dryRun }).then(function (result) { + rm(absoluteFilePath, { dryRun: dryRun, force: true }).then(function (result) { result = result.map(removeBasePath); next(new HttpSuccess(200, { entries: result })); }, function (error) {