1
1
package de .tum .cit .aet .artemis .athena .web ;
2
2
3
3
import static de .tum .cit .aet .artemis .core .config .Constants .PROFILE_ATHENA ;
4
- import static de .tum .cit .aet .artemis .programming .service .localvc .ssh .HashUtils .hashSha256 ;
5
4
6
- import java .io .IOException ;
7
- import java .security .MessageDigest ;
8
5
import java .util .List ;
9
6
import java .util .Optional ;
10
7
import java .util .function .Function ;
11
8
12
9
import org .slf4j .Logger ;
13
10
import org .slf4j .LoggerFactory ;
14
- import org .springframework .beans .factory .annotation .Value ;
15
11
import org .springframework .context .annotation .Profile ;
16
- import org .springframework .core .io .Resource ;
17
12
import org .springframework .http .HttpStatus ;
18
13
import org .springframework .http .ResponseEntity ;
19
14
import org .springframework .web .bind .annotation .GetMapping ;
20
15
import org .springframework .web .bind .annotation .PathVariable ;
21
- import org .springframework .web .bind .annotation .RequestHeader ;
22
16
import org .springframework .web .bind .annotation .RequestMapping ;
23
17
import org .springframework .web .bind .annotation .RestController ;
24
18
27
21
import de .tum .cit .aet .artemis .athena .dto .TextFeedbackDTO ;
28
22
import de .tum .cit .aet .artemis .athena .service .AthenaFeedbackSuggestionsService ;
29
23
import de .tum .cit .aet .artemis .athena .service .AthenaModuleService ;
30
- import de .tum .cit .aet .artemis .athena .service .AthenaRepositoryExportService ;
31
24
import de .tum .cit .aet .artemis .core .domain .Course ;
32
- import de .tum .cit .aet .artemis .core .exception .AccessForbiddenException ;
33
25
import de .tum .cit .aet .artemis .core .exception .InternalServerErrorException ;
34
26
import de .tum .cit .aet .artemis .core .exception .NetworkingException ;
35
27
import de .tum .cit .aet .artemis .core .repository .CourseRepository ;
36
28
import de .tum .cit .aet .artemis .core .security .Role ;
37
29
import de .tum .cit .aet .artemis .core .security .annotations .EnforceAtLeastEditor ;
38
30
import de .tum .cit .aet .artemis .core .security .annotations .EnforceAtLeastTutor ;
39
- import de .tum .cit .aet .artemis .core .security .annotations .EnforceNothing ;
40
- import de .tum .cit .aet .artemis .core .security .annotations .ManualConfig ;
41
31
import de .tum .cit .aet .artemis .core .service .AuthorizationCheckService ;
42
- import de .tum .cit .aet .artemis .core .util .ResponseUtil ;
43
32
import de .tum .cit .aet .artemis .exercise .domain .Exercise ;
44
33
import de .tum .cit .aet .artemis .exercise .domain .ExerciseType ;
45
34
import de .tum .cit .aet .artemis .exercise .domain .Submission ;
46
35
import de .tum .cit .aet .artemis .modeling .repository .ModelingExerciseRepository ;
47
36
import de .tum .cit .aet .artemis .modeling .repository .ModelingSubmissionRepository ;
48
- import de .tum .cit .aet .artemis .programming .domain .RepositoryType ;
49
37
import de .tum .cit .aet .artemis .programming .repository .ProgrammingExerciseRepository ;
50
38
import de .tum .cit .aet .artemis .programming .repository .ProgrammingSubmissionRepository ;
51
39
import de .tum .cit .aet .artemis .text .api .TextApi ;
@@ -81,20 +69,15 @@ public class AthenaResource {
81
69
82
70
private final AthenaFeedbackSuggestionsService athenaFeedbackSuggestionsService ;
83
71
84
- private final AthenaRepositoryExportService athenaRepositoryExportService ;
85
-
86
72
private final AthenaModuleService athenaModuleService ;
87
73
88
- private final byte [] athenaSecretHash ;
89
-
90
74
/**
91
75
* The AthenaResource provides an endpoint for the client to fetch feedback suggestions from Athena.
92
76
*/
93
77
public AthenaResource (CourseRepository courseRepository , Optional <TextRepositoryApi > textRepositoryApi , Optional <TextSubmissionApi > textSubmissionApi ,
94
78
ProgrammingExerciseRepository programmingExerciseRepository , ProgrammingSubmissionRepository programmingSubmissionRepository ,
95
79
ModelingExerciseRepository modelingExerciseRepository , ModelingSubmissionRepository modelingSubmissionRepository , AuthorizationCheckService authCheckService ,
96
- AthenaFeedbackSuggestionsService athenaFeedbackSuggestionsService , AthenaRepositoryExportService athenaRepositoryExportService , AthenaModuleService athenaModuleService ,
97
- @ Value ("${artemis.athena.secret}" ) String athenaSecret ) {
80
+ AthenaFeedbackSuggestionsService athenaFeedbackSuggestionsService , AthenaModuleService athenaModuleService ) {
98
81
this .courseRepository = courseRepository ;
99
82
this .textRepositoryApi = textRepositoryApi ;
100
83
this .textSubmissionApi = textSubmissionApi ;
@@ -104,9 +87,7 @@ public AthenaResource(CourseRepository courseRepository, Optional<TextRepository
104
87
this .modelingSubmissionRepository = modelingSubmissionRepository ;
105
88
this .authCheckService = authCheckService ;
106
89
this .athenaFeedbackSuggestionsService = athenaFeedbackSuggestionsService ;
107
- this .athenaRepositoryExportService = athenaRepositoryExportService ;
108
90
this .athenaModuleService = athenaModuleService ;
109
- this .athenaSecretHash = hashSha256 (athenaSecret );
110
91
}
111
92
112
93
@ FunctionalInterface
@@ -237,81 +218,4 @@ public ResponseEntity<List<String>> getAvailableModulesForProgrammingExercises(@
237
218
public ResponseEntity <List <String >> getAvailableModulesForModelingExercises (@ PathVariable long courseId ) {
238
219
return this .getAvailableModules (courseId , ExerciseType .MODELING );
239
220
}
240
-
241
- /**
242
- * Check if the given auth header is valid for Athena, otherwise throw an exception.
243
- *
244
- * @param incomingSecret the auth header value to check
245
- */
246
- private void checkAthenaSecret (String incomingSecret ) {
247
- if (!MessageDigest .isEqual (athenaSecretHash , hashSha256 (incomingSecret ))) {
248
- log .error ("Athena secret does not match" );
249
- throw new AccessForbiddenException ("Athena secret does not match" );
250
- }
251
- }
252
-
253
- /**
254
- * GET public/programming-exercises/:exerciseId/submissions/:submissionId/repository : Get the repository as a zip file download
255
- *
256
- * @param exerciseId the id of the exercise the submission belongs to
257
- * @param submissionId the id of the submission to get the repository for
258
- * @param auth the auth header value to check
259
- * @return 200 Ok with the zip file as body if successful
260
- */
261
- @ GetMapping ("public/programming-exercises/{exerciseId}/submissions/{submissionId}/repository" )
262
- @ EnforceNothing // We check the Athena secret instead
263
- @ ManualConfig
264
- public ResponseEntity <Resource > getRepository (@ PathVariable long exerciseId , @ PathVariable long submissionId , @ RequestHeader ("Authorization" ) String auth ) throws IOException {
265
- log .debug ("REST call to get student repository for exercise {}, submission {}" , exerciseId , submissionId );
266
- checkAthenaSecret (auth );
267
- return ResponseUtil .ok (athenaRepositoryExportService .exportRepository (exerciseId , submissionId , null ));
268
- }
269
-
270
- /**
271
- * GET public/programming-exercises/:exerciseId/repository/template : Get the template repository as a zip file download
272
- *
273
- * @param exerciseId the id of the exercise
274
- * @param auth the auth header value to check
275
- * @return 200 Ok with the zip file as body if successful
276
- */
277
- @ GetMapping ("public/programming-exercises/{exerciseId}/repository/template" )
278
- @ EnforceNothing // We check the Athena secret instead
279
- @ ManualConfig
280
- public ResponseEntity <Resource > getTemplateRepository (@ PathVariable long exerciseId , @ RequestHeader ("Authorization" ) String auth ) throws IOException {
281
- log .debug ("REST call to get template repository for exercise {}" , exerciseId );
282
- checkAthenaSecret (auth );
283
- return ResponseUtil .ok (athenaRepositoryExportService .exportRepository (exerciseId , null , RepositoryType .TEMPLATE ));
284
- }
285
-
286
- /**
287
- * GET public/programming-exercises/:exerciseId/repository/solution : Get the solution repository as a zip file download
288
- *
289
- * @param exerciseId the id of the exercise
290
- * @param auth the auth header value to check
291
- * @return 200 Ok with the zip file as body if successful
292
- */
293
- @ GetMapping ("public/programming-exercises/{exerciseId}/repository/solution" )
294
- @ EnforceNothing // We check the Athena secret instead
295
- @ ManualConfig
296
- public ResponseEntity <Resource > getSolutionRepository (@ PathVariable long exerciseId , @ RequestHeader ("Authorization" ) String auth ) throws IOException {
297
- log .debug ("REST call to get solution repository for exercise {}" , exerciseId );
298
- checkAthenaSecret (auth );
299
- return ResponseUtil .ok (athenaRepositoryExportService .exportRepository (exerciseId , null , RepositoryType .SOLUTION ));
300
- }
301
-
302
- /**
303
- * GET public/programming-exercises/:exerciseId/repository/tests : Get the test repository as a zip file download
304
- *
305
- * @param exerciseId the id of the exercise
306
- * @param auth the auth header value to check
307
- * @return 200 Ok with the zip file as body if successful
308
- */
309
- @ GetMapping ("public/programming-exercises/{exerciseId}/repository/tests" )
310
- @ EnforceNothing // We check the Athena secret instead
311
- @ ManualConfig
312
- public ResponseEntity <Resource > getTestRepository (@ PathVariable long exerciseId , @ RequestHeader ("Authorization" ) String auth ) throws IOException {
313
- log .debug ("REST call to get test repository for exercise {}" , exerciseId );
314
- checkAthenaSecret (auth );
315
- return ResponseUtil .ok (athenaRepositoryExportService .exportRepository (exerciseId , null , RepositoryType .TESTS ));
316
- }
317
221
}
0 commit comments