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

[backend/frontend] add exercise report #1419

Merged
merged 11 commits into from
Sep 20, 2024
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package io.openbas.migration;

import org.flywaydb.core.api.migration.BaseJavaMigration;
import org.flywaydb.core.api.migration.Context;
import org.springframework.stereotype.Component;

import java.sql.Connection;
import java.sql.Statement;

@Component
public class V3_40__Add_reports_tables extends BaseJavaMigration {
@Override
public void migrate(Context context) throws Exception {
Connection connection = context.getConnection();
Statement select = connection.createStatement();
select.execute("DROP TABLE IF EXISTS reports;");

// Create table
select.execute("""
CREATE TABLE reports (
report_id UUID NOT NULL CONSTRAINT reports_pkey PRIMARY KEY,
report_name VARCHAR(255) NOT NULL,
report_global_observation TEXT,
report_created_at TIMESTAMP DEFAULT now(),
report_updated_at TIMESTAMP DEFAULT now()
);
CREATE INDEX idx_reports ON reports(report_id);

CREATE TABLE reports_exercises (
report_id UUID NOT NULL,
exercise_id VARCHAR(255) NOT NULL,
PRIMARY KEY (report_id, exercise_id),
FOREIGN KEY (report_id) REFERENCES reports (report_id) ON DELETE CASCADE,
FOREIGN KEY (exercise_id) REFERENCES exercises (exercise_id) ON DELETE CASCADE
);
CREATE INDEX idx_reports_exercises_report ON reports_exercises (report_id);
CREATE INDEX idx_reports_exercises_exercise ON reports_exercises (exercise_id);

CREATE TABLE report_informations (
report_informations_id UUID NOT NULL CONSTRAINT report_informations_pkey PRIMARY KEY,
report_id UUID NOT NULL,
report_informations_type VARCHAR(255) NOT NULL,
report_informations_display BOOLEAN DEFAULT FALSE,
UNIQUE (report_id, report_informations_type),
FOREIGN KEY (report_id) REFERENCES reports (report_id) ON DELETE CASCADE
);
CREATE INDEX idx_report_informations ON report_informations (report_id);

CREATE TABLE report_inject_comment (
report_id UUID NOT NULL,
inject_id VARCHAR(255) NOT NULL,
comment TEXT,
PRIMARY KEY (report_id, inject_id),
FOREIGN KEY (report_id) REFERENCES reports (report_id) ON DELETE CASCADE,
FOREIGN KEY (inject_id) REFERENCES injects (inject_id) ON DELETE CASCADE
);
CREATE INDEX idx_report_inject_comment_inject ON report_inject_comment (report_id);
CREATE INDEX idx_report_inject_comment_report ON report_inject_comment (inject_id);
""");
}
}
59 changes: 28 additions & 31 deletions openbas-api/src/main/java/io/openbas/rest/report/ReportApi.java
Original file line number Diff line number Diff line change
@@ -1,69 +1,66 @@
package io.openbas.rest.report;

import io.openbas.database.model.Exercise;
import io.openbas.database.model.Report;
import io.openbas.database.repository.ExerciseRepository;
import io.openbas.database.repository.ReportRepository;
import io.openbas.database.specification.ReportSpecification;
import io.openbas.rest.exception.ElementNotFoundException;
import io.openbas.database.model.*;
import io.openbas.rest.exercise.ExerciseService;
import io.openbas.rest.helper.RestBehavior;
import io.openbas.rest.report.form.ReportCreateInput;
import io.openbas.rest.report.form.ReportUpdateInput;
import io.openbas.rest.report.form.ReportInput;
import io.openbas.service.ReportService;
import jakarta.transaction.Transactional;
import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.annotation.Secured;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import static java.time.Instant.now;
import java.util.UUID;

import static io.openbas.database.model.User.ROLE_USER;

