Search in sources :

Example 21 with EntityNotFoundException

use of de.tum.in.www1.artemis.web.rest.errors.EntityNotFoundException in project ArTEMiS by ls1intum.

the class ProgrammingExerciseExportImportResource method importProgrammingExercise.

/**
 * POST /programming-exercises/import: Imports an existing programming exercise into an existing course
 * <p>
 * This will import the whole exercise, including all base build plans (template, solution) and repositories
 * (template, solution, test). Referenced entities, s.a. the test cases or the hints will get cloned and assigned
 * a new id. For a concrete list of what gets copied and what not have a look
 * at {@link ProgrammingExerciseImportService#importProgrammingExerciseBasis(ProgrammingExercise, ProgrammingExercise)}
 *
 * @param sourceExerciseId   The ID of the original exercise which should get imported
 * @param newExercise        The new exercise containing values that should get overwritten in the imported exercise, s.a. the title or difficulty
 * @param recreateBuildPlans Option determining whether the build plans should be copied or re-created from scratch
 * @param updateTemplate     Option determining whether the template files should be updated with the most recent template version
 * @return The imported exercise (200), a not found error (404) if the template does not exist, or a forbidden error
 * (403) if the user is not at least an instructor in the target course.
 * @see ProgrammingExerciseImportService#importProgrammingExerciseBasis(ProgrammingExercise, ProgrammingExercise)
 * @see ProgrammingExerciseImportService#importBuildPlans(ProgrammingExercise, ProgrammingExercise)
 * @see ProgrammingExerciseImportService#importRepositories(ProgrammingExercise, ProgrammingExercise)
 */
