@@ -12,6 +12,7 @@ const _ = require('lodash')
12
12
const s3 = new AWS . S3 ( )
13
13
const logger = require ( '../common/logger' )
14
14
const HelperService = require ( './HelperService' )
15
+ const commonHelper = require ( '../common/helper' )
15
16
16
17
/*
17
18
* Function to upload file to S3
@@ -39,16 +40,36 @@ async function _uploadToS3 (file, name) {
39
40
* @param {String } fileName File name which need to be downloaded from S3
40
41
* @return {Promise<Object> } File downloaded from S3
41
42
*/
42
- async function downloadArtifact ( submissionId , fileName ) {
43
+ async function downloadArtifact ( authUser , submissionId , fileName ) {
43
44
// Check the validness of Submission ID
44
- await HelperService . _checkRef ( { submissionId } )
45
- const artifacts = await s3 . listObjects ( { Bucket : config . aws . ARTIFACT_BUCKET , Prefix : `${ submissionId } /${ fileName } ` } ) . promise ( )
45
+ const submission = await HelperService . _checkRef ( { submissionId } )
46
+
47
+ let challenge
48
+ try {
49
+ challenge = await commonHelper . getChallenge ( submission . challengeId )
50
+ } catch ( e ) {
51
+ throw new errors . NotFoundError ( `Could not load challenge: ${ submission . challengeId } .\n Details: ${ _ . get ( e , 'message' ) } ` )
52
+ }
53
+
54
+ const { hasFullAccess, isSubmitter, hasNoAccess } = await commonHelper . getChallengeAccessLevel ( authUser , submission . challengeId )
55
+
56
+ if ( hasNoAccess || ( isSubmitter && challenge . isMM && submission . memberId . toString ( ) !== authUser . userId . toString ( ) ) ) {
57
+ throw new errors . HttpStatusError ( 403 , 'You are not allowed to download this submission artifact.' )
58
+ }
59
+
60
+ if ( fileName . includes ( 'internal' ) && ! hasFullAccess ) {
61
+ throw new errors . HttpStatusError ( 403 , 'Could not access artifact.' )
62
+ }
63
+
64
+ const prefix = submissionId + '/' + fileName
65
+ const artifacts = await s3 . listObjects ( { Bucket : config . aws . ARTIFACT_BUCKET , Prefix : prefix } ) . promise ( )
66
+
46
67
if ( artifacts . Contents . length === 0 ) {
47
68
throw new errors . HttpStatusError ( 400 , `Artifact ${ fileName } doesn't exist for ${ submissionId } ` )
48
69
}
49
70
50
- const key = submissionId + '/' + fileName + '.zip'
51
- if ( ! _ . includes ( _ . map ( artifacts . Contents , 'Key' ) , key ) ) {
71
+ const key = _ . get ( _ . find ( artifacts . Contents , { Key : ` ${ prefix } .zip` } ) || ( artifacts . Contents . length === 1 ? artifacts . Contents [ 0 ] : { } ) , 'Key' , null )
72
+ if ( ! key ) {
52
73
throw new errors . HttpStatusError ( 400 , `Artifact ${ fileName } doesn't exist for ${ submissionId } ` )
53
74
}
54
75
@@ -59,6 +80,7 @@ async function downloadArtifact (submissionId, fileName) {
59
80
}
60
81
61
82
downloadArtifact . schema = joi . object ( {
83
+ authUser : joi . object ( ) . required ( ) ,
62
84
submissionId : joi . string ( ) . uuid ( ) . required ( ) ,
63
85
fileName : joi . string ( ) . trim ( ) . required ( )
64
86
} ) . required ( )
@@ -68,14 +90,30 @@ downloadArtifact.schema = joi.object({
68
90
* @param {String } submissionId Submission ID
69
91
* @return {Promise<Object> } List of files present in S3 bucket under submissionId directory
70
92
*/
71
- async function listArtifacts ( submissionId ) {
93
+ async function listArtifacts ( authUser , submissionId ) {
72
94
// Check the validness of Submission ID
73
- await HelperService . _checkRef ( { submissionId } )
95
+ const submission = await HelperService . _checkRef ( { submissionId } )
96
+
97
+ let challenge
98
+ try {
99
+ challenge = await commonHelper . getChallenge ( submission . challengeId )
100
+ } catch ( e ) {
101
+ throw new errors . NotFoundError ( `Could not load challenge: ${ submission . challengeId } .\n Details: ${ _ . get ( e , 'message' ) } ` )
102
+ }
103
+
104
+ const { hasFullAccess, isSubmitter, hasNoAccess } = await commonHelper . getChallengeAccessLevel ( authUser , submission . challengeId )
105
+
106
+ if ( hasNoAccess || ( isSubmitter && challenge . isMM && submission . memberId . toString ( ) !== authUser . userId . toString ( ) ) ) {
107
+ throw new errors . HttpStatusError ( 403 , 'You are not allowed to access this submission artifact.' )
108
+ }
109
+
74
110
const artifacts = await s3 . listObjects ( { Bucket : config . aws . ARTIFACT_BUCKET , Prefix : submissionId } ) . promise ( )
75
- return { artifacts : _ . map ( artifacts . Contents , ( at ) => path . parse ( at . Key ) . name ) }
111
+ const artifactsContents = _ . map ( artifacts . Contents , ( at ) => path . parse ( at . Key ) . name )
112
+ return { artifacts : hasFullAccess ? artifactsContents : _ . filter ( artifactsContents , artifactName => ! artifactName . includes ( 'internal' ) ) }
76
113
}
77
114
78
115
listArtifacts . schema = joi . object ( {
116
+ authUser : joi . object ( ) . required ( ) ,
79
117
submissionId : joi . string ( ) . uuid ( ) . required ( )
80
118
} ) . required ( )
81
119
@@ -94,7 +132,7 @@ async function createArtifact (files, submissionId, entity) {
94
132
logger . info ( 'Creating a new Artifact' )
95
133
if ( files && files . artifact ) {
96
134
const uFileType = ( await FileType . fromBuffer ( files . artifact . data ) ) . ext // File type of uploaded file
97
- fileName = `${ submissionId } /${ files . artifact . name } .${ uFileType } `
135
+ fileName = `${ submissionId } /${ files . artifact . name . split ( '.' ) . slice ( 0 , - 1 ) } .${ uFileType } `
98
136
99
137
// Upload the artifact to S3
100
138
await _uploadToS3 ( files . artifact , fileName )
@@ -127,11 +165,6 @@ async function deleteArtifact (submissionId, fileName) {
127
165
logger . info ( `deleteArtifact: deleted artifact ${ fileName } of Submission ID: ${ submissionId } ` )
128
166
}
129
167
130
- downloadArtifact . schema = joi . object ( {
131
- submissionId : joi . string ( ) . uuid ( ) . required ( ) ,
132
- fileName : joi . string ( ) . trim ( ) . required ( )
133
- } ) . required ( )
134
-
135
168
module . exports = {
136
169
downloadArtifact,
137
170
listArtifacts,
0 commit comments