@@ -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,29 @@ 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
+ const { hasFullAccess, isSubmitter, hasNoAccess } = await commonHelper . getChallengeAccessLevel ( authUser , submission . challengeId )
48
+
49
+ if ( hasNoAccess || ( isSubmitter && submission . memberId . toString ( ) !== authUser . userId . toString ( ) ) ) {
50
+ throw new errors . HttpStatusError ( 403 , 'You are not allowed to download this submission artifact.' )
51
+ }
52
+
53
+ if ( fileName . includes ( 'internal' ) && ! hasFullAccess ) {
54
+ throw new errors . HttpStatusError ( 403 , 'Could not access artifact.' )
55
+ }
56
+
57
+ const prefix = submissionId + '/' + fileName
58
+ const artifacts = await s3 . listObjects ( { Bucket : config . aws . ARTIFACT_BUCKET , Prefix : prefix } ) . promise ( )
59
+
46
60
if ( artifacts . Contents . length === 0 ) {
47
61
throw new errors . HttpStatusError ( 400 , `Artifact ${ fileName } doesn't exist for ${ submissionId } ` )
48
62
}
49
63
50
- const key = submissionId + '/' + fileName + '.zip'
51
- if ( ! _ . includes ( _ . map ( artifacts . Contents , 'Key' ) , key ) ) {
64
+ const key = _ . get ( _ . find ( artifacts . Contents , { Key : ` ${ prefix } .zip` } ) || ( artifacts . Contents . length === 1 ? artifacts . Contents [ 0 ] : { } ) , 'Key' , null )
65
+ if ( ! key ) {
52
66
throw new errors . HttpStatusError ( 400 , `Artifact ${ fileName } doesn't exist for ${ submissionId } ` )
53
67
}
54
68
@@ -59,6 +73,7 @@ async function downloadArtifact (submissionId, fileName) {
59
73
}
60
74
61
75
downloadArtifact . schema = joi . object ( {
76
+ authUser : joi . object ( ) . required ( ) ,
62
77
submissionId : joi . string ( ) . uuid ( ) . required ( ) ,
63
78
fileName : joi . string ( ) . trim ( ) . required ( )
64
79
} ) . required ( )
@@ -68,14 +83,23 @@ downloadArtifact.schema = joi.object({
68
83
* @param {String } submissionId Submission ID
69
84
* @return {Promise<Object> } List of files present in S3 bucket under submissionId directory
70
85
*/
71
- async function listArtifacts ( submissionId ) {
86
+ async function listArtifacts ( authUser , submissionId ) {
72
87
// Check the validness of Submission ID
73
- await HelperService . _checkRef ( { submissionId } )
88
+ const submission = await HelperService . _checkRef ( { submissionId } )
89
+
90
+ const { hasFullAccess, isSubmitter, hasNoAccess } = await commonHelper . getChallengeAccessLevel ( authUser , submission . challengeId )
91
+
92
+ if ( hasNoAccess || ( isSubmitter && submission . memberId . toString ( ) !== authUser . userId . toString ( ) ) ) {
93
+ throw new errors . HttpStatusError ( 403 , 'You are not allowed to access this submission artifact.' )
94
+ }
95
+
74
96
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 ) }
97
+ const artifactsContents = _ . map ( artifacts . Contents , ( at ) => path . parse ( at . Key ) . name )
98
+ return { artifacts : hasFullAccess ? artifactsContents : _ . filter ( artifactsContents , artifactName => ! artifactName . includes ( 'internal' ) ) }
76
99
}
77
100
78
101
listArtifacts . schema = joi . object ( {
102
+ authUser : joi . object ( ) . required ( ) ,
79
103
submissionId : joi . string ( ) . uuid ( ) . required ( )
80
104
} ) . required ( )
81
105
@@ -94,7 +118,7 @@ async function createArtifact (files, submissionId, entity) {
94
118
logger . info ( 'Creating a new Artifact' )
95
119
if ( files && files . artifact ) {
96
120
const uFileType = ( await FileType . fromBuffer ( files . artifact . data ) ) . ext // File type of uploaded file
97
- fileName = `${ submissionId } /${ files . artifact . name } .${ uFileType } `
121
+ fileName = `${ submissionId } /${ files . artifact . name . split ( '.' ) . slice ( 0 , - 1 ) } .${ uFileType } `
98
122
99
123
// Upload the artifact to S3
100
124
await _uploadToS3 ( files . artifact , fileName )
@@ -127,11 +151,6 @@ async function deleteArtifact (submissionId, fileName) {
127
151
logger . info ( `deleteArtifact: deleted artifact ${ fileName } of Submission ID: ${ submissionId } ` )
128
152
}
129
153
130
- downloadArtifact . schema = joi . object ( {
131
- submissionId : joi . string ( ) . uuid ( ) . required ( ) ,
132
- fileName : joi . string ( ) . trim ( ) . required ( )
133
- } ) . required ( )
134
-
135
154
module . exports = {
136
155
downloadArtifact,
137
156
listArtifacts,
0 commit comments