Search in sources :

Example 1 with Exercise

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);
}
Also used : Exercise(de.tum.in.www1.artemis.domain.Exercise) IOException(java.io.IOException)

Example 2 with Exercise

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());
}
Also used : User(de.tum.in.www1.artemis.domain.User) ProgrammingExercise(de.tum.in.www1.artemis.domain.ProgrammingExercise) Course(de.tum.in.www1.artemis.domain.Course) Timed(com.codahale.metrics.annotation.Timed) PreAuthorize(org.springframework.security.access.prepost.PreAuthorize)

Example 3 with Exercise

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);
}
Also used : User(de.tum.in.www1.artemis.domain.User) ProgrammingExercise(de.tum.in.www1.artemis.domain.ProgrammingExercise) Course(de.tum.in.www1.artemis.domain.Course) Timed(com.codahale.metrics.annotation.Timed) PreAuthorize(org.springframework.security.access.prepost.PreAuthorize)

Example 4 with Exercise

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());
}
Also used : Path(java.nio.file.Path) GitAPIException(org.eclipse.jgit.api.errors.GitAPIException) ExerciseRepository(de.tum.in.www1.artemis.repository.ExerciseRepository) BambooException(de.tum.in.www1.artemis.exception.BambooException) IOException(java.io.IOException) Transactional(org.springframework.transaction.annotation.Transactional)

Example 5 with Exercise

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);
    }
}
Also used : LtiLaunchRequestDTO(de.tum.in.www1.artemis.web.rest.dto.LtiLaunchRequestDTO)

Aggregations

ProgrammingExercise (de.tum.in.www1.artemis.domain.ProgrammingExercise)6 Transactional (org.springframework.transaction.annotation.Transactional)6 Timed (com.codahale.metrics.annotation.Timed)4 Exercise (de.tum.in.www1.artemis.domain.Exercise)4 PreAuthorize (org.springframework.security.access.prepost.PreAuthorize)4 Course (de.tum.in.www1.artemis.domain.Course)3 User (de.tum.in.www1.artemis.domain.User)3 IOException (java.io.IOException)3 Test (org.junit.Test)3 SpringBootTest (org.springframework.boot.test.context.SpringBootTest)3 ExerciseRepository (de.tum.in.www1.artemis.repository.ExerciseRepository)2 URI (java.net.URI)2 Path (java.nio.file.Path)2 GitAPIException (org.eclipse.jgit.api.errors.GitAPIException)2 Result (de.tum.in.www1.artemis.domain.Result)1 BambooException (de.tum.in.www1.artemis.exception.BambooException)1 LtiLaunchRequestDTO (de.tum.in.www1.artemis.web.rest.dto.LtiLaunchRequestDTO)1 BadRequestAlertException (de.tum.in.www1.artemis.web.rest.errors.BadRequestAlertException)1