@RequiredArgsConstructor
@RestController
@Secured(ROLE_USER)
public class ReportApi extends RestBehavior {

private ExerciseRepository exerciseRepository;
private ReportRepository reportRepository;

@Autowired
public void setExerciseRepository(ExerciseRepository exerciseRepository) {
this.exerciseRepository = exerciseRepository;
}
private final ExerciseService exerciseService;
private final ReportService reportService;

@Autowired
public void setReportRepository(ReportRepository reportRepository) {
this.reportRepository = reportRepository;
@GetMapping("/api/reports/{reportId}")
@PreAuthorize("isObserver()")
public Report report(@PathVariable String reportId) {
return this.reportService.report(UUID.fromString(reportId));

Check warning on line 30 in openbas-api/src/main/java/io/openbas/rest/report/ReportApi.java

View check run for this annotation

Codecov / codecov/patch

openbas-api/src/main/java/io/openbas/rest/report/ReportApi.java#L30

Added line #L30 was not covered by tests
}

@GetMapping("/api/exercises/{exerciseId}/reports")
@PreAuthorize("isExerciseObserver(#exerciseId)")
public Iterable<Report> exerciseReports(@PathVariable String exerciseId) {
return reportRepository.findAll(ReportSpecification.fromExercise(exerciseId));
return this.reportService.reportsFromExercise(exerciseId);
}

@PostMapping("/api/exercises/{exerciseId}/reports")
@PreAuthorize("isExercisePlanner(#exerciseId)")
@Transactional(rollbackOn = Exception.class)
public Report createExerciseReport(@PathVariable String exerciseId, @Valid @RequestBody ReportCreateInput input) {
Exercise exercise = exerciseRepository.findById(exerciseId).orElseThrow(ElementNotFoundException::new);
public Report createExerciseReport(@PathVariable String exerciseId, @Valid @RequestBody ReportInput input) {
Exercise exercise = this.exerciseService.exercise(exerciseId);
Report report = new Report();
report.setUpdateAttributes(input);
report.setExercise(exercise);
return reportRepository.save(report);
return this.reportService.updateReport(report, input);
}

@PutMapping("/api/exercises/{exerciseId}/reports/{reportId}")
@PreAuthorize("isExercisePlanner(#exerciseId)")
@Transactional(rollbackOn = Exception.class)
public Report updateExerciseReport(@PathVariable String exerciseId,@PathVariable String reportId, @Valid @RequestBody ReportUpdateInput input) {
Report report = reportRepository.findById(reportId).orElseThrow(ElementNotFoundException::new);
report.setUpdateAttributes(input);
report.setUpdated(now());
return reportRepository.save(report);
public Report updateExerciseReport(@PathVariable String exerciseId,@PathVariable String reportId, @Valid @RequestBody ReportInput input) {
Report report = this.reportService.report(UUID.fromString(reportId));
assert exerciseId.equals(report.getExercise().getId());
return this.reportService.updateReport(report, input);
}

@DeleteMapping("/api/exercises/{exerciseId}/reports/{reportId}")
@PreAuthorize("isExercisePlanner(#exerciseId)")
@Transactional(rollbackOn = Exception.class)
public void deleteExerciseReport(@PathVariable String exerciseId, @PathVariable String reportId) {
reportRepository.deleteById(reportId);
Report report = this.reportService.report(UUID.fromString(reportId));
assert exerciseId.equals(report.getExercise().getId());
this.reportService.deleteReport(UUID.fromString(reportId));
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package io.openbas.rest.report.form;

import com.fasterxml.jackson.annotation.JsonProperty;
import io.openbas.database.model.ReportInformationsType;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;

@Data
public class ReportInformationInput {
@JsonProperty("report_informations_type")
@NotBlank
private ReportInformationsType reportInformationsType;

@JsonProperty("report_informations_display")
@NotNull
private Boolean reportInformationsDisplay;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package io.openbas.rest.report.form;

import com.fasterxml.jackson.annotation.JsonProperty;

import jakarta.validation.constraints.NotBlank;
import lombok.Data;

import java.util.List;

import static io.openbas.config.AppConfig.MANDATORY_MESSAGE;

@Data
public class ReportInput {
@NotBlank(message = MANDATORY_MESSAGE)
@JsonProperty("report_name")
private String name;

@JsonProperty("report_informations")
private List<ReportInformationInput> reportInformations;
}
Loading