@PostMapping(IMPORT)
@PreAuthorize("hasRole('EDITOR')")
@FeatureToggle(Feature.ProgrammingExercises)
public ResponseEntity<ProgrammingExercise> importProgrammingExercise(@PathVariable long sourceExerciseId, @RequestBody ProgrammingExercise newExercise, @RequestParam(defaultValue = "false") boolean recreateBuildPlans, @RequestParam(defaultValue = "false") boolean updateTemplate) {
    if (sourceExerciseId < 0) {
        throw new BadRequestAlertException("Invalid source id when importing programming exercises", ENTITY_NAME, "invalidSourceExerciseId");
    }
    // Valid exercises have set either a course or an exerciseGroup
    newExercise.checkCourseAndExerciseGroupExclusivity(ENTITY_NAME);
    log.debug("REST request to import programming exercise {} into course {}", sourceExerciseId, newExercise.getCourseViaExerciseGroupOrCourseMember().getId());
    newExercise.validateGeneralSettings();
    newExercise.validateProgrammingSettings();
    validateStaticCodeAnalysisSettings(newExercise);
    final var user = userRepository.getUserWithGroupsAndAuthorities();
    Course course = courseService.retrieveCourseOverExerciseGroupOrCourseId(newExercise);
    authCheckService.checkHasAtLeastRoleInCourseElseThrow(Role.EDITOR, course, user);
    // Validate course settings
    programmingExerciseRepository.validateCourseSettings(newExercise, course);
    final var originalProgrammingExercise = programmingExerciseRepository.findByIdWithEagerTestCasesStaticCodeAnalysisCategoriesHintsAndTemplateAndSolutionParticipationsAndAuxReposAndTasksWithTestCases(sourceExerciseId).orElseThrow(() -> new EntityNotFoundException("ProgrammingExercise", sourceExerciseId));
    // The static code analysis flag can only change, if the build plans are recreated and the template is upgraded
    if (newExercise.isStaticCodeAnalysisEnabled() != originalProgrammingExercise.isStaticCodeAnalysisEnabled() && !(recreateBuildPlans && updateTemplate)) {
        throw new BadRequestAlertException("Static code analysis can only change, if the recreation of build plans and update of template files is activated", ENTITY_NAME, "staticCodeAnalysisCannotChange");
    }
    // If the new exercise has a submission policy, it must be validated.
    if (newExercise.getSubmissionPolicy() != null) {
        submissionPolicyService.validateSubmissionPolicy(newExercise.getSubmissionPolicy());
    }
    // Check if the user has the rights to access the original programming exercise
    Course originalCourse = courseService.retrieveCourseOverExerciseGroupOrCourseId(originalProgrammingExercise);
    authCheckService.checkHasAtLeastRoleInCourseElseThrow(Role.EDITOR, originalCourse, user);
    newExercise.generateAndSetProjectKey();
    programmingExerciseService.checkIfProjectExists(newExercise);
    final var importedProgrammingExercise = programmingExerciseImportService.importProgrammingExerciseBasis(originalProgrammingExercise, newExercise);
    programmingExerciseImportService.importRepositories(originalProgrammingExercise, importedProgrammingExercise);
    // Update the template files
    if (updateTemplate) {
        TemplateUpgradeService upgradeService = templateUpgradePolicy.getUpgradeService(importedProgrammingExercise.getProgrammingLanguage());
        upgradeService.upgradeTemplate(importedProgrammingExercise);
    }
    HttpHeaders responseHeaders;
    // Copy or recreate the build plans
    try {
        if (recreateBuildPlans) {
            // Create completely new build plans for the exercise
            programmingExerciseService.setupBuildPlansForNewExercise(importedProgrammingExercise);
        } else {
            // We have removed the automatic build trigger from test to base for new programming exercises.
            // We also remove this build trigger in the case of an import as the source exercise might still have this trigger.
            // The importBuildPlans method includes this process
            programmingExerciseImportService.importBuildPlans(originalProgrammingExercise, importedProgrammingExercise);
        }
        responseHeaders = HeaderUtil.createEntityCreationAlert(applicationName, true, ENTITY_NAME, importedProgrammingExercise.getTitle());
    } catch (Exception e) {
        responseHeaders = HeaderUtil.createFailureAlert(applicationName, true, ENTITY_NAME, "importExerciseTriggerPlanFail", "Unable to trigger imported build plans");
    }
    programmingExerciseService.scheduleOperations(importedProgrammingExercise.getId());
    // Remove unnecessary fields
    importedProgrammingExercise.setTestCases(null);
    importedProgrammingExercise.setStaticCodeAnalysisCategories(null);
    importedProgrammingExercise.setTemplateParticipation(null);
    importedProgrammingExercise.setSolutionParticipation(null);
    importedProgrammingExercise.setExerciseHints(null);
    importedProgrammingExercise.setTasks(null);
    return ResponseEntity.ok().headers(responseHeaders).body(importedProgrammingExercise);
}
Also used : BadRequestAlertException(de.tum.in.www1.artemis.web.rest.errors.BadRequestAlertException) HttpHeaders(org.springframework.http.HttpHeaders) EntityNotFoundException(de.tum.in.www1.artemis.web.rest.errors.EntityNotFoundException) Course(de.tum.in.www1.artemis.domain.Course) BadRequestAlertException(de.tum.in.www1.artemis.web.rest.errors.BadRequestAlertException) IOException(java.io.IOException) EntityNotFoundException(de.tum.in.www1.artemis.web.rest.errors.EntityNotFoundException) FeatureToggle(de.tum.in.www1.artemis.service.feature.FeatureToggle) PreAuthorize(org.springframework.security.access.prepost.PreAuthorize)

Example 22 with EntityNotFoundException

use of de.tum.in.www1.artemis.web.rest.errors.EntityNotFoundException in project ArTEMiS by ls1intum.

the class ProgrammingExerciseParticipationResource method getParticipationWithLatestResultForStudentParticipation.

/**
 * Get the given student participation with its latest result and feedbacks.
 *
 * @param participationId for which to retrieve the student participation with latest result and feedbacks.
 * @return the ResponseEntity with status 200 (OK) and the participation with its latest result in the body.
 */
@GetMapping("/programming-exercise-participations/{participationId}/student-participation-with-latest-result-and-feedbacks")
@PreAuthorize("hasRole('USER')")
public ResponseEntity<Participation> getParticipationWithLatestResultForStudentParticipation(@PathVariable Long participationId) {
    ProgrammingExerciseStudentParticipation participation = programmingExerciseStudentParticipationRepository.findStudentParticipationWithLatestResultAndFeedbacksAndRelatedSubmissions(participationId).orElseThrow(() -> new EntityNotFoundException("Participation", participationId));
    if (!programmingExerciseParticipationService.canAccessParticipation(participation)) {
        throw new AccessForbiddenException("participation", participationId);
    }
    if (!authCheckService.isAtLeastTeachingAssistantForExercise(participation.getExercise())) {
        // hide details that should not be shown to the students
        participation.getExercise().filterSensitiveInformation();
        participation.getResults().forEach(result -> filterSensitiveInformationInResult(participation, result));
    }
    return ResponseEntity.ok(participation);
}
Also used : ProgrammingExerciseStudentParticipation(de.tum.in.www1.artemis.domain.participation.ProgrammingExerciseStudentParticipation) EntityNotFoundException(de.tum.in.www1.artemis.web.rest.errors.EntityNotFoundException) AccessForbiddenException(de.tum.in.www1.artemis.web.rest.errors.AccessForbiddenException) PreAuthorize(org.springframework.security.access.prepost.PreAuthorize)

