@@ -589,17 +589,60 @@ patchSubmission.schema = {
589
589
* @param {Object } span the Span object
590
590
* @return {Promise }
591
591
*/
592
- function * deleteSubmission ( submissionId , span ) {
592
+ function * deleteSubmission ( authUser , submissionId , span ) {
593
593
const deleteSubmissionSpan = tracer . startChildSpans ( 'SubmissionService.deleteSubmission' , span )
594
594
deleteSubmissionSpan . setTag ( 'submissionId' , submissionId )
595
595
596
596
try {
597
- const exist = yield _getSubmission ( submissionId , deleteSubmissionSpan )
598
- if ( ! exist ) {
597
+ const submissionRecord = yield _getSubmission ( submissionId , deleteSubmissionSpan )
598
+ if ( ! submissionRecord ) {
599
599
throw new errors . HttpStatusError ( 404 , `Submission with ID = ${ submissionId } is not found` )
600
600
}
601
601
602
- // Filter used to delete the record
602
+ if ( _ . intersection ( authUser . roles , [ 'Administrator' , 'administrator' ] ) . length === 0 && ! authUser . scopes ) {
603
+ // If not administrator, verify that the submission is owned by the user
604
+ if ( submissionRecord . memberId !== authUser . userId ) {
605
+ throw new errors . HttpStatusError ( 403 , 'You cannot access other member\'s submission' )
606
+ }
607
+
608
+ // Now verify that the Submission phase for the challenge is still active
609
+ // If not, non admin user cannot delete the submission
610
+ const activeSubmissionPhaseId = yield helper . getSubmissionPhaseId ( submissionRecord . challengeId , deleteSubmissionSpan )
611
+
612
+ if ( ! activeSubmissionPhaseId ) {
613
+ throw new errors . HttpStatusError ( 403 , 'You cannot delete the submission because submission phase is not active' )
614
+ }
615
+ }
616
+
617
+ // All checks passed - proceed to delete
618
+ // First, delete reviews and review summations for the submission
619
+ if ( submissionRecord . review ) {
620
+ const reviewService = require ( './ReviewService' )
621
+ for ( let i = 0 ; i < submissionRecord . review . length ; i ++ ) {
622
+ const review = submissionRecord . review [ i ]
623
+ yield reviewService . deleteReview ( review . id , deleteSubmissionSpan )
624
+ }
625
+ }
626
+
627
+ if ( submissionRecord . reviewSummation ) {
628
+ const reviewSummationService = require ( './ReviewSummationService' )
629
+ for ( let i = 0 ; i < submissionRecord . reviewSummation . length ; i ++ ) {
630
+ const reviewSummation = submissionRecord . reviewSummation [ i ]
631
+ yield reviewSummationService . deleteReviewSummation ( reviewSummation . id , deleteSubmissionSpan )
632
+ }
633
+ }
634
+
635
+ // Importing at the beginning of this service causes a circular dependency. Hence, dynamically invoking it
636
+ const artifactService = require ( './ArtifactService' )
637
+
638
+ // Next delete the artifacts for the submission
639
+ const submissionArtifacts = yield artifactService . listArtifacts ( submissionRecord . id , deleteSubmissionSpan )
640
+
641
+ for ( let i = 0 ; i < submissionArtifacts . artifacts . length ; i ++ ) {
642
+ yield artifactService . deleteArtifact ( submissionRecord . id , submissionArtifacts . artifacts [ i ] , deleteSubmissionSpan )
643
+ }
644
+
645
+ // Finally delete the submission itself
603
646
const filter = {
604
647
TableName : table ,
605
648
Key : {
@@ -630,6 +673,7 @@ function * deleteSubmission (submissionId, span) {
630
673
}
631
674
632
675
deleteSubmission . schema = {
676
+ authUser : joi . object ( ) . required ( ) ,
633
677
submissionId : joi . string ( ) . guid ( ) . required ( )
634
678
}
635
679
0 commit comments