mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Add endpoint to delete a project
Needs acceptance tests
This commit is contained in:
parent
fc80aa3954
commit
47e96a4d94
6 changed files with 82 additions and 0 deletions
|
@ -61,6 +61,11 @@ app.delete(
|
|||
keyBuilder.userFileKeyMiddleware,
|
||||
fileController.deleteFile
|
||||
)
|
||||
app.delete(
|
||||
'/project/:project_id',
|
||||
keyBuilder.userProjectKeyMiddleware,
|
||||
fileController.deleteProject
|
||||
)
|
||||
|
||||
app.head(
|
||||
'/template/:template_id/v/:version/:format',
|
||||
|
|
|
@ -13,6 +13,7 @@ module.exports = {
|
|||
insertFile,
|
||||
copyFile,
|
||||
deleteFile,
|
||||
deleteProject,
|
||||
directorySize
|
||||
}
|
||||
|
||||
|
@ -158,6 +159,22 @@ function deleteFile(req, res, next) {
|
|||
})
|
||||
}
|
||||
|
||||
function deleteProject(req, res, next) {
|
||||
metrics.inc('deleteProject')
|
||||
const { project_id: projectId, bucket } = req
|
||||
|
||||
req.requestLogger.setMessage('getting project size')
|
||||
req.requestLogger.addFields({ projectId, bucket })
|
||||
|
||||
FileHandler.deleteProject(bucket, projectId, function(err) {
|
||||
if (err) {
|
||||
next(err)
|
||||
} else {
|
||||
res.sendStatus(204)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function directorySize(req, res, next) {
|
||||
metrics.inc('projectSize')
|
||||
const { project_id: projectId, bucket } = req
|
||||
|
|
|
@ -10,6 +10,7 @@ const { ConversionError, WriteError } = require('./Errors')
|
|||
module.exports = {
|
||||
insertFile: callbackify(insertFile),
|
||||
deleteFile: callbackify(deleteFile),
|
||||
deleteProject: callbackify(deleteProject),
|
||||
getFile: callbackify(getFile),
|
||||
getFileSize: callbackify(getFileSize),
|
||||
getDirectorySize: callbackify(getDirectorySize),
|
||||
|
@ -17,6 +18,7 @@ module.exports = {
|
|||
getFile,
|
||||
insertFile,
|
||||
deleteFile,
|
||||
deleteProject,
|
||||
getFileSize,
|
||||
getDirectorySize
|
||||
}
|
||||
|
@ -48,6 +50,16 @@ async function deleteFile(bucket, key) {
|
|||
])
|
||||
}
|
||||
|
||||
async function deleteProject(bucket, key) {
|
||||
if (!key.match(/^[0-9a-f]{24}\//i)) {
|
||||
throw new WriteError({
|
||||
message: 'key does not match validation regex',
|
||||
info: { bucket, key }
|
||||
})
|
||||
}
|
||||
await PersistorManager.promises.deleteDirectory(bucket, key)
|
||||
}
|
||||
|
||||
async function getFile(bucket, key, opts) {
|
||||
opts = opts || {}
|
||||
if (!opts.format && !opts.style) {
|
||||
|
|
|
@ -4,6 +4,7 @@ module.exports = {
|
|||
getConvertedFolderKey,
|
||||
addCachingToKey,
|
||||
userFileKeyMiddleware,
|
||||
userProjectKeyMiddleware,
|
||||
publicFileKeyMiddleware,
|
||||
publicProjectKeyMiddleware,
|
||||
bucketFileKeyMiddleware,
|
||||
|
@ -37,6 +38,13 @@ function userFileKeyMiddleware(req, res, next) {
|
|||
next()
|
||||
}
|
||||
|
||||
function userProjectKeyMiddleware(req, res, next) {
|
||||
const { project_id: projectId } = req.params
|
||||
req.key = `${projectId}/`
|
||||
req.bucket = settings.filestore.stores.user_files
|
||||
next()
|
||||
}
|
||||
|
||||
function publicFileKeyMiddleware(req, res, next) {
|
||||
if (settings.filestore.stores.public_files == null) {
|
||||
return res.status(501).send('public files not available')
|
||||
|
|
|
@ -40,6 +40,7 @@ describe('FileController', function() {
|
|||
getFile: sinon.stub().yields(null, fileStream),
|
||||
getFileSize: sinon.stub().yields(null, fileSize),
|
||||
deleteFile: sinon.stub().yields(),
|
||||
deleteProject: sinon.stub().yields(),
|
||||
insertFile: sinon.stub().yields(),
|
||||
getDirectorySize: sinon.stub().yields(null, fileSize)
|
||||
}
|
||||
|
@ -67,6 +68,7 @@ describe('FileController', function() {
|
|||
req = {
|
||||
key: key,
|
||||
bucket: bucket,
|
||||
project_id: projectId,
|
||||
query: {},
|
||||
params: {
|
||||
project_id: projectId,
|
||||
|
@ -257,6 +259,23 @@ describe('FileController', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('delete project', function() {
|
||||
it('should tell the file handler', function(done) {
|
||||
res.sendStatus = code => {
|
||||
code.should.equal(204)
|
||||
expect(FileHandler.deleteProject).to.have.been.calledWith(bucket, projectId)
|
||||
done()
|
||||
}
|
||||
FileController.deleteProject(req, res, next)
|
||||
})
|
||||
|
||||
it('should send a 500 if there was an error', function() {
|
||||
FileHandler.deleteProject.yields(error)
|
||||
FileController.deleteProject(req, res, next)
|
||||
expect(next).to.have.been.calledWith(error)
|
||||
})
|
||||
})
|
||||
|
||||
describe('directorySize', function() {
|
||||
it('should return total directory size bytes', function(done) {
|
||||
FileController.directorySize(req, {
|
||||
|
|
|
@ -27,6 +27,7 @@ describe('FileHandler', function() {
|
|||
const bucket = 'my_bucket'
|
||||
const key = `${ObjectId()}/${ObjectId()}`
|
||||
const convertedFolderKey = `${ObjectId()}/${ObjectId()}`
|
||||
const projectKey = `${ObjectId()}/`
|
||||
const sourceStream = 'sourceStream'
|
||||
const convertedKey = 'convertedKey'
|
||||
const readStream = {
|
||||
|
@ -154,6 +155,26 @@ describe('FileHandler', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('deleteProject', function() {
|
||||
it('should tell the filestore manager to delete the folder', function(done) {
|
||||
FileHandler.deleteProject(bucket, projectKey, err => {
|
||||
expect(err).not.to.exist
|
||||
expect(PersistorManager.promises.deleteDirectory).to.have.been.calledWith(
|
||||
bucket,
|
||||
projectKey
|
||||
)
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it('should throw an error when the key is in the wrong format', function(done) {
|
||||
FileHandler.deleteProject(bucket, 'wombat', err => {
|
||||
expect(err).to.exist
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('getFile', function() {
|
||||
it('should return the source stream no format or style are defined', function(done) {
|
||||
FileHandler.getFile(bucket, key, null, (err, stream) => {
|
||||
|
|
Loading…
Reference in a new issue