Example 23 with EntityNotFoundException

use of de.tum.in.www1.artemis.web.rest.errors.EntityNotFoundException in project ArTEMiS by ls1intum.

the class CourseResource method downloadCourseArchive.

/**
 * Downloads the zip file of the archived course if it exists. Throws a 404 if the course doesn't exist
 *
 * @param courseId The course id of the archived course
 * @return ResponseEntity with status
 */
@PreAuthorize("hasRole('INSTRUCTOR')")
@GetMapping("/courses/{courseId}/download-archive")
public ResponseEntity<Resource> downloadCourseArchive(@PathVariable Long courseId) throws FileNotFoundException {
    log.info("REST request to download archive of Course : {}", courseId);
    final Course course = courseRepository.findByIdElseThrow(courseId);
    authCheckService.checkHasAtLeastRoleInCourseElseThrow(Role.INSTRUCTOR, course, null);
    if (!course.hasCourseArchive()) {
        throw new EntityNotFoundException("Archived course", courseId);
    }
    // The path is stored in the course table
    Path archive = Path.of(courseArchivesDirPath, course.getCourseArchivePath());
    File zipFile = archive.toFile();
    InputStreamResource resource = new InputStreamResource(new FileInputStream(zipFile));
    return ResponseEntity.ok().contentLength(zipFile.length()).contentType(MediaType.APPLICATION_OCTET_STREAM).header("filename", zipFile.getName()).body(resource);
}
Also used : Path(java.nio.file.Path) EntityNotFoundException(de.tum.in.www1.artemis.web.rest.errors.EntityNotFoundException) File(java.io.File) FileInputStream(java.io.FileInputStream) InputStreamResource(org.springframework.core.io.InputStreamResource) PreAuthorize(org.springframework.security.access.prepost.PreAuthorize)

Example 24 with EntityNotFoundException

use of de.tum.in.www1.artemis.web.rest.errors.EntityNotFoundException in project ArTEMiS by ls1intum.

the class ProgrammingExerciseResource method updateProblemStatement.

/**
 * PATCH /programming-exercises-problem: Updates the problem statement of the exercise.
 *
 * @param exerciseId              The ID of the exercise for which to change the problem statement
 * @param updatedProblemStatement The new problemStatement
 * @param notificationText        to notify the student group about the updated problemStatement on the programming exercise
 * @return the ResponseEntity with status 200 (OK) and with body the updated problemStatement, with status 404 if the programmingExercise could not be found, or with 403 if the user does not have permissions to access the programming exercise.
 */
@PatchMapping(PROBLEM)
@PreAuthorize("hasRole('EDITOR')")
public ResponseEntity<ProgrammingExercise> updateProblemStatement(@PathVariable long exerciseId, @RequestBody String updatedProblemStatement, @RequestParam(value = "notificationText", required = false) String notificationText) {
    log.debug("REST request to update ProgrammingExercise with new problem statement: {}", updatedProblemStatement);
    var programmingExercise = programmingExerciseRepository.findWithTemplateAndSolutionParticipationTeamAssignmentConfigCategoriesById(exerciseId).orElseThrow(() -> new EntityNotFoundException("Programming Exercise", exerciseId));
    var user = userRepository.getUserWithGroupsAndAuthorities();
    authCheckService.checkHasAtLeastRoleForExerciseElseThrow(Role.EDITOR, programmingExercise, user);
    var updatedProgrammingExercise = programmingExerciseService.updateProblemStatement(programmingExercise, updatedProblemStatement, notificationText);
    exerciseService.logUpdate(updatedProgrammingExercise, updatedProgrammingExercise.getCourseViaExerciseGroupOrCourseMember(), user);
    return ResponseEntity.ok().headers(HeaderUtil.createEntityUpdateAlert(applicationName, true, ENTITY_NAME, updatedProgrammingExercise.getTitle())).body(updatedProgrammingExercise);
}
Also used : EntityNotFoundException(de.tum.in.www1.artemis.web.rest.errors.EntityNotFoundException) PreAuthorize(org.springframework.security.access.prepost.PreAuthorize)

