Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Development: Theia integration test #9759

Open
wants to merge 125 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
125 commits
Select commit Hold shift + click to select a range
a0497f3
Move Theia Button to Code Button
iyannsch Sep 23, 2024
2ab444e
Add functionality to pull build config on demand from server
iyannsch Sep 24, 2024
389f5fd
Merge branch 'develop' into feature/programming-exercises/provide-the…
iyannsch Sep 28, 2024
7ce3a49
Add Uri, Token, and landing-page URL to Theia Button
iyannsch Sep 28, 2024
5dec295
enable bearer authentication
janthoXO Oct 1, 2024
fc69fca
Add ProgrammingExercise by ProjectKey endpoint
janthoXO Oct 1, 2024
b447b28
Add re-key endpoint
janthoXO Oct 1, 2024
a3d0fbb
Implement rabbit feedback
janthoXO Oct 2, 2024
83ef1a5
check for access to exercise
janthoXO Oct 2, 2024
4160302
Add Form test and re-key endpoint
iyannsch Oct 3, 2024
eae2c89
Clean up initTheia method
iyannsch Oct 3, 2024
0f18104
Fix formatting
iyannsch Oct 3, 2024
486b2c5
Fix implicit type expressions
iyannsch Oct 4, 2024
069f2eb
Merge branch 'feature/bearer-support' of github.com:ls1intum/Artemis …
janthoXO Oct 4, 2024
39e4bad
make token theia specific
janthoXO Oct 4, 2024
d9bf634
Fix rekey endpoint to be reachable
iyannsch Oct 4, 2024
a643b42
Merge upstream key endpoint
iyannsch Oct 4, 2024
ddd8802
fix conversion from day to millis
janthoXO Oct 4, 2024
34a84d7
Merge branch 'feature/re-key' into feature/programming-exercises/prov…
iyannsch Oct 4, 2024
4f1a99b
Fix endpoint theia-token connection
iyannsch Oct 4, 2024
07afea2
only respond as cookie if asked for
janthoXO Oct 4, 2024
b59f8ad
fix class cast error for websockets
janthoXO Oct 5, 2024
896fd4c
let login return json with token
janthoXO Oct 7, 2024
4aa5171
Merge branch 'develop' into feature/programming-exercises/provide-the…
iyannsch Oct 8, 2024
7abb02c
Merge branch 'feature/re-key' into feature/programming-exercises/prov…
iyannsch Oct 8, 2024
b7ebea0
Merge upstream bearer branch
iyannsch Oct 8, 2024
685a483
Get Token unconditionally
iyannsch Oct 8, 2024
490692e
add @param to docs
janthoXO Oct 25, 2024
056fcc9
merge develop
janthoXO Oct 26, 2024
e8be59c
Merge branch 'develop' into feature/programming-exercises/provide-the…
iyannsch Oct 29, 2024
575379b
Fix failing correct data submission test
iyannsch Oct 29, 2024
2d2a5b7
Remove minus from appDef to align to TS configuration
iyannsch Oct 29, 2024
2e247db
add server test for bearer token
janthoXO Nov 6, 2024
6207ce8
Fix configuration values to align with new system
iyannsch Nov 7, 2024
e8bde67
Merge branch 'develop' into feature/bearer-support
iyannsch Nov 7, 2024
c36c6ec
Merge branch 'develop' into feature/re-key
iyannsch Nov 7, 2024
a6cc06e
Merge branch 'develop' into feature/programming-exercises/provide-the…
iyannsch Nov 7, 2024
f82d6fb
Merge branch 'feature/re-key' into feature/programming-exercises/prov…
iyannsch Nov 7, 2024
8743e73
Merge branch 'feature/bearer-support' of github.com:ls1intum/Artemis …
iyannsch Nov 7, 2024
beb3d48
Merge branch 'feature/re-key' of github.com:ls1intum/Artemis into fea…
iyannsch Nov 7, 2024
625216e
Rename endpoint to theia-token
iyannsch Nov 7, 2024
02e63b7
change theia token to general tool token endpoint
janthoXO Nov 8, 2024
44ca43c
Apply suggestions from code review
janthoXO Nov 8, 2024
6cab497
add tool token annotation
janthoXO Nov 9, 2024
e2bb2d0
Merge remote-tracking branch 'origin/feature/re-key' into feature/re-key
janthoXO Nov 9, 2024
6e61b26
move interceptor registration
janthoXO Nov 9, 2024
149a53a
add tool token option to login
janthoXO Nov 11, 2024
b0ed73d
change filter chain to only accept one auth method
janthoXO Nov 11, 2024
6b19a87
Merge remote-tracking branch 'origin/feature/bearer-support' into fea…
janthoXO Nov 11, 2024
8df1a6b
write filter a bit nicer
janthoXO Nov 11, 2024
7fe83a9
Merge branch 'feature/bearer-support' of github.com:ls1intum/Artemis …
janthoXO Nov 12, 2024
9f61018
annotate endpoints required by Scorpio
janthoXO Nov 12, 2024
7d3b311
Merge branch 'feature/re-key' of github.com:ls1intum/Artemis into fea…
janthoXO Nov 12, 2024
932ae63
only allow scorpio tokens
janthoXO Nov 12, 2024
5908f73
change bad request behaviour
janthoXO Nov 12, 2024
5c7ef80
Merge branch 'feature/re-key' of github.com:ls1intum/Artemis into fea…
janthoXO Nov 12, 2024
2946389
Merge branch 'feature/re-key' of github.com:ls1intum/Artemis into fea…
iyannsch Nov 12, 2024
c7c5322
Rename endpoint to tool-token
iyannsch Nov 12, 2024
9b0bcc3
Add ArtemisURL to theia query params
iyannsch Nov 12, 2024
ae35975
Merge branch 'feature/programming-exercises/provide-theia-clone-infor…
iyannsch Nov 12, 2024
0bc0474
Merge branch 'develop' of github.com:ls1intum/Artemis into chore/thei…
iyannsch Nov 13, 2024
d3817c8
Add gitUser and gitMail to Theia LP
iyannsch Nov 13, 2024
3c596ac
Merge branch 'feature/programming-exercises/provide-theia-clone-infor…
iyannsch Nov 13, 2024
590fde4
Fix ArtemisUrl
iyannsch Nov 13, 2024
ac87b07
Remove debug for artemisUrl
iyannsch Nov 13, 2024
10648b0
Merge branch 'develop' of github.com:ls1intum/Artemis into feature/pr…
iyannsch Nov 13, 2024
dbe23d9
Merge branch 'feature/programming-exercises/provide-theia-clone-infor…
iyannsch Nov 13, 2024
2941799
Merge branch 'develop' of github.com:ls1intum/Artemis into feature/pr…
iyannsch Nov 18, 2024
c76998c
Merge branch 'feature/programming-exercises/provide-theia-clone-infor…
iyannsch Nov 18, 2024
288a1eb
Merge branch 'develop' of github.com:ls1intum/Artemis into feature/be…
iyannsch Nov 18, 2024
81f4739
Merge branch 'develop' of github.com:ls1intum/Artemis into feature/re…
iyannsch Nov 18, 2024
7a69620
fix server tests
Nov 19, 2024
5803813
Merge remote-tracking branch 'origin/feature/re-key' into feature/re-key
Nov 19, 2024
1cf7281
Merge branch 'develop' of github.com:ls1intum/Artemis into feature/be…
Nov 19, 2024
4dabd91
Merge branch 'feature/bearer-support' of github.com:ls1intum/Artemis …
Nov 19, 2024
52b816b
Merge branch 'feature/bearer-support' of github.com:ls1intum/Artemis …
Nov 19, 2024
9ca745b
adjust tests
Nov 19, 2024
277f8b1
merge from bearer support
Nov 19, 2024
3e93d8c
include rabbit feedback
Nov 19, 2024
8715557
Merge branch 'feature/bearer-support' of github.com:ls1intum/Artemis …
Nov 19, 2024
ca0aa32
include test for allowedTools annotation
Nov 20, 2024
f2f2851
change from Date to ZonedDateTime
Nov 20, 2024
fe7af6d
use system.currenttimemillis instead of zonedtimedate
Nov 20, 2024
28d0c44
Merge branch 'develop' of github.com:ls1intum/Artemis into feature/re…
Nov 20, 2024
1b257ed
allow scorpio to get vcs access token
Nov 20, 2024
07a408f
merge
janthoXO Nov 21, 2024
5b1dc16
Merge branch 'feature/re-key' of github.com:ls1intum/Artemis into fea…
iyannsch Nov 21, 2024
1ce1288
Merge branch 'feature/programming-exercises/provide-theia-clone-infor…
iyannsch Nov 21, 2024
e57a661
allow login and logout with scorpio
Nov 26, 2024
a3e0e63
Merge branch 'feature/re-key' of github.com:ls1intum/Artemis into fea…
Nov 26, 2024
f843afa
add server test
Nov 26, 2024
72a06f1
Merge branch 'feature/programming-exercise-by-projectkey' of github.c…
iyannsch Nov 26, 2024
f770151
Remove public from API URL
iyannsch Nov 26, 2024
6e6eea3
Refactor initTheia into changes
iyannsch Nov 26, 2024
7172f9c
Merge branch 'develop' of github.com:ls1intum/Artemis into feature/be…
iyannsch Nov 26, 2024
30a8652
Merge branch 'feature/bearer-support' into feature/re-key
iyannsch Nov 26, 2024
dd2e128
Merge branch 'feature/re-key' into feature/programming-exercises/prov…
iyannsch Nov 26, 2024
edb337a
Merge branch 'feature/programming-exercises/provide-theia-clone-infor…
iyannsch Nov 26, 2024
432148e
Refactor initTheia back into the init
iyannsch Nov 26, 2024
9fbbc39
Merge branch 'feature/programming-exercises/provide-theia-clone-infor…
iyannsch Nov 26, 2024
9fc561e
Adjust access modifier
iyannsch Nov 26, 2024
63973a5
Merge branch 'feature/programming-exercises/provide-theia-clone-infor…
iyannsch Nov 26, 2024
44489c3
allow scorpio to fetch feedback
janthoXO Dec 5, 2024
cc95100
fetch programming exercise with results
janthoXO Dec 6, 2024
c8698fc
Merge branch 'feature/programming-exercise-by-projectkey' of github.c…
janthoXO Dec 6, 2024
a1166ee
merge
janthoXO Dec 9, 2024
b99c037
merge
janthoXO Dec 9, 2024
504b2d3
merge
Dec 9, 2024
02c62a5
Merge branch 'develop' into feature/re-key
janthoXO Dec 10, 2024
6bbbb67
Merge branch 'develop' into feature/programming-exercises/provide-the…
iyannsch Dec 13, 2024
2214886
Merge branch 'develop' into feature/re-key
iyannsch Dec 13, 2024
49e988f
Merge branch 'develop' into feature/re-key
janthoXO Dec 21, 2024
62ebee9
allow plantUml for scorpio token
janthoXO Jan 6, 2025
02cb559
Merge branch 'feature/re-key' of github.com:ls1intum/Artemis into cho…
janthoXO Jan 6, 2025
3f8288d
Merge branch 'develop' of github.com:ls1intum/Artemis into feature/re…
janthoXO Jan 7, 2025
1a31996
limit tooltoken to api and not public api
janthoXO Jan 7, 2025
e9bb853
readd getClaim
janthoXO Jan 7, 2025
261fc2c
Merge branch 'feature/re-key' into feature/programming-exercises/prov…
iyannsch Jan 11, 2025
a6a6e3c
Add annotations
iyannsch Jan 16, 2025
1951b03
Merge branch 'develop' into feature/re-key
iyannsch Jan 16, 2025
a24f9dc
merge re-key
iyannsch Jan 16, 2025
440b3b7
fix double import
iyannsch Jan 16, 2025
1f776a8
Merge branch 'develop' of github.com:ls1intum/Artemis into feature/pr…
iyannsch Jan 24, 2025
405c2e1
Remove unused import
iyannsch Jan 24, 2025
c777709
merge feature/programming-exercises/provide-theia-clone-information-o…
janthoXO Jan 24, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
@Entity
@Table(name = "programming_exercise_build_config")
@JsonInclude(JsonInclude.Include.NON_EMPTY)
@JsonIgnoreProperties(value = { "programmingExercise" })
public class ProgrammingExerciseBuildConfig extends DomainObject {

private static final Logger log = LoggerFactory.getLogger(ProgrammingExerciseBuildConfig.class);
Expand Down Expand Up @@ -64,7 +65,6 @@ public class ProgrammingExerciseBuildConfig extends DomainObject {
private String dockerFlags;

@OneToOne(mappedBy = "buildConfig")
@JsonIgnoreProperties("buildConfig")
private ProgrammingExercise programmingExercise;

@Nullable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,14 @@ default void generateBuildPlanAccessSecretIfNotExists(ProgrammingExerciseBuildCo
default void loadAndSetBuildConfig(ProgrammingExercise programmingExercise) {
programmingExercise.setBuildConfig(getProgrammingExerciseBuildConfigElseThrow(programmingExercise));
}

/**
* Find a build config by its programming exercise's id and throw an Exception if it cannot be found
*
* @param programmingExerciseId of the programming exercise.
* @return The programming exercise related to the given id
*/
default ProgrammingExerciseBuildConfig findByExerciseIdElseThrow(long programmingExerciseId) {
return getValueElseThrow(findByProgrammingExerciseId(programmingExerciseId));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,25 @@ default ProgrammingExercise findOneByProjectKeyOrThrow(String projectKey, boolea
return exercises.getFirst();
}

/**
* Get a programmingExercise for a student, with the latest result and feedbacks.
*
* @param projectKey of the exercise that should be fetched.
* @return the exercise with the given ID, if found.
*/
@Query("""
SELECT DISTINCT pe
FROM ProgrammingExercise pe
LEFT JOIN FETCH pe.studentParticipations sp
LEFT JOIN FETCH sp.results spr
LEFT JOIN FETCH spr.feedbacks sf
LEFT JOIN FETCH sf.testCase
WHERE pe.projectKey = :projectKey
AND (spr.id = (SELECT MAX(re2.id) FROM sp.results re2) OR spr.id IS NULL)
AND (sp.student.id IS NULL OR sp.student.id = :studentId)
""")
Optional<ProgrammingExercise> findWithStudentParticipationLatestResultFeedbackTestCasesByProjectKey(@Param("studentId") long studentId, @Param("projectKey") String projectKey);

/**
* Get a programmingExercise with template participation, each with the latest result and feedbacks.
* NOTICE: this query is quite expensive because it loads all feedback and test cases, and it includes sub queries to retrieve the latest result
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,13 @@
import de.tum.cit.aet.artemis.core.repository.CourseRepository;
import de.tum.cit.aet.artemis.core.repository.UserRepository;
import de.tum.cit.aet.artemis.core.security.Role;
import de.tum.cit.aet.artemis.core.security.allowedTools.AllowedTools;
import de.tum.cit.aet.artemis.core.security.allowedTools.ToolTokenType;
import de.tum.cit.aet.artemis.core.security.annotations.EnforceAtLeastEditor;
import de.tum.cit.aet.artemis.core.security.annotations.EnforceAtLeastInstructor;
import de.tum.cit.aet.artemis.core.security.annotations.EnforceAtLeastStudent;
import de.tum.cit.aet.artemis.core.security.annotations.EnforceAtLeastTutor;
import de.tum.cit.aet.artemis.core.security.annotations.enforceRoleInExercise.EnforceAtLeastStudentInExercise;
import de.tum.cit.aet.artemis.core.security.annotations.enforceRoleInExercise.EnforceAtLeastTutorInExercise;
import de.tum.cit.aet.artemis.core.service.AuthorizationCheckService;
import de.tum.cit.aet.artemis.core.service.CourseService;
Expand All @@ -71,13 +75,15 @@
import de.tum.cit.aet.artemis.plagiarism.service.PlagiarismDetectionConfigHelper;
import de.tum.cit.aet.artemis.programming.domain.AuxiliaryRepository;
import de.tum.cit.aet.artemis.programming.domain.ProgrammingExercise;
import de.tum.cit.aet.artemis.programming.domain.ProgrammingExerciseBuildConfig;
import de.tum.cit.aet.artemis.programming.domain.ProgrammingExerciseTestCase;
import de.tum.cit.aet.artemis.programming.domain.ProgrammingLanguage;
import de.tum.cit.aet.artemis.programming.dto.BuildLogStatisticsDTO;
import de.tum.cit.aet.artemis.programming.dto.CheckoutDirectoriesDTO;
import de.tum.cit.aet.artemis.programming.dto.ProgrammingExerciseResetOptionsDTO;
import de.tum.cit.aet.artemis.programming.dto.ProgrammingExerciseTestCaseStateDTO;
import de.tum.cit.aet.artemis.programming.repository.BuildLogStatisticsEntryRepository;
import de.tum.cit.aet.artemis.programming.repository.ProgrammingExerciseBuildConfigRepository;
import de.tum.cit.aet.artemis.programming.repository.ProgrammingExerciseRepository;
import de.tum.cit.aet.artemis.programming.repository.ProgrammingExerciseTestCaseRepository;
import de.tum.cit.aet.artemis.programming.repository.SolutionProgrammingExerciseParticipationRepository;
Expand Down Expand Up @@ -114,6 +120,8 @@ public class ProgrammingExerciseResource {

private final ProgrammingExerciseTestCaseRepository programmingExerciseTestCaseRepository;

private final ProgrammingExerciseBuildConfigRepository programmingExerciseBuildConfigRepository;

private final UserRepository userRepository;

private final CourseService courseService;
Expand Down Expand Up @@ -157,9 +165,9 @@ public class ProgrammingExerciseResource {
private final Environment environment;

public ProgrammingExerciseResource(ProgrammingExerciseRepository programmingExerciseRepository, ProgrammingExerciseTestCaseRepository programmingExerciseTestCaseRepository,
UserRepository userRepository, AuthorizationCheckService authCheckService, CourseService courseService,
Optional<ContinuousIntegrationService> continuousIntegrationService, Optional<VersionControlService> versionControlService, ExerciseService exerciseService,
ExerciseDeletionService exerciseDeletionService, ProgrammingExerciseService programmingExerciseService,
ProgrammingExerciseBuildConfigRepository programmingExerciseBuildConfigRepository, UserRepository userRepository, AuthorizationCheckService authCheckService,
CourseService courseService, Optional<ContinuousIntegrationService> continuousIntegrationService, Optional<VersionControlService> versionControlService,
ExerciseService exerciseService, ExerciseDeletionService exerciseDeletionService, ProgrammingExerciseService programmingExerciseService,
ProgrammingExerciseRepositoryService programmingExerciseRepositoryService, ProgrammingExerciseTaskService programmingExerciseTaskService,
StudentParticipationRepository studentParticipationRepository, StaticCodeAnalysisService staticCodeAnalysisService,
GradingCriterionRepository gradingCriterionRepository, CourseRepository courseRepository, GitService gitService, AuxiliaryRepositoryService auxiliaryRepositoryService,
Expand All @@ -170,6 +178,7 @@ public ProgrammingExerciseResource(ProgrammingExerciseRepository programmingExer
this.programmingExerciseTaskService = programmingExerciseTaskService;
this.programmingExerciseRepository = programmingExerciseRepository;
this.programmingExerciseTestCaseRepository = programmingExerciseTestCaseRepository;
this.programmingExerciseBuildConfigRepository = programmingExerciseBuildConfigRepository;
this.userRepository = userRepository;
this.courseService = courseService;
this.authCheckService = authCheckService;
Expand Down Expand Up @@ -493,6 +502,21 @@ public ResponseEntity<ProgrammingExercise> getProgrammingExercise(@PathVariable
return ResponseEntity.ok().body(programmingExercise);
}

/**
* GET /programming-exercises/:exerciseId/build-config : get the build config of "exerciseId" programmingExercise.
*
* @param exerciseId the id of the programmingExercise to retrieve the config for
* @return the ResponseEntity with status 200 (OK) and with body the programmingExerciseBuildConfig, or with status 404 (Not Found)
*/
@GetMapping("programming-exercises/{exerciseId}/build-config")
@EnforceAtLeastStudentInExercise
public ResponseEntity<ProgrammingExerciseBuildConfig> getBuildConfig(@PathVariable long exerciseId) {
log.debug("REST request to get build config of ProgrammingExercise : {}", exerciseId);
var buildConfig = programmingExerciseBuildConfigRepository.findByExerciseIdElseThrow(exerciseId);

return ResponseEntity.ok().body(buildConfig);
}

/**
* GET /programming-exercises/:exerciseId/with-participations/ : get the "exerciseId" programmingExercise.
*
Expand Down Expand Up @@ -547,6 +571,26 @@ public ResponseEntity<ProgrammingExercise> getProgrammingExerciseWithAuxiliaryRe
return ResponseEntity.ok(programmingExercise);
}

/**
* GET /programming-exercises : Queries a programming exercise by its project key.
*
*
* @param projectKey the project key of the programming exercise
*
* @return the ProgrammingExercise of this project key in an ResponseEntity or 404 Not Found if no exercise exists
*/
@GetMapping("programming-exercises/project-key/{projectKey}")
@EnforceAtLeastStudent
@AllowedTools(ToolTokenType.SCORPIO)
public ResponseEntity<ProgrammingExercise> getExerciseByProjectKey(@PathVariable String projectKey) {
User user = userRepository.getUserWithGroupsAndAuthorities();

final ProgrammingExercise exercise = programmingExerciseRepository.findWithStudentParticipationLatestResultFeedbackTestCasesByProjectKey(user.getId(), projectKey)
.orElseThrow(() -> new EntityNotFoundException("ProgrammingExercise", projectKey));

return ResponseEntity.ok(exercise);
}

/**
* DELETE /programming-exercises/:id : delete the "id" programmingExercise.
*
Expand Down
10 changes: 5 additions & 5 deletions src/main/resources/config/application-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -131,15 +131,15 @@ eureka:

# Theia configuration
theia:
portal-url: https://theia-test.k8s.ase.cit.tum.de
portal-url: https://theia.artemis.cit.tum.de

images:
java:
Java-17: "ghcr.io/ls1intum/theia/java-17:latest"
Java-Test: "ghcr.io/ls1intum/theia/java-test:latest"
Java-Test2: "ghcr.io/ls1intum/theia/java-test:2"
Java-17: "java-17-latest"
Java-Test: "java-17-latest"
Java-Test2: "java-17-latest"
c:
C: "ghcr.io/ls1intum/theia/c:latest"
C: "c-latest"

artemis:
push-notification-relay: https://hermes-sandbox.artemis.cit.tum.de
Expand Down
4 changes: 2 additions & 2 deletions src/main/resources/config/application-theia.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ theia:
# Upper level key is the language category (must match the language key in the programming-exercise configuration)
java:
# Lower level key can be multiple flavors of the image, e.g. version, tag, or additional dependencies
Java-17: "my-registry/my-image:my-tag"
java17: "my-kubernetes-appdefinition"
# Add more flavors here (e.g. Java-11, Java-8, etc.)
# Add more languages here (e.g. c, python, etc.)
c:
C: "my-registry/my-image:my-tag"
C: "my-kubernetes-appdefinition"
8 changes: 8 additions & 0 deletions src/main/webapp/app/core/auth/account.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -362,4 +362,12 @@ export class AccountService implements IAccountService {
const params = new HttpParams().set('participationId', participationId);
return this.http.put<string>('api/account/participation-vcs-access-token', null, { observe: 'response', params, responseType: 'text' as 'json' });
}

/**
* Trades the current cookie for a new Tool-specific bearer token which is able to authenticate the user.
* The Cookie stays valid, a new bearer token is generated on every call with a validity of max 1d.
*/
getToolToken(tool: string): Observable<string> {
return this.http.post<string>('api/tool-token', null, { params: { tool: tool }, responseType: 'text' as 'json' });
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { Participation } from 'app/entities/participation/participation.model';
import { PlagiarismResultDTO } from 'app/exercises/shared/plagiarism/types/PlagiarismResultDTO';
import { ImportOptions } from 'app/types/programming-exercises';
import { CheckoutDirectoriesDto } from 'app/entities/programming/checkout-directories-dto';
import { ProgrammingExerciseBuildConfig } from 'app/entities/programming/programming-exercise-build.config';

export type EntityResponseType = HttpResponse<ProgrammingExercise>;
export type EntityArrayResponseType = HttpResponse<ProgrammingExercise[]>;
Expand Down Expand Up @@ -624,6 +625,10 @@ export class ProgrammingExerciseService {
return this.http.get<BuildLogStatisticsDTO>(`${this.resourceUrl}/${exerciseId}/build-log-statistics`);
}

getBuildConfig(exerciseId: number): Observable<ProgrammingExerciseBuildConfig> {
return this.http.get<ProgrammingExerciseBuildConfig>(`${this.resourceUrl}/${exerciseId}/build-config`);
}

/** Imports a programming exercise from a given zip file **/
importFromFile(exercise: ProgrammingExercise, courseId: number): Observable<EntityResponseType> {
let copy = this.convertDataFromClient(exercise);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,12 +132,6 @@
[useParticipationVcsAccessToken]="true"
/>
}
@if (theiaEnabled) {
<a class="btn btn-primary" [class.btn-sm]="smallButtons" (click)="startOnlineIDE()" target="_blank" rel="noopener noreferrer">
<fa-icon [icon]="faDesktop" [fixedWidth]="true" />
<span class="d-none d-md-inline" jhiTranslate="artemisApp.exerciseActions.openOnlineIDE"></span>
</a>
}
@if (exercise.allowFeedbackRequests && gradedParticipation && exercise.type === ExerciseType.PROGRAMMING) {
<jhi-request-feedback-button [exercise]="exercise" [smallButtons]="smallButtons" />
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ import { ProgrammingExercise } from 'app/entities/programming/programming-exerci
import { StudentParticipation } from 'app/entities/participation/student-participation.model';
import { ArtemisQuizService } from 'app/shared/quiz/quiz.service';
import { finalize } from 'rxjs/operators';
import { faDesktop, faEye, faFolderOpen, faPlayCircle, faRedo, faUsers } from '@fortawesome/free-solid-svg-icons';
import { faEye, faFolderOpen, faPlayCircle, faRedo, faUsers } from '@fortawesome/free-solid-svg-icons';
import { CourseExerciseService } from 'app/exercises/shared/course-exercises/course-exercise.service';
import { ParticipationService } from 'app/exercises/shared/participation/participation.service';
import dayjs from 'dayjs/esm';
import { QuizExercise } from 'app/entities/quiz/quiz-exercise.model';
import { ProfileService } from 'app/shared/layouts/profiles/profile.service';
import { PROFILE_ATHENA, PROFILE_LOCALVC, PROFILE_THEIA } from 'app/app.constants';
import { PROFILE_ATHENA, PROFILE_LOCALVC } from 'app/app.constants';
import { AssessmentType } from 'app/entities/assessment-type.model';
import { ButtonType } from 'app/shared/components/button.component';
import { NgTemplateOutlet } from '@angular/common';
Expand Down Expand Up @@ -51,8 +51,8 @@ import { ArtemisTranslatePipe } from 'app/shared/pipes/artemis-translate.pipe';
],
providers: [ExternalCloningService],
selector: 'jhi-exercise-details-student-actions',
styleUrls: ['../course-overview.scss'],
templateUrl: './exercise-details-student-actions.component.html',
styleUrls: ['../course-overview.scss'],
})
export class ExerciseDetailsStudentActionsComponent implements OnInit, OnChanges {
private alertService = inject(AlertService);
Expand Down Expand Up @@ -95,16 +95,12 @@ export class ExerciseDetailsStudentActionsComponent implements OnInit, OnChanges
routerLink: string;
repositoryLink: string;

theiaEnabled = false;
theiaPortalURL: string;

// Icons
readonly faFolderOpen = faFolderOpen;
readonly faUsers = faUsers;
readonly faEye = faEye;
readonly faPlayCircle = faPlayCircle;
readonly faRedo = faRedo;
readonly faDesktop = faDesktop;

ngOnInit(): void {
this.repositoryLink = this.router.url;
Expand Down Expand Up @@ -132,29 +128,6 @@ export class ExerciseDetailsStudentActionsComponent implements OnInit, OnChanges
this.profileService.getProfileInfo().subscribe((profileInfo) => {
this.localVCEnabled = profileInfo.activeProfiles?.includes(PROFILE_LOCALVC);
this.athenaEnabled = profileInfo.activeProfiles?.includes(PROFILE_ATHENA);

// The online IDE is only available with correct SpringProfile and if it's enabled for this exercise
if (profileInfo.activeProfiles?.includes(PROFILE_THEIA) && this.programmingExercise) {
this.theiaEnabled = true;

// Set variables now, sanitize later on
this.theiaPortalURL = profileInfo.theiaPortalURL ?? '';

// Verify that Theia's portal URL is set
if (this.theiaPortalURL === '') {
this.theiaEnabled = false;
}

// Verify that the exercise allows the online IDE
if (!this.programmingExercise.allowOnlineIde) {
this.theiaEnabled = false;
}

// Verify that the exercise has a theia blueprint configured
if (!this.programmingExercise.buildConfig?.theiaImage) {
this.theiaEnabled = false;
}
}
});
} else if (this.exercise.type === ExerciseType.MODELING) {
this.editorLabel = 'openModelingEditor';
Expand All @@ -181,10 +154,6 @@ export class ExerciseDetailsStudentActionsComponent implements OnInit, OnChanges
this.isTeamAvailable = !!(this.exercise.teamMode && this.exercise.studentAssignedTeamIdComputed && this.exercise.studentAssignedTeamId);
}

startOnlineIDE() {
window.open(this.theiaPortalURL, '_blank');
}

receiveNewParticipation(newParticipation: StudentParticipation) {
const studentParticipations = this.exercise.studentParticipations ?? [];
if (studentParticipations.map((participation) => participation.id).includes(newParticipation.id)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,11 @@ <h5>{{ cloneHeadline | artemisTranslate }}</h5>
style="min-width: 100px"
jhiTranslate="{{ wasCopied ? 'artemisApp.exerciseActions.copiedUrl' : 'artemisApp.exerciseActions.copyUrl' }}"
></button>
@if (theiaEnabled) {
<a class="btn btn-primary btn-sm me-2" (click)="startOnlineIDE()" target="_blank" rel="noopener noreferrer">
<span class="d-none d-md-inline" jhiTranslate="artemisApp.exerciseActions.openOnlineIDE"></span>
</a>
}
<a
class="btn btn-primary btn-sm"
target="hidden-iframe"
Expand Down
Loading
Loading