use of de.tum.in.www1.artemis.domain.Exercise in project ArTEMiS by ls1intum.
the class LtiResource method launch.
/**
* POST /lti/launch/:exerciseId : Launch the exercise app using request by a LTI consumer. Redirects the user to the exercise on success.
*
* @param launchRequest the LTI launch request (ExerciseLtiConfigurationDTO)
* @param exerciseId the id of the exercise the user wants to open
* @param request HTTP request
* @param response HTTP response
*/
@PostMapping(value = "/lti/launch/{exerciseId}", produces = MediaType.APPLICATION_JSON_VALUE)
public void launch(@ModelAttribute LtiLaunchRequestDTO launchRequest, @PathVariable("exerciseId") Long exerciseId, HttpServletRequest request, HttpServletResponse response) throws IOException {
log.debug("Launch request : {}", launchRequest);
// Verify request
if (!ltiService.verifyRequest(request)) {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Bad or expired request. Please try again.");
return;
}
// Check if exercise ID is valid
Exercise exercise = exerciseRepository.findOne(exerciseId);
if (exercise == null) {
response.sendError(HttpServletResponse.SC_NOT_FOUND, "Exercise not found");
return;
}
// Handle the launch request using LtiService
try {
ltiService.handleLaunchRequest(launchRequest, exercise);
} catch (Exception ex) {
log.error("Error during LIT launch request of exercise " + exercise.getTitle() + ": " + ex.getMessage());
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, ex.getMessage());
return;
}
// If the current user was created within the last 15 seconds, we just created the user
// Display a welcome message to the user
Boolean isNewUser = SecurityUtils.isAuthenticated() && TimeUnit.SECONDS.toMinutes(ZonedDateTime.now().toEpochSecond() - userService.getUser().getCreatedDate().toEpochMilli() * 1000) < 15;
String redirectUrl = // "http"
request.getScheme() + // "://"
"://" + // "myhost"
request.getServerName() + (request.getServerPort() != 80 && request.getServerPort() != 443 ? ":" + request.getServerPort() : "") + "/#/courses/" + exercise.getCourse().getId() + "/exercise/" + exercise.getId() + (isNewUser ? "?welcome" : "") + (!SecurityUtils.isAuthenticated() ? "?login" : "");
response.sendRedirect(redirectUrl);
}
use of de.tum.in.www1.artemis.domain.Exercise in project ArTEMiS by ls1intum.
the class ProgrammingExerciseResource method getAllProgrammingExercises.
/**
* GET /programming-exercises : get all the programmingExercises.
*
* @return the ResponseEntity with status 200 (OK) and the list of programmingExercises in body
*/
@GetMapping("/programming-exercises")
@PreAuthorize("hasAnyRole('TA', 'INSTRUCTOR', 'ADMIN')")
@Timed
public List<ProgrammingExercise> getAllProgrammingExercises() {
log.debug("REST request to get all ProgrammingExercises");
List<ProgrammingExercise> exercises = programmingExerciseRepository.findAll();
Stream<ProgrammingExercise> authorizedExercises = exercises.stream().filter(exercise -> {
Course course = exercise.getCourse();
User user = userService.getUserWithGroupsAndAuthorities();
return authCheckService.isTeachingAssistantInCourse(course, user) || authCheckService.isInstructorInCourse(course, user) || authCheckService.isAdmin();
});
return authorizedExercises.collect(Collectors.toList());
}
use of de.tum.in.www1.artemis.domain.Exercise in project ArTEMiS by ls1intum.
the class ProgrammingExerciseResource method updateProgrammingExercise.
/**
* PUT /programming-exercises : Updates an existing programmingExercise.
*
* @param programmingExercise the programmingExercise to update
* @return the ResponseEntity with status 200 (OK) and with body the updated programmingExercise,
* or with status 400 (Bad Request) if the programmingExercise is not valid,
* or with status 500 (Internal Server Error) if the programmingExercise couldn't be updated
* @throws URISyntaxException if the Location URI syntax is incorrect
*/
@PutMapping("/programming-exercises")
@PreAuthorize("hasAnyRole('TA', 'INSTRUCTOR', 'ADMIN')")
@Timed
public ResponseEntity<ProgrammingExercise> updateProgrammingExercise(@RequestBody ProgrammingExercise programmingExercise) throws URISyntaxException {
log.debug("REST request to update ProgrammingExercise : {}", programmingExercise);
if (programmingExercise.getId() == null) {
return createProgrammingExercise(programmingExercise);
}
// fetch course from database to make sure client didn't change groups
Course course = courseService.findOne(programmingExercise.getCourse().getId());
if (course == null) {
return ResponseEntity.badRequest().headers(HeaderUtil.createFailureAlert(ENTITY_NAME, "courseNotFound", "The course belonging to this programming exercise does not exist")).body(null);
}
User user = userService.getUserWithGroupsAndAuthorities();
if (!authCheckService.isTeachingAssistantInCourse(course, user) && !authCheckService.isInstructorInCourse(course, user) && !authCheckService.isAdmin()) {
return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
}
ResponseEntity<ProgrammingExercise> errorResponse = checkProgrammingExerciseForError(programmingExercise);
if (errorResponse != null) {
return errorResponse;
}
ProgrammingExercise result = programmingExerciseRepository.save(programmingExercise);
return ResponseEntity.ok().headers(HeaderUtil.createEntityUpdateAlert(ENTITY_NAME, programmingExercise.getId().toString())).body(result);
}
use of de.tum.in.www1.artemis.domain.Exercise in project ArTEMiS by ls1intum.
the class ExerciseService method cleanup.
/**
* Delete build plans (except BASE) and optionally repositores of all exercise participations.
*
* @param id id of the exercise for which build plans in respective participations are deleted
*/
@Transactional
public java.io.File cleanup(Long id, boolean deleteRepositories) throws java.io.IOException {
Exercise exercise = findOneLoadParticipations(id);
log.info("Request to cleanup all participations for Exercise : {}", exercise.getTitle());
List<Repository> studentRepositories = new ArrayList<>();
Path finalZipFilePath = null;
if (Optional.ofNullable(exercise).isPresent() && exercise instanceof ProgrammingExercise) {
exercise.getParticipations().forEach(participation -> {
if (participation.getBuildPlanId() != null) {
// ignore participations without build plan id
try {
continuousIntegrationService.get().deleteBuildPlan(participation.getBuildPlanId());
} catch (BambooException ex) {
log.error(ex.getMessage());
if (ex.getCause() != null) {
log.error(ex.getCause().getMessage());
}
}
participation.setInitializationState(ParticipationState.INACTIVE);
participation.setBuildPlanId(null);
participationService.save(participation);
}
if (deleteRepositories == true && participation.getRepositoryUrl() != null) {
// ignore participations without repository URL
try {
// 1. clone the repository
Repository repo = gitService.get().getOrCheckoutRepository(participation);
// 2. collect the repo file
studentRepositories.add(repo);
} catch (GitAPIException | IOException ex) {
log.error("Archiving and deleting the repository " + participation.getRepositoryUrlAsUrl() + " did not work as expected", ex);
}
}
});
if (deleteRepositories == false) {
// in this case, we are done
return null;
}
if (studentRepositories.isEmpty()) {
log.info("No student repositories have been found.");
return null;
}
// from here on, deleteRepositories is true and does not need to be evaluated again
log.info("Create zip file for all repositories");
Files.createDirectories(Paths.get("zippedRepos"));
finalZipFilePath = Paths.get("zippedRepos", exercise.getCourse().getTitle() + " " + exercise.getTitle() + " Student Repositories.zip");
zipAllRepositories(studentRepositories, finalZipFilePath);
exercise.getParticipations().forEach(participation -> {
if (participation.getRepositoryUrl() != null) {
// ignore participations without repository URL
try {
// 3. delete the locally cloned repo again
gitService.get().deleteLocalRepository(participation);
} catch (IOException e) {
log.error("Archiving and deleting the repository " + participation.getRepositoryUrlAsUrl() + " did not work as expected", e);
}
// 4. finally delete the repository on the VC Server
versionControlService.get().deleteRepository(participation.getRepositoryUrlAsUrl());
participation.setRepositoryUrl(null);
participation.setInitializationState(ParticipationState.FINISHED);
participationService.save(participation);
}
});
scheduleForDeletion(finalZipFilePath, 300);
} else {
log.info("Exercise with id {} is not an instance of ProgrammingExercise. Ignoring the request to cleanup repositories and build plan", id);
return null;
}
return new java.io.File(finalZipFilePath.toString());
}
use of de.tum.in.www1.artemis.domain.Exercise in project ArTEMiS by ls1intum.
the class LtiService method handleLaunchRequestForSession.
/**
* Handle launch request which was initiated earlier by a LTI consumer
*
* @param sessionId
*/
public void handleLaunchRequestForSession(String sessionId) {
if (launchRequestForSession.containsKey(sessionId)) {
log.debug("Found LTI launchRequest for session ID {}", sessionId);
LtiLaunchRequestDTO launchRequest = launchRequestForSession.get(sessionId).getLeft();
Exercise exercise = launchRequestForSession.get(sessionId).getRight();
onSuccessfulLtiAuthentication(launchRequest, exercise);
// clean up
launchRequestForSession.remove(sessionId);
}
}
Aggregations