Example 25 with EntityNotFoundException

use of de.tum.in.www1.artemis.web.rest.errors.EntityNotFoundException in project ArTEMiS by ls1intum.

the class ProgrammingSubmissionResultSimulationResource method createNewProgrammingExerciseResult.

/**
 * This method is used to notify artemis that there is a new programming exercise build result.
 * This result is only a SIMULATION for the testing of programming exercises without a connection
 * to the VCS and CI server
 * This functionality is only for testing purposes (noVersionControlAndContinuousIntegrationAvailable)
 * @param exerciseId id of the exercise
 * @return HTTP OK and Result
 */
@PostMapping(Endpoints.RESULTS_SIMULATION)
@PreAuthorize("hasRole('EDITOR')")
public ResponseEntity<Result> createNewProgrammingExerciseResult(@PathVariable Long exerciseId) {
    log.debug("Received result notify (NEW)");
    User user = userRepository.getUserWithGroupsAndAuthorities();
    ProgrammingExercise programmingExercise = programmingExerciseRepository.findByIdWithStudentParticipationsAndLegalSubmissionsElseThrow(exerciseId);
    var studentParticipation = participationService.findOneByExerciseAndParticipantAnyState(programmingExercise, user).orElseThrow(() -> new EntityNotFoundException("Participation for programming exercise " + programmingExercise.getId() + " and user " + user.getLogin() + " not found!"));
    var programmingExerciseStudentParticipation = (ProgrammingExerciseStudentParticipation) studentParticipation;
    Result result = programmingSubmissionResultSimulationService.createResult(programmingExerciseStudentParticipation);
    messagingService.broadcastNewResult(programmingExerciseStudentParticipation, result);
    log.info("The new result for {} was saved successfully", programmingExerciseStudentParticipation.getBuildPlanId());
    try {
        return ResponseEntity.created(new URI("/api/results" + result.getId())).body(result);
    } catch (URISyntaxException e) {
        log.error("Error while simulating a result", e);
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).headers(HeaderUtil.createAlert(applicationName, "An error occurred while simulating a result: " + e.getMessage(), "errorResult")).body(null);
    }
}
Also used : ProgrammingExerciseStudentParticipation(de.tum.in.www1.artemis.domain.participation.ProgrammingExerciseStudentParticipation) EntityNotFoundException(de.tum.in.www1.artemis.web.rest.errors.EntityNotFoundException) URISyntaxException(java.net.URISyntaxException) URI(java.net.URI) PostMapping(org.springframework.web.bind.annotation.PostMapping) PreAuthorize(org.springframework.security.access.prepost.PreAuthorize)

Aggregations

EntityNotFoundException (de.tum.in.www1.artemis.web.rest.errors.EntityNotFoundException)96 PreAuthorize (org.springframework.security.access.prepost.PreAuthorize)42 StudentParticipation (de.tum.in.www1.artemis.domain.participation.StudentParticipation)20 BadRequestAlertException (de.tum.in.www1.artemis.web.rest.errors.BadRequestAlertException)20 StudentExam (de.tum.in.www1.artemis.domain.exam.StudentExam)16 AccessForbiddenException (de.tum.in.www1.artemis.web.rest.errors.AccessForbiddenException)12 Exam (de.tum.in.www1.artemis.domain.exam.Exam)10 QuizExercise (de.tum.in.www1.artemis.domain.quiz.QuizExercise)10 AuditEvent (org.springframework.boot.actuate.audit.AuditEvent)10 User (de.tum.in.www1.artemis.domain.User)9 ExerciseGroup (de.tum.in.www1.artemis.domain.exam.ExerciseGroup)8 ModelingExercise (de.tum.in.www1.artemis.domain.modeling.ModelingExercise)8 java.util (java.util)8 Collectors (java.util.stream.Collectors)8 Logger (org.slf4j.Logger)8 LoggerFactory (org.slf4j.LoggerFactory)8 Service (org.springframework.stereotype.Service)8 de.tum.in.www1.artemis.domain (de.tum.in.www1.artemis.domain)6 Course (de.tum.in.www1.artemis.domain.Course)6 Result (de.tum.in.www1.artemis.domain.Result)6