Skip to content

Commit db6934a

Browse files
authored
Merge pull request #289 from topcoder-platform/develop
Allow submitters to delete their own submissions
2 parents 9c81e30 + 0cba11f commit db6934a

File tree

5 files changed

+40
-13
lines changed

5 files changed

+40
-13
lines changed

src/common/helper.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -713,6 +713,17 @@ function * downloadFile (fileURL) {
713713
return downloadedFile.Body
714714
}
715715

716+
/**
717+
* Function to create s3 readstream from given S3 URL
718+
* @param{String} fileURL S3 URL of the file to be downloaded
719+
* @returns {Object} ReadStream of downloaded file
720+
*/
721+
function createS3ReadStream (fileURL) {
722+
const { bucket, key } = AmazonS3URI(fileURL)
723+
logger.info(`create s3 readStream(): file is on S3 ${bucket} / ${key}`)
724+
return s3.getObject({ Bucket: bucket, Key: key }).createReadStream()
725+
}
726+
716727
/**
717728
* Wrapper function to post to bus api. Ensures that every event posted to bus api
718729
* is duplicated and posted to bus api again, but to a different "aggregate" topic
@@ -895,6 +906,7 @@ module.exports = {
895906
checkCreateAccess,
896907
checkGetAccess,
897908
checkReviewGetAccess,
909+
createS3ReadStream,
898910
downloadFile,
899911
postToBusApi,
900912
cleanseReviews,

src/controllers/SubmissionController.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ function * downloadSubmission (req, res) {
2828
fileName = `submission-${result.submission.id}.zip`
2929
}
3030
res.attachment(fileName)
31-
res.send(result.file)
31+
helper.createS3ReadStream(result.submission.url).pipe(res)
3232
}
3333

3434
/**
@@ -74,7 +74,7 @@ function * patchSubmission (req, res) {
7474
* @param res the http response
7575
*/
7676
function * deleteSubmission (req, res) {
77-
yield SubmissionService.deleteSubmission(req.params.submissionId)
77+
yield SubmissionService.deleteSubmission(req.authUser, req.params.submissionId)
7878
res.status(204).send()
7979
}
8080

src/routes/SubmissionRoutes.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ module.exports = {
5050
controller: 'SubmissionController',
5151
method: 'deleteSubmission',
5252
auth: 'jwt',
53-
access: ['Administrator'],
53+
access: ['Topcoder User', 'Administrator', 'Copilot'],
5454
scopes: ['delete:submission', 'all:submission'],
5555
blockByIp: true
5656
}

src/services/SubmissionService.js

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -164,15 +164,14 @@ getSubmission.schema = {
164164
}
165165

166166
/**
167-
* Function to download submission from S3
167+
* Function to get submission
168168
* @param {Object} authUser Authenticated User
169169
* @param {String} submissionId ID of the Submission which need to be retrieved
170-
* @return {Object} Submission retrieved from S3
170+
* @return {Object} Submission retrieved
171171
*/
172172
function * downloadSubmission (authUser, submissionId) {
173173
const record = yield getSubmission(authUser, submissionId)
174-
const downloadedFile = yield helper.downloadFile(record.url)
175-
return { submission: record, file: downloadedFile }
174+
return { submission: record }
176175
}
177176

178177
/**
@@ -569,15 +568,20 @@ patchSubmission.schema = {
569568

570569
/**
571570
* Function to delete submission
571+
* @param {Object} authUser Authenticated User
572572
* @param {String} submissionId submissionId which need to be deleted
573573
* @return {Promise}
574574
*/
575-
function * deleteSubmission (submissionId) {
575+
function * deleteSubmission (authUser, submissionId) {
576576
const exist = yield _getSubmission(submissionId)
577577
if (!exist) {
578578
throw new errors.HttpStatusError(404, `Submission with ID = ${submissionId} is not found`)
579579
}
580580

581+
if (_.intersection(authUser.roles, ['Administrator', 'administrator']).length === 0 && exist.memberId !== authUser.userId) {
582+
throw new errors.HttpStatusError(403, 'You do not have permissions to delete this submission.')
583+
}
584+
581585
// Filter used to delete the record
582586
const filter = {
583587
TableName: table,
@@ -598,6 +602,7 @@ function * deleteSubmission (submissionId) {
598602
payload: {
599603
resource: helper.camelize(table),
600604
id: submissionId
605+
601606
}
602607
}
603608

@@ -606,7 +611,8 @@ function * deleteSubmission (submissionId) {
606611
}
607612

608613
deleteSubmission.schema = {
609-
submissionId: joi.string().guid().required()
614+
authUser: joi.object().required(),
615+
submissionId: joi.string().guid().required(),
610616
}
611617

612618
module.exports = {

test/unit/SubmissionService.test.js

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -470,16 +470,15 @@ describe('Submission Service tests', () => {
470470
})
471471
})
472472

473-
it('Deleting submission with user token should throw 403', (done) => {
473+
it('Deleting submission with User token should get succeeded', (done) => {
474474
chai.request(app)
475475
.delete(`${config.API_VERSION}/submissions/${testSubmission.Item.id}`)
476476
.set('Authorization', `Bearer ${config.USER_TOKEN}`)
477477
.end((err, res) => {
478-
res.should.have.status(403)
479-
res.body.message.should.be.eql('You are not allowed to perform this action!')
478+
res.should.have.status(204)
480479
done()
481480
})
482-
})
481+
}).timeout(10000)
483482

484483
it('Deleting non-existent submission should throw 404', (done) => {
485484
chai.request(app)
@@ -492,6 +491,16 @@ describe('Submission Service tests', () => {
492491
})
493492
})
494493

494+
it('Deleting submission with Copilot token should get succeeded', (done) => {
495+
chai.request(app)
496+
.delete(`${config.API_VERSION}/submissions/${testSubmission.Item.id}`)
497+
.set('Authorization', `Bearer ${config.COPILOT_TOKEN}`)
498+
.end((err, res) => {
499+
res.should.have.status(204)
500+
done()
501+
})
502+
}).timeout(10000)
503+
495504
it('Deleting submission with Admin token should get succeeded', (done) => {
496505
chai.request(app)
497506
.delete(`${config.API_VERSION}/submissions/${testSubmission.Item.id}`)

0 commit comments

Comments
 (0)