From b0977b84bcfcbe49c8146dcaa377a47e10d80414 Mon Sep 17 00:00:00 2001 From: Romuald Lemesle Date: Tue, 9 Jan 2024 10:14:21 +0100 Subject: [PATCH] [backend] Migration to Spring Boot v3 (#467) --- .circleci/config.yml | 30 +- .drone.yml | 4 +- .github/workflows/codeql.yml | 2 +- Dockerfile | 4 +- Dockerfile_circleci | 4 +- openex-api/pom.xml | 26 +- .../main/java/io/openex/config/AppConfig.java | 6 +- .../io/openex/config/AppSecurityConfig.java | 86 +- .../main/java/io/openex/config/MvcConfig.java | 3 +- .../java/io/openex/config/SessionManager.java | 8 +- .../java/io/openex/helper/InjectHelper.java | 7 +- .../io/openex/importer/V1_DataImporter.java | 8 +- .../injects/challenge/ChallengeExecutor.java | 4 +- .../injects/channel/ChannelExecutor.java | 4 +- .../openex/injects/email/EmailExecutor.java | 4 +- .../injects/email/service/EmailService.java | 10 +- .../injects/email/service/ImapService.java | 10 +- .../openex/injects/manual/ManualExecutor.java | 2 +- .../migration/V2_67__Variables_Enum.java | 37 + .../rest/attack_pattern/AttackPatternApi.java | 10 +- .../form/AttackPatternCreateInput.java | 4 +- .../io/openex/rest/audience/AudienceApi.java | 0 .../openex/rest/challenge/ChallengeApi.java | 10 +- .../challenge/form/ChallengeCreateInput.java | 4 +- .../challenge/form/ChallengeUpdateInput.java | 4 +- .../openex/rest/challenge/form/FlagInput.java | 2 +- .../io/openex/rest/channel/ChannelApi.java | 16 +- .../rest/channel/form/ArticleCreateInput.java | 2 +- .../rest/channel/form/ArticleUpdateInput.java | 2 +- .../rest/channel/form/ChannelCreateInput.java | 2 +- .../rest/channel/form/ChannelUpdateInput.java | 2 +- .../io/openex/rest/comcheck/ComcheckApi.java | 4 +- .../rest/comcheck/form/ComcheckInput.java | 2 +- .../io/openex/rest/document/DocumentApi.java | 6 +- .../document/form/DocumentUpdateInput.java | 2 +- .../io/openex/rest/exercise/ExerciseApi.java | 1321 +++++++++-------- .../rest/exercise/ExerciseExpectationApi.java | 4 +- .../exports/VariableWithValueMixin.java | 2 +- .../rest/exercise/form/DryrunCreateInput.java | 2 +- .../exercise/form/ExerciseCreateInput.java | 4 +- .../rest/exercise/form/ExerciseSimple.java | 4 +- .../form/ExerciseTeamPlayersEnableInput.java | 3 - .../exercise/form/ExerciseUpdateInput.java | 4 +- .../form/ExerciseUpdateStartDateInput.java | 2 +- .../exercise/form/ExpectationUpdateInput.java | 2 +- .../java/io/openex/rest/group/GroupApi.java | 24 +- .../rest/group/form/GroupCreateInput.java | 2 +- .../rest/group/form/GroupGrantInput.java | 2 +- .../group/form/OrganizationGrantInput.java | 2 +- .../io/openex/rest/helper/RestBehavior.java | 2 +- .../java/io/openex/rest/inject/InjectApi.java | 6 +- .../kill_chain_phase/KillChainPhaseApi.java | 10 +- .../form/KillChainPhaseCreateInput.java | 4 +- .../io/openex/rest/lessons/LessonsApi.java | 2 +- .../form/LessonsCategoryCreateInput.java | 2 +- .../form/LessonsCategoryUpdateInput.java | 2 +- .../form/LessonsQuestionCreateInput.java | 4 +- .../form/LessonsQuestionUpdateInput.java | 2 +- .../lessons_template/LessonsTemplateApi.java | 23 +- .../LessonsTemplateCategoryCreateInput.java | 2 +- .../LessonsTemplateCategoryUpdateInput.java | 2 +- .../form/LessonsTemplateCreateInput.java | 2 +- .../LessonsTemplateQuestionCreateInput.java | 2 +- .../LessonsTemplateQuestionUpdateInput.java | 2 +- .../form/LessonsTemplateUpdateInput.java | 2 +- .../openex/rest/objective/ObjectiveApi.java | 4 +- .../rest/organization/OrganizationApi.java | 10 +- .../form/OrganizationCreateInput.java | 2 +- .../form/OrganizationUpdateInput.java | 2 +- .../java/io/openex/rest/report/ReportApi.java | 2 +- .../rest/report/form/ReportCreateInput.java | 4 +- .../rest/report/form/ReportUpdateInput.java | 4 +- .../rest/security/MethodSecurityConfig.java | 33 +- .../rest/security/SecurityExpression.java | 2 +- .../security/SecurityExpressionHandler.java | 43 +- .../io/openex/rest/settings/SettingsApi.java | 8 +- .../settings/form/SettingsUpdateInput.java | 2 +- .../main/java/io/openex/rest/tag/TagApi.java | 11 +- .../openex/rest/tag/form/TagCreateInput.java | 2 +- .../openex/rest/tag/form/TagUpdateInput.java | 2 +- .../java/io/openex/rest/team/TeamApi.java | 16 +- .../rest/team/form/TeamCreateInput.java | 3 +- .../rest/team/form/TeamUpdateInput.java | 2 +- .../main/java/io/openex/rest/user/MeApi.java | 22 +- .../java/io/openex/rest/user/PlayerApi.java | 6 +- .../java/io/openex/rest/user/UserApi.java | 18 +- .../rest/user/form/login/LoginUserInput.java | 2 +- .../rest/user/form/login/ResetUserInput.java | 2 +- .../user/form/me/UpdateMePasswordInput.java | 2 +- .../rest/user/form/me/UpdateProfileInput.java | 4 +- .../user/form/player/CreatePlayerInput.java | 4 +- .../user/form/player/UpdatePlayerInput.java | 2 +- .../user/form/user/ChangePasswordInput.java | 2 +- .../rest/user/form/user/CreateUserInput.java | 4 +- .../rest/user/form/user/RenewTokenInput.java | 2 +- .../user/form/user/UpdatePasswordInput.java | 2 +- .../rest/user/form/user/UpdateUserInput.java | 2 +- .../io/openex/rest/variable/VariableApi.java | 9 +- .../rest/variable/form/VariableInput.java | 4 +- .../runner/InitAdminCommandLineRunner.java | 4 +- .../scheduler/jobs/ComchecksExecutionJob.java | 8 +- ...soRefererAuthenticationFailureHandler.java | 6 +- ...soRefererAuthenticationSuccessHandler.java | 6 +- .../security/TokenAuthenticationFilter.java | 12 +- .../io/openex/service/ChallengeService.java | 2 +- .../java/io/openex/service/DryrunService.java | 4 +- .../service/ExerciseExpectationService.java | 4 +- .../java/io/openex/service/ImportService.java | 4 +- .../io/openex/service/MailingService.java | 4 +- .../java/io/openex/service/UserService.java | 4 +- .../io/openex/service/VariableService.java | 4 +- .../commons/mail/util/MimeMessageParser.java | 455 ++++++ .../src/main/resources/application.properties | 4 +- .../io/openex/injects/InjectCrudTest.java | 4 +- .../injects/email/EmailExecutorTest.java | 2 +- .../src/test/resources/application.properties | 2 +- openex-collectors | 2 +- openex-dev/docker-compose.yml | 4 +- .../java/io/openex/contract/Contract.java | 6 +- .../io/openex/contract/ContractVariable.java | 4 +- .../contract/fields/ContractExpectations.java | 6 +- .../java/io/openex/execution/Injector.java | 2 +- .../java/io/openex/execution/ProtectUser.java | 2 +- .../model/expectation/ManualExpectation.java | 2 +- .../service/ExecutionContextService.java | 6 +- openex-injectors | 2 +- openex-model/pom.xml | 12 +- .../java/io/openex/config/MinioConfig.java | 2 +- .../database/audit/ModelBaseListener.java | 8 +- .../database/converter/ContentConverter.java | 8 +- .../converter/ExecutionConverter.java | 8 +- .../converter/PostgreSqlStringArrayType.java | 119 +- .../io/openex/database/model/Article.java | 7 +- .../openex/database/model/AttackPattern.java | 17 +- .../java/io/openex/database/model/Base.java | 2 +- .../io/openex/database/model/Challenge.java | 6 +- .../openex/database/model/ChallengeFlag.java | 6 +- .../io/openex/database/model/Channel.java | 6 +- .../io/openex/database/model/Comcheck.java | 6 +- .../openex/database/model/ComcheckStatus.java | 6 +- .../openex/database/model/Communication.java | 8 +- .../io/openex/database/model/Document.java | 6 +- .../io/openex/database/model/DryInject.java | 8 +- .../database/model/DryInjectStatus.java | 6 +- .../java/io/openex/database/model/Dryrun.java | 6 +- .../io/openex/database/model/Evaluation.java | 6 +- .../io/openex/database/model/Exercise.java | 8 +- .../database/model/ExerciseTeamUser.java | 2 +- .../database/model/ExerciseTeamUserId.java | 3 +- .../java/io/openex/database/model/Grant.java | 6 +- .../java/io/openex/database/model/Group.java | 6 +- .../java/io/openex/database/model/Inject.java | 602 ++++---- .../openex/database/model/InjectDocument.java | 2 +- .../database/model/InjectDocumentId.java | 2 +- .../database/model/InjectExpectation.java | 8 +- .../openex/database/model/InjectStatus.java | 6 +- .../openex/database/model/KillChainPhase.java | 7 +- .../openex/database/model/LessonsAnswer.java | 6 +- .../database/model/LessonsCategory.java | 6 +- .../database/model/LessonsQuestion.java | 6 +- .../database/model/LessonsTemplate.java | 6 +- .../model/LessonsTemplateCategory.java | 6 +- .../model/LessonsTemplateQuestion.java | 6 +- .../java/io/openex/database/model/Log.java | 6 +- .../io/openex/database/model/Objective.java | 6 +- .../openex/database/model/Organization.java | 6 +- .../java/io/openex/database/model/Pause.java | 6 +- .../java/io/openex/database/model/Report.java | 6 +- .../io/openex/database/model/Setting.java | 6 +- .../java/io/openex/database/model/Tag.java | 6 +- .../java/io/openex/database/model/Team.java | 9 +- .../java/io/openex/database/model/Token.java | 6 +- .../java/io/openex/database/model/User.java | 10 +- .../io/openex/database/model/Variable.java | 13 +- .../repository/ArticleRepository.java | 2 +- .../repository/AttackPatternRepository.java | 2 +- .../repository/AudienceRepository.java | 0 .../repository/ChallengeFlagRepository.java | 2 +- .../repository/ChallengeRepository.java | 2 +- .../repository/ChannelRepository.java | 2 +- .../repository/ComcheckRepository.java | 2 +- .../repository/ComcheckStatusRepository.java | 2 +- .../repository/CommunicationRepository.java | 2 +- .../repository/DocumentRepository.java | 2 +- .../DryInjectReportingRepository.java | 2 +- .../repository/DryInjectRepository.java | 2 +- .../database/repository/DryRunRepository.java | 2 +- .../repository/EvaluationRepository.java | 2 +- .../repository/ExerciseRepository.java | 2 +- .../ExerciseTeamUserRepository.java | 4 +- .../database/repository/GrantRepository.java | 2 +- .../database/repository/GroupRepository.java | 2 +- .../repository/InjectDocumentRepository.java | 2 +- .../InjectExpectationRepository.java | 4 +- .../repository/InjectReportingRepository.java | 2 +- .../database/repository/InjectRepository.java | 2 +- .../repository/InjectStatusRepository.java | 2 +- .../repository/KillChainPhaseRepository.java | 2 +- .../repository/LessonsAnswerRepository.java | 2 +- .../repository/LessonsCategoryRepository.java | 2 +- .../repository/LessonsQuestionRepository.java | 2 +- .../LessonsTemplateCategoryRepository.java | 2 +- .../LessonsTemplateQuestionRepository.java | 2 +- .../repository/LessonsTemplateRepository.java | 2 +- .../database/repository/LogRepository.java | 2 +- .../repository/ObjectiveRepository.java | 2 +- .../repository/OrganizationRepository.java | 2 +- .../database/repository/PauseRepository.java | 2 +- .../database/repository/ReportRepository.java | 2 +- .../repository/SettingRepository.java | 2 +- .../database/repository/TagRepository.java | 2 +- .../database/repository/TeamRepository.java | 5 +- .../database/repository/TokenRepository.java | 5 +- .../database/repository/UserRepository.java | 2 +- .../specification/DryInjectSpecification.java | 2 +- .../specification/InjectSpecification.java | 5 +- pom.xml | 16 +- 217 files changed, 2108 insertions(+), 1606 deletions(-) create mode 100644 openex-api/src/main/java/io/openex/migration/V2_67__Variables_Enum.java create mode 100644 openex-api/src/main/java/io/openex/rest/audience/AudienceApi.java create mode 100644 openex-api/src/main/java/org/apache/commons/mail/util/MimeMessageParser.java create mode 100644 openex-model/src/main/java/io/openex/database/repository/AudienceRepository.java diff --git a/.circleci/config.yml b/.circleci/config.yml index d69ceb8c76..dc94c13c28 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -17,14 +17,14 @@ jobs: command: | git submodule sync git submodule update --init --recursive --jobs 8 - - run: + - run: working_directory: ~/openex/openex-front command: yarn install - run: working_directory: ~/openex/openex-front command: NODE_OPTIONS=--max-old-space-size=8096 yarn build no_output_timeout: 30m - - run: + - run: working_directory: ~/ command: cp -a openex openex_docker && cp -a openex openex_musl - slack/notify: @@ -39,15 +39,15 @@ jobs: - openex - openex_docker - openex_musl - + build_platform: working_directory: ~/openex docker: - - image: maven:3.8.7-openjdk-18 + - image: maven:3.9.6-eclipse-temurin-21 steps: - attach_workspace: at: ~/ - - run: + - run: working_directory: ~/openex command: mvn install -DskipTests -Pdev - slack/notify: @@ -64,12 +64,12 @@ jobs: build_platform_musl: working_directory: ~/openex_musl docker: - - image: maven:3.8.6-eclipse-temurin-18-alpine + - image: maven:3.9.6-eclipse-temurin-21-alpine resource_class: large steps: - attach_workspace: at: ~/ - - run: + - run: working_directory: ~/openex_musl command: mvn install -DskipTests -Pdev - slack/notify: @@ -86,7 +86,7 @@ jobs: package_rolling: working_directory: ~/openex docker: - - image: maven:3.8.7-openjdk-18 + - image: maven:3.9.6-eclipse-temurin-21 steps: - attach_workspace: at: ~/ @@ -108,7 +108,7 @@ jobs: package_rolling_musl: working_directory: ~/openex_musl docker: - - image: maven:3.8.7-openjdk-18 + - image: maven:3.9.6-eclipse-temurin-21 steps: - attach_workspace: at: ~/ @@ -214,12 +214,12 @@ jobs: - ms-teams/report: only_on_fail: true webhook_url: $MS_TEAMS_WEBHOOK_URL - + notify_rolling: docker: - image: "cimg/base:stable" steps: - - run: sudo apt-get update -qq && sudo apt install curl + - run: sudo apt-get update -qq && sudo apt install curl - slack/notify: event: pass template: basic_success_1 @@ -230,13 +230,13 @@ jobs: docker: - image: "cimg/base:stable" steps: - - run: sudo apt-get update -qq && sudo apt install curl + - run: sudo apt-get update -qq && sudo apt install curl - slack/notify: event: pass template: basic_success_1 - ms-teams/report: only_on_fail: false - webhook_url: $MS_TEAMS_WEBHOOK_URL + webhook_url: $MS_TEAMS_WEBHOOK_URL workflows: openex: @@ -290,7 +290,7 @@ workflows: ignore: /.*/ - deploy_testing: requires: - - docker_build_platform_rolling + - docker_build_platform_rolling - notify_rolling: requires: - deploy_testing @@ -303,4 +303,4 @@ workflows: tags: only: /[0-9]+(\.[0-9]+)+(\.[0-9]+)*/ branches: - ignore: /.*/ \ No newline at end of file + ignore: /.*/ diff --git a/.drone.yml b/.drone.yml index 301cfe4ab1..8f0468bfef 100644 --- a/.drone.yml +++ b/.drone.yml @@ -15,7 +15,7 @@ steps: commands: - git submodule update --init --recursive - name: api-tests - image: maven:3.8.7-openjdk-18 + image: maven:3.9.6-eclipse-temurin-21 environment: SPRING_DATASOURCE_URL: jdbc:postgresql://pgsql:5432/openex MINIO_ENDPOINT: minio @@ -66,7 +66,7 @@ steps: commands: - git submodule update --init --recursive - name: api-tests - image: maven:3.8.7-openjdk-18 + image: maven:3.9.6-eclipse-temurin-21 environment: SPRING_DATASOURCE_URL: jdbc:postgresql://pgsql:5432/openex MINIO_ENDPOINT: minio diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 9cd98baf92..c6fdd11bf2 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -51,7 +51,7 @@ jobs: uses: actions/setup-java@v4 with: distribution: 'zulu' - java-version: 18 + java-version: 21 if: matrix.language == 'java-kotlin' # Initializes the CodeQL tools for scanning. diff --git a/Dockerfile b/Dockerfile index 760c637e22..e5816c2394 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,7 +8,7 @@ RUN yarn install COPY openex-front /opt/openex-build/openex-front RUN yarn build -FROM maven:3.8.7-openjdk-18 AS api-builder +FROM maven:3.9.6-eclipse-temurin-21 AS api-builder WORKDIR /opt/openex-build/openex COPY openex-model ./openex-model @@ -20,7 +20,7 @@ COPY pom.xml ./pom.xml COPY --from=front-builder /opt/openex-build/openex-front/builder/prod/build ./openex-front/builder/prod/build RUN mvn install -DskipTests -Pdev -FROM openjdk:18-slim AS app +FROM eclipse-temurin:21-jre AS app RUN DEBIAN_FRONTEND=noninteractive apt-get update -q && DEBIAN_FRONTEND=noninteractive apt-get install -qq -y tini; COPY --from=api-builder /opt/openex-build/openex/openex-api/target/openex-api.jar ./ diff --git a/Dockerfile_circleci b/Dockerfile_circleci index eab4fb9bb8..8480179a80 100644 --- a/Dockerfile_circleci +++ b/Dockerfile_circleci @@ -1,4 +1,4 @@ -FROM maven:3.8.7-openjdk-18 AS api-builder +FROM maven:3.9.6-eclipse-temurin-21 AS api-builder WORKDIR /opt/openex-build/openex COPY openex-model ./openex-model @@ -10,7 +10,7 @@ COPY openex-front/builder/prod/build ./openex-front/builder/prod/build COPY pom.xml ./pom.xml RUN mvn install -DskipTests -Pdev -FROM openjdk:18-slim AS app +FROM eclipse-temurin:21-jre AS app RUN ln -s /usr/bin/dpkg-split /usr/sbin/dpkg-split RUN ln -s /usr/bin/dpkg-deb /usr/sbin/dpkg-deb diff --git a/openex-api/pom.xml b/openex-api/pom.xml index 3ad23c193d..610699b4f3 100644 --- a/openex-api/pom.xml +++ b/openex-api/pom.xml @@ -15,7 +15,6 @@ 1.70 - 1.16.0 4.4 1.5 1.7 @@ -124,7 +123,6 @@ commons-io commons-io - ${commons-io.version} @@ -133,9 +131,8 @@ ${commons-validator.version} - javax.validation - validation-api - ${validation-api.version} + jakarta.validation + jakarta.validation-api org.postgresql @@ -144,24 +141,22 @@ com.fasterxml.jackson.datatype - jackson-datatype-hibernate5 - ${jackson.version} + jackson-datatype-hibernate6 com.fasterxml.jackson.datatype jackson-datatype-jdk8 - ${jackson.version} com.fasterxml.jackson.datatype jackson-datatype-jsr310 - ${jackson.version} - - - org.apache.commons - commons-email - ${commons-email.version} + + + + + + org.apache.commons commons-collections4 @@ -170,13 +165,10 @@ org.flywaydb flyway-core - ${flyway.version} commons-codec commons-codec - - ${commons-codec.version} org.springframework.security diff --git a/openex-api/src/main/java/io/openex/config/AppConfig.java b/openex-api/src/main/java/io/openex/config/AppConfig.java index 70803092f0..458185ddbe 100644 --- a/openex-api/src/main/java/io/openex/config/AppConfig.java +++ b/openex-api/src/main/java/io/openex/config/AppConfig.java @@ -3,7 +3,7 @@ import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.util.StdDateFormat; -import com.fasterxml.jackson.datatype.hibernate5.Hibernate5Module; +import com.fasterxml.jackson.datatype.hibernate6.Hibernate6Module; import com.fasterxml.jackson.datatype.jdk8.Jdk8Module; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import io.swagger.v3.oas.models.ExternalDocumentation; @@ -16,7 +16,7 @@ import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.EnableTransactionManagement; -import javax.annotation.Resource; +import jakarta.annotation.Resource; @Component @EnableAsync @@ -39,7 +39,7 @@ ObjectMapper openexJsonMapper() { ObjectMapper mapper = new ObjectMapper(); mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); mapper.setDateFormat(new StdDateFormat().withColonInTimeZone(true)); - mapper.registerModule(new Hibernate5Module()); + mapper.registerModule(new Hibernate6Module()); mapper.registerModule(new Jdk8Module()); mapper.registerModule(new JavaTimeModule()); return mapper; diff --git a/openex-api/src/main/java/io/openex/config/AppSecurityConfig.java b/openex-api/src/main/java/io/openex/config/AppSecurityConfig.java index c5b052b4a7..ef35a2a909 100644 --- a/openex-api/src/main/java/io/openex/config/AppSecurityConfig.java +++ b/openex-api/src/main/java/io/openex/config/AppSecurityConfig.java @@ -11,14 +11,17 @@ import io.openex.security.SsoRefererAuthenticationSuccessHandler; import io.openex.security.TokenAuthenticationFilter; import io.openex.service.UserService; +import jakarta.annotation.Resource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; import org.springframework.core.env.Environment; import org.springframework.http.HttpStatus; import org.springframework.security.authentication.ProviderManager; +import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserRequest; import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserService; @@ -38,14 +41,13 @@ import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationException; import org.springframework.security.saml2.provider.service.metadata.OpenSamlMetadataResolver; import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository; -import org.springframework.security.saml2.provider.service.servlet.filter.Saml2WebSsoAuthenticationFilter; import org.springframework.security.saml2.provider.service.web.DefaultRelyingPartyRegistrationResolver; -import org.springframework.security.saml2.provider.service.web.RelyingPartyRegistrationResolver; import org.springframework.security.saml2.provider.service.web.Saml2MetadataFilter; +import org.springframework.security.saml2.provider.service.web.authentication.Saml2WebSsoAuthenticationFilter; +import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.security.web.savedrequest.HttpSessionRequestCache; -import javax.annotation.Resource; import java.io.IOException; import java.util.ArrayList; import java.util.Base64; @@ -61,8 +63,9 @@ import static org.apache.commons.lang3.StringUtils.isBlank; import static org.springframework.util.StringUtils.hasLength; +@Configuration @EnableWebSecurity -public class AppSecurityConfig extends WebSecurityConfigurerAdapter { +public class AppSecurityConfig { private static final Logger LOGGER = Logger.getLogger(AppSecurityConfig.class.getName()); @@ -97,54 +100,59 @@ public void setUserRepository(UserRepository userRepository) { @Autowired(required = false) private RelyingPartyRegistrationRepository relyingPartyRegistrationRepository; - @Override - protected void configure(HttpSecurity http) throws Exception { + @Bean + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.addFilterBefore(tokenAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class) - .requestCache() - /**/.requestCache(new HttpSessionRequestCache()) - .and() - .csrf() - /**/.disable() - .formLogin() - /**/.disable() - .authorizeRequests() - /**/.antMatchers("/api/comcheck/**").permitAll() - /**/.antMatchers("/api/player/**").permitAll() - /**/.antMatchers("/api/settings").permitAll() - /**/.antMatchers("/api/login").permitAll() - /**/.antMatchers("/api/reset/**").permitAll() - /**/.antMatchers("/api/**").authenticated() - .and() - .logout() - /**/.invalidateHttpSession(true) - /**/.deleteCookies("JSESSIONID", openExConfig.getCookieName()) - /**/.logoutSuccessUrl(env.getProperty("openex.logout-success-url", String.class, "/")); + .requestCache(Customizer.withDefaults()) + /**/.requestCache((cache) -> cache.requestCache(new HttpSessionRequestCache())) + .csrf(AbstractHttpConfigurer::disable) + .formLogin(AbstractHttpConfigurer::disable) + .securityContext((securityContext) -> securityContext.requireExplicitSave(false)) + .authorizeHttpRequests( + rq -> rq.requestMatchers("/api/comcheck/**").permitAll() + .requestMatchers("/api/player/**").permitAll() + .requestMatchers("/api/settings").permitAll() + .requestMatchers("/api/login").permitAll() + .requestMatchers("/api/reset/**").permitAll() + .requestMatchers("/api/**").authenticated() + ) + .logout( + logout -> logout.invalidateHttpSession(true) + .deleteCookies("JSESSIONID", openExConfig.getCookieName()) + .logoutSuccessUrl(env.getProperty("openex.logout-success-url", String.class, "/")) + ); if (openExConfig.isAuthOpenidEnable()) { - http.oauth2Login() - .successHandler(new SsoRefererAuthenticationSuccessHandler()) - .failureHandler(new SsoRefererAuthenticationFailureHandler()); + http.oauth2Login( + login -> login.successHandler(new SsoRefererAuthenticationSuccessHandler()) + .failureHandler(new SsoRefererAuthenticationFailureHandler()) + ); } if (openExConfig.isAuthSaml2Enable()) { DefaultRelyingPartyRegistrationResolver relyingPartyRegistrationResolver = new DefaultRelyingPartyRegistrationResolver( this.relyingPartyRegistrationRepository); Saml2MetadataFilter filter = new Saml2MetadataFilter( - (RelyingPartyRegistrationResolver) relyingPartyRegistrationResolver, + relyingPartyRegistrationResolver, new OpenSamlMetadataResolver()); OpenSaml4AuthenticationProvider authenticationProvider = getOpenSaml4AuthenticationProvider(); - http - .addFilterBefore(filter, Saml2WebSsoAuthenticationFilter.class) - .saml2Login() - .authenticationManager(new ProviderManager(authenticationProvider)) - .successHandler(new SsoRefererAuthenticationSuccessHandler()); + http.addFilterBefore(filter, Saml2WebSsoAuthenticationFilter.class) + .saml2Login( + saml2Login -> saml2Login + .authenticationManager(new ProviderManager(authenticationProvider)) + .successHandler(new SsoRefererAuthenticationSuccessHandler()) + ); } // Rewrite 403 code to 401 - http.exceptionHandling().authenticationEntryPoint( - (request, response, authException) -> response.setStatus(HttpStatus.UNAUTHORIZED.value())); + http.exceptionHandling( + exceptionHandling -> exceptionHandling.authenticationEntryPoint( + (request, response, authException) -> response.setStatus(HttpStatus.UNAUTHORIZED.value())) + ); + + return http.build(); } @Bean @@ -157,6 +165,7 @@ private List extractRolesFromToken(OAuth2AccessToken accessToken, String }); if (accessToken != null) { String rolesPathConfig = "openex.provider." + registrationId + ".roles_path"; + //noinspection unchecked List rolesPath = env.getProperty(rolesPathConfig, List.class, new ArrayList()); try { String[] chunks = accessToken.getTokenValue().split("\\."); @@ -182,12 +191,14 @@ private List extractRolesFromToken(OAuth2AccessToken accessToken, String private List extractRolesFromUser(Saml2AuthenticatedPrincipal user, String registrationId) { String rolesPathConfig = "openex.provider." + registrationId + ".roles_path"; + //noinspection unchecked List rolesPath = env.getProperty(rolesPathConfig, List.class, new ArrayList()); try { return rolesPath.stream() .flatMap(path -> { try { List roles = user.getAttribute(path); + assert roles != null; return roles.stream(); } catch (NullPointerException e) { return Stream.empty(); @@ -207,6 +218,7 @@ public User userManagement( String lastName) { String email = ofNullable(emailAttribute).orElseThrow(); String rolesAdminConfig = "openex.provider." + registrationId + ".roles_admin"; + //noinspection unchecked List rolesAdmin = this.env.getProperty(rolesAdminConfig, List.class, new ArrayList()); boolean isAdmin = rolesAdmin.stream().anyMatch(rolesFromToken::contains); if (hasLength(email)) { diff --git a/openex-api/src/main/java/io/openex/config/MvcConfig.java b/openex-api/src/main/java/io/openex/config/MvcConfig.java index baee2ca09a..6a8b4fdc8e 100644 --- a/openex-api/src/main/java/io/openex/config/MvcConfig.java +++ b/openex-api/src/main/java/io/openex/config/MvcConfig.java @@ -1,6 +1,7 @@ package io.openex.config; import com.fasterxml.jackson.databind.ObjectMapper; +import jakarta.annotation.Resource; import org.jetbrains.annotations.NotNull; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -21,7 +22,7 @@ public class MvcConfig implements WebMvcConfigurer { private final static int CACHE_PERIOD = 3600; - @javax.annotation.Resource + @Resource private ObjectMapper objectMapper; @Bean diff --git a/openex-api/src/main/java/io/openex/config/SessionManager.java b/openex-api/src/main/java/io/openex/config/SessionManager.java index d5dd721e5a..5c28e98be0 100644 --- a/openex-api/src/main/java/io/openex/config/SessionManager.java +++ b/openex-api/src/main/java/io/openex/config/SessionManager.java @@ -9,9 +9,9 @@ import org.springframework.security.oauth2.core.user.OAuth2User; import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken; -import javax.servlet.http.HttpSession; -import javax.servlet.http.HttpSessionEvent; -import javax.servlet.http.HttpSessionListener; +import jakarta.servlet.http.HttpSession; +import jakarta.servlet.http.HttpSessionEvent; +import jakarta.servlet.http.HttpSessionListener; import java.util.HashMap; import java.util.Map; import java.util.Optional; @@ -104,4 +104,4 @@ public void refreshUserSessions(User databaseUser) { public void invalidateUserSession(String userId) { getUserSessions(userId).forEach(HttpSession::invalidate); } -} \ No newline at end of file +} diff --git a/openex-api/src/main/java/io/openex/helper/InjectHelper.java b/openex-api/src/main/java/io/openex/helper/InjectHelper.java index e29eb4ed5a..88dcbe5cba 100644 --- a/openex-api/src/main/java/io/openex/helper/InjectHelper.java +++ b/openex-api/src/main/java/io/openex/helper/InjectHelper.java @@ -2,29 +2,28 @@ import io.openex.contract.Contract; import io.openex.database.model.*; -import io.openex.database.repository.TeamRepository; import io.openex.database.repository.DryInjectRepository; import io.openex.database.repository.InjectRepository; +import io.openex.database.repository.TeamRepository; import io.openex.database.specification.DryInjectSpecification; import io.openex.database.specification.InjectSpecification; import io.openex.execution.ExecutableInject; import io.openex.execution.ExecutionContext; import io.openex.service.ContractService; import io.openex.service.ExecutionContextService; +import jakarta.transaction.Transactional; +import jakarta.validation.constraints.NotNull; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import reactor.util.function.Tuple2; import reactor.util.function.Tuples; -import javax.transaction.Transactional; -import javax.validation.constraints.NotNull; import java.time.Instant; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; -import static io.openex.helper.StreamHelper.fromIterable; import static java.util.stream.Collectors.groupingBy; import static java.util.stream.Stream.concat; diff --git a/openex-api/src/main/java/io/openex/importer/V1_DataImporter.java b/openex-api/src/main/java/io/openex/importer/V1_DataImporter.java index 3216209b4c..698f5fc41c 100644 --- a/openex-api/src/main/java/io/openex/importer/V1_DataImporter.java +++ b/openex-api/src/main/java/io/openex/importer/V1_DataImporter.java @@ -16,9 +16,9 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import javax.activation.MimetypesFileTypeMap; -import javax.annotation.Resource; -import javax.validation.constraints.NotNull; +import jakarta.activation.MimetypesFileTypeMap; +import jakarta.annotation.Resource; +import jakarta.validation.constraints.NotNull; import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; @@ -238,7 +238,7 @@ private void importInjects(Map baseIds, Exercise exercise, List 0) { + if (!childInjects.isEmpty()) { importInjects(baseIds, exercise, childInjects); } } diff --git a/openex-api/src/main/java/io/openex/injects/challenge/ChallengeExecutor.java b/openex-api/src/main/java/io/openex/injects/challenge/ChallengeExecutor.java index 8a18a6dba3..a5ba0e4d2d 100644 --- a/openex-api/src/main/java/io/openex/injects/challenge/ChallengeExecutor.java +++ b/openex-api/src/main/java/io/openex/injects/challenge/ChallengeExecutor.java @@ -16,8 +16,8 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; -import javax.annotation.Resource; -import javax.validation.constraints.NotNull; +import jakarta.annotation.Resource; +import jakarta.validation.constraints.NotNull; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; diff --git a/openex-api/src/main/java/io/openex/injects/channel/ChannelExecutor.java b/openex-api/src/main/java/io/openex/injects/channel/ChannelExecutor.java index d6712b944f..634cb74b7a 100644 --- a/openex-api/src/main/java/io/openex/injects/channel/ChannelExecutor.java +++ b/openex-api/src/main/java/io/openex/injects/channel/ChannelExecutor.java @@ -17,8 +17,8 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; -import javax.annotation.Resource; -import javax.validation.constraints.NotNull; +import jakarta.annotation.Resource; +import jakarta.validation.constraints.NotNull; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; diff --git a/openex-api/src/main/java/io/openex/injects/email/EmailExecutor.java b/openex-api/src/main/java/io/openex/injects/email/EmailExecutor.java index 548c288da8..4398612053 100644 --- a/openex-api/src/main/java/io/openex/injects/email/EmailExecutor.java +++ b/openex-api/src/main/java/io/openex/injects/email/EmailExecutor.java @@ -14,8 +14,8 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; -import javax.annotation.Resource; -import javax.validation.constraints.NotNull; +import jakarta.annotation.Resource; +import jakarta.validation.constraints.NotNull; import java.util.List; import java.util.stream.Stream; diff --git a/openex-api/src/main/java/io/openex/injects/email/service/EmailService.java b/openex-api/src/main/java/io/openex/injects/email/service/EmailService.java index 5c33b5869d..0babc370d6 100644 --- a/openex-api/src/main/java/io/openex/injects/email/service/EmailService.java +++ b/openex-api/src/main/java/io/openex/injects/email/service/EmailService.java @@ -9,11 +9,11 @@ import org.springframework.mail.javamail.JavaMailSender; import org.springframework.stereotype.Component; -import javax.activation.DataHandler; -import javax.mail.Message; -import javax.mail.Multipart; -import javax.mail.internet.*; -import javax.mail.util.ByteArrayDataSource; +import jakarta.activation.DataHandler; +import jakarta.mail.Message; +import jakarta.mail.Multipart; +import jakarta.mail.internet.*; +import jakarta.mail.util.ByteArrayDataSource; import java.io.ByteArrayOutputStream; import java.util.ArrayList; import java.util.List; diff --git a/openex-api/src/main/java/io/openex/injects/email/service/ImapService.java b/openex-api/src/main/java/io/openex/injects/email/service/ImapService.java index 4252c52383..fd9d145130 100644 --- a/openex-api/src/main/java/io/openex/injects/email/service/ImapService.java +++ b/openex-api/src/main/java/io/openex/injects/email/service/ImapService.java @@ -17,11 +17,11 @@ import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; -import javax.activation.DataSource; -import javax.mail.*; -import javax.mail.internet.InternetAddress; -import javax.mail.internet.MimeMessage; -import javax.mail.internet.MimeMultipart; +import jakarta.activation.DataSource; +import jakarta.mail.*; +import jakarta.mail.internet.InternetAddress; +import jakarta.mail.internet.MimeMessage; +import jakarta.mail.internet.MimeMultipart; import java.io.IOException; import java.util.*; import java.util.logging.Level; diff --git a/openex-api/src/main/java/io/openex/injects/manual/ManualExecutor.java b/openex-api/src/main/java/io/openex/injects/manual/ManualExecutor.java index ac9de62fa0..d3ff80a5df 100644 --- a/openex-api/src/main/java/io/openex/injects/manual/ManualExecutor.java +++ b/openex-api/src/main/java/io/openex/injects/manual/ManualExecutor.java @@ -7,7 +7,7 @@ import io.openex.model.Expectation; import org.springframework.stereotype.Component; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import java.util.List; @Component(ManualContract.TYPE) diff --git a/openex-api/src/main/java/io/openex/migration/V2_67__Variables_Enum.java b/openex-api/src/main/java/io/openex/migration/V2_67__Variables_Enum.java new file mode 100644 index 0000000000..4120f1380d --- /dev/null +++ b/openex-api/src/main/java/io/openex/migration/V2_67__Variables_Enum.java @@ -0,0 +1,37 @@ +package io.openex.migration; + +import io.openex.database.model.Variable; +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.PreparedStatement; +import java.sql.ResultSet; +import java.sql.Statement; + +@Component +public class V2_67__Variables_Enum extends BaseJavaMigration { + + @Override + public void migrate(Context context) throws Exception { + Connection connection = context.getConnection(); + Statement select = connection.createStatement(); + // Alter column type for ENUM + select.execute("ALTER TABLE variables ALTER COLUMN variable_type TYPE varchar(255)"); + // Migration datas + ResultSet results = select.executeQuery("SELECT * FROM variables"); + PreparedStatement statement = connection.prepareStatement( + "UPDATE variables SET variable_type = ? WHERE variable_id = ?" + ); + while (results.next()) { + String id = results.getString("variable_id"); + int type = results.getInt("variable_type"); + Variable.VariableType newType = Variable.VariableType.values()[type]; + statement.setString(1, String.valueOf(newType)); + statement.setString(2, id); + statement.addBatch(); + } + statement.executeBatch(); + } +} diff --git a/openex-api/src/main/java/io/openex/rest/attack_pattern/AttackPatternApi.java b/openex-api/src/main/java/io/openex/rest/attack_pattern/AttackPatternApi.java index 232ad37cb8..8e9d1402b0 100644 --- a/openex-api/src/main/java/io/openex/rest/attack_pattern/AttackPatternApi.java +++ b/openex-api/src/main/java/io/openex/rest/attack_pattern/AttackPatternApi.java @@ -5,16 +5,16 @@ import io.openex.rest.attack_pattern.form.AttackPatternCreateInput; import io.openex.rest.helper.RestBehavior; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.annotation.Secured; import org.springframework.web.bind.annotation.*; -import javax.annotation.security.RolesAllowed; -import javax.validation.Valid; +import jakarta.validation.Valid; import static io.openex.database.model.User.ROLE_ADMIN; import static io.openex.database.model.User.ROLE_USER; @RestController -@RolesAllowed(ROLE_USER) +@Secured(ROLE_USER) public class AttackPatternApi extends RestBehavior { private AttackPatternRepository attackPatternRepository; @@ -34,7 +34,7 @@ public AttackPattern attackPattern(@PathVariable String attackPatternId) { return attackPatternRepository.findById(attackPatternId).orElseThrow(); } - @RolesAllowed(ROLE_ADMIN) + @Secured(ROLE_ADMIN) @PostMapping("/api/attack_patterns") public AttackPattern createAttackPattern(@Valid @RequestBody AttackPatternCreateInput input) { AttackPattern attackPattern = new AttackPattern(); @@ -43,7 +43,7 @@ public AttackPattern createAttackPattern(@Valid @RequestBody AttackPatternCreate return attackPatternRepository.save(attackPattern); } - @RolesAllowed(ROLE_ADMIN) + @Secured(ROLE_ADMIN) @DeleteMapping("/api/attack_patterns/{attackPatternId}") public void deleteAttackPattern(@PathVariable String attackPatternId) { attackPatternRepository.deleteById(attackPatternId); diff --git a/openex-api/src/main/java/io/openex/rest/attack_pattern/form/AttackPatternCreateInput.java b/openex-api/src/main/java/io/openex/rest/attack_pattern/form/AttackPatternCreateInput.java index bad8cbee20..b98661b2c6 100644 --- a/openex-api/src/main/java/io/openex/rest/attack_pattern/form/AttackPatternCreateInput.java +++ b/openex-api/src/main/java/io/openex/rest/attack_pattern/form/AttackPatternCreateInput.java @@ -3,7 +3,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Getter; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; import java.util.ArrayList; import java.util.List; @@ -79,4 +79,4 @@ public String getParentId() { public void setParentId(String parentId) { this.parentId = parentId; } -} \ No newline at end of file +} diff --git a/openex-api/src/main/java/io/openex/rest/audience/AudienceApi.java b/openex-api/src/main/java/io/openex/rest/audience/AudienceApi.java new file mode 100644 index 0000000000..e69de29bb2 diff --git a/openex-api/src/main/java/io/openex/rest/challenge/ChallengeApi.java b/openex-api/src/main/java/io/openex/rest/challenge/ChallengeApi.java index 661cbfbbb0..38b632cfca 100644 --- a/openex-api/src/main/java/io/openex/rest/challenge/ChallengeApi.java +++ b/openex-api/src/main/java/io/openex/rest/challenge/ChallengeApi.java @@ -11,13 +11,13 @@ import io.openex.rest.challenge.response.ChallengesReader; import io.openex.rest.helper.RestBehavior; import io.openex.service.ChallengeService; +import jakarta.transaction.Transactional; +import jakarta.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.annotation.Secured; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; -import javax.annotation.security.RolesAllowed; -import javax.transaction.Transactional; -import javax.validation.Valid; import java.time.Instant; import java.util.Comparator; import java.util.List; @@ -170,7 +170,7 @@ public ChallengesReader observerChallenges(@PathVariable String exerciseId) { return challengesReader; } - @RolesAllowed(ROLE_ADMIN) + @Secured(ROLE_ADMIN) @DeleteMapping("/api/challenges/{challengeId}") public void deleteChallenge(@PathVariable String challengeId) { challengeRepository.deleteById(challengeId); @@ -228,4 +228,4 @@ public ChallengesReader validateChallenge(@PathVariable String exerciseId, } return playerChallenges(exerciseId, userId); } -} \ No newline at end of file +} diff --git a/openex-api/src/main/java/io/openex/rest/challenge/form/ChallengeCreateInput.java b/openex-api/src/main/java/io/openex/rest/challenge/form/ChallengeCreateInput.java index 467ade2d10..44ee90d3e7 100644 --- a/openex-api/src/main/java/io/openex/rest/challenge/form/ChallengeCreateInput.java +++ b/openex-api/src/main/java/io/openex/rest/challenge/form/ChallengeCreateInput.java @@ -2,8 +2,8 @@ import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotEmpty; import java.util.ArrayList; import java.util.List; diff --git a/openex-api/src/main/java/io/openex/rest/challenge/form/ChallengeUpdateInput.java b/openex-api/src/main/java/io/openex/rest/challenge/form/ChallengeUpdateInput.java index 1cc554243c..24ef93c5fe 100644 --- a/openex-api/src/main/java/io/openex/rest/challenge/form/ChallengeUpdateInput.java +++ b/openex-api/src/main/java/io/openex/rest/challenge/form/ChallengeUpdateInput.java @@ -2,8 +2,8 @@ import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotEmpty; import java.util.ArrayList; import java.util.List; diff --git a/openex-api/src/main/java/io/openex/rest/challenge/form/FlagInput.java b/openex-api/src/main/java/io/openex/rest/challenge/form/FlagInput.java index c895cc61ae..fbf295dccf 100644 --- a/openex-api/src/main/java/io/openex/rest/challenge/form/FlagInput.java +++ b/openex-api/src/main/java/io/openex/rest/challenge/form/FlagInput.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; import static io.openex.config.AppConfig.MANDATORY_MESSAGE; diff --git a/openex-api/src/main/java/io/openex/rest/channel/ChannelApi.java b/openex-api/src/main/java/io/openex/rest/channel/ChannelApi.java index 1e17db2b16..e99c16eef1 100644 --- a/openex-api/src/main/java/io/openex/rest/channel/ChannelApi.java +++ b/openex-api/src/main/java/io/openex/rest/channel/ChannelApi.java @@ -8,13 +8,13 @@ import io.openex.rest.channel.form.*; import io.openex.rest.channel.model.VirtualArticle; import io.openex.rest.channel.response.ChannelReader; +import jakarta.transaction.Transactional; +import jakarta.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.annotation.Secured; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; -import javax.annotation.security.RolesAllowed; -import javax.transaction.Transactional; -import javax.validation.Valid; import java.time.Instant; import java.util.*; import java.util.stream.Collectors; @@ -78,7 +78,7 @@ public Channel channel(@PathVariable String channelId) { return channelRepository.findById(channelId).orElseThrow(); } - @RolesAllowed(ROLE_ADMIN) + @Secured(ROLE_ADMIN) @PutMapping("/api/channels/{channelId}") public Channel updateChannel(@PathVariable String channelId, @Valid @RequestBody ChannelUpdateInput input) { Channel channel = channelRepository.findById(channelId).orElseThrow(); @@ -86,7 +86,7 @@ public Channel updateChannel(@PathVariable String channelId, @Valid @RequestBody return channelRepository.save(channel); } - @RolesAllowed(ROLE_ADMIN) + @Secured(ROLE_ADMIN) @PutMapping("/api/channels/{channelId}/logos") public Channel updateChannelLogos(@PathVariable String channelId, @Valid @RequestBody ChannelUpdateLogoInput input) { Channel channel = channelRepository.findById(channelId).orElseThrow(); @@ -103,7 +103,7 @@ public Channel updateChannelLogos(@PathVariable String channelId, @Valid @Reques return channelRepository.save(channel); } - @RolesAllowed(ROLE_ADMIN) + @Secured(ROLE_ADMIN) @PostMapping("/api/channels") public Channel createChannel(@Valid @RequestBody ChannelCreateInput input) { Channel channel = new Channel(); @@ -111,7 +111,7 @@ public Channel createChannel(@Valid @RequestBody ChannelCreateInput input) { return channelRepository.save(channel); } - @RolesAllowed(ROLE_ADMIN) + @Secured(ROLE_ADMIN) @DeleteMapping("/api/channels/{channelId}") public void deleteChannel(@PathVariable String channelId) { channelRepository.deleteById(channelId); @@ -267,7 +267,7 @@ public ChannelReader playerArticles(@PathVariable String exerciseId, @PathVariab .filter(Objects::nonNull) .distinct() .collect(Collectors.toMap(VirtualArticle::id, VirtualArticle::date)); - if (toPublishArticleIdsMap.size() > 0) { + if (!toPublishArticleIdsMap.isEmpty()) { List
publishedArticles = fromIterable(articleRepository.findAllById(toPublishArticleIdsMap.keySet())) .stream().filter(article -> article.getChannel().equals(channel)) .peek(article -> article.setVirtualPublication(toPublishArticleIdsMap.get(article.getId()))) diff --git a/openex-api/src/main/java/io/openex/rest/channel/form/ArticleCreateInput.java b/openex-api/src/main/java/io/openex/rest/channel/form/ArticleCreateInput.java index dae859469a..62c87cf4fb 100644 --- a/openex-api/src/main/java/io/openex/rest/channel/form/ArticleCreateInput.java +++ b/openex-api/src/main/java/io/openex/rest/channel/form/ArticleCreateInput.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; import java.util.ArrayList; import java.util.List; diff --git a/openex-api/src/main/java/io/openex/rest/channel/form/ArticleUpdateInput.java b/openex-api/src/main/java/io/openex/rest/channel/form/ArticleUpdateInput.java index 6feeecd42b..1077499e7a 100644 --- a/openex-api/src/main/java/io/openex/rest/channel/form/ArticleUpdateInput.java +++ b/openex-api/src/main/java/io/openex/rest/channel/form/ArticleUpdateInput.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; import java.util.ArrayList; import java.util.List; diff --git a/openex-api/src/main/java/io/openex/rest/channel/form/ChannelCreateInput.java b/openex-api/src/main/java/io/openex/rest/channel/form/ChannelCreateInput.java index 8e095bdf95..e2075a1255 100644 --- a/openex-api/src/main/java/io/openex/rest/channel/form/ChannelCreateInput.java +++ b/openex-api/src/main/java/io/openex/rest/channel/form/ChannelCreateInput.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; import static io.openex.config.AppConfig.MANDATORY_MESSAGE; diff --git a/openex-api/src/main/java/io/openex/rest/channel/form/ChannelUpdateInput.java b/openex-api/src/main/java/io/openex/rest/channel/form/ChannelUpdateInput.java index 5801c69227..366f43ff77 100644 --- a/openex-api/src/main/java/io/openex/rest/channel/form/ChannelUpdateInput.java +++ b/openex-api/src/main/java/io/openex/rest/channel/form/ChannelUpdateInput.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; import static io.openex.config.AppConfig.MANDATORY_MESSAGE; diff --git a/openex-api/src/main/java/io/openex/rest/comcheck/ComcheckApi.java b/openex-api/src/main/java/io/openex/rest/comcheck/ComcheckApi.java index 9756784a48..93e06eae33 100644 --- a/openex-api/src/main/java/io/openex/rest/comcheck/ComcheckApi.java +++ b/openex-api/src/main/java/io/openex/rest/comcheck/ComcheckApi.java @@ -11,8 +11,8 @@ import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; -import javax.transaction.Transactional; -import javax.validation.Valid; +import jakarta.transaction.Transactional; +import jakarta.validation.Valid; import java.util.List; import static io.openex.helper.StreamHelper.fromIterable; diff --git a/openex-api/src/main/java/io/openex/rest/comcheck/form/ComcheckInput.java b/openex-api/src/main/java/io/openex/rest/comcheck/form/ComcheckInput.java index 7e50653b99..a17f35fb53 100644 --- a/openex-api/src/main/java/io/openex/rest/comcheck/form/ComcheckInput.java +++ b/openex-api/src/main/java/io/openex/rest/comcheck/form/ComcheckInput.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; import java.time.Instant; import java.util.ArrayList; import java.util.List; diff --git a/openex-api/src/main/java/io/openex/rest/document/DocumentApi.java b/openex-api/src/main/java/io/openex/rest/document/DocumentApi.java index 53a19a53f7..171a0ce923 100644 --- a/openex-api/src/main/java/io/openex/rest/document/DocumentApi.java +++ b/openex-api/src/main/java/io/openex/rest/document/DocumentApi.java @@ -19,9 +19,9 @@ import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; -import javax.servlet.http.HttpServletResponse; -import javax.transaction.Transactional; -import javax.validation.Valid; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.transaction.Transactional; +import jakarta.validation.Valid; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; diff --git a/openex-api/src/main/java/io/openex/rest/document/form/DocumentUpdateInput.java b/openex-api/src/main/java/io/openex/rest/document/form/DocumentUpdateInput.java index a00af3c4d5..e5c161cb37 100644 --- a/openex-api/src/main/java/io/openex/rest/document/form/DocumentUpdateInput.java +++ b/openex-api/src/main/java/io/openex/rest/document/form/DocumentUpdateInput.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotEmpty; import java.util.ArrayList; import java.util.List; diff --git a/openex-api/src/main/java/io/openex/rest/exercise/ExerciseApi.java b/openex-api/src/main/java/io/openex/rest/exercise/ExerciseApi.java index a9561272f0..9a92d11bab 100644 --- a/openex-api/src/main/java/io/openex/rest/exercise/ExerciseApi.java +++ b/openex-api/src/main/java/io/openex/rest/exercise/ExerciseApi.java @@ -15,26 +15,29 @@ import io.openex.rest.exercise.response.PublicExercise; import io.openex.rest.helper.RestBehavior; import io.openex.service.*; +import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.transaction.Transactional; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.jpa.domain.Specification; import org.springframework.http.HttpHeaders; +import org.springframework.security.access.annotation.Secured; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import reactor.util.function.Tuples; -import javax.annotation.Resource; -import javax.annotation.security.RolesAllowed; -import javax.servlet.http.HttpServletResponse; -import javax.transaction.Transactional; -import javax.validation.Valid; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; import java.io.IOException; import java.io.InputStream; import java.time.Instant; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Optional; import java.util.logging.Level; import java.util.logging.Logger; import java.util.zip.ZipEntry; @@ -52,645 +55,673 @@ import static java.time.temporal.ChronoUnit.MINUTES; @RestController -@RolesAllowed(ROLE_USER) +@Secured(ROLE_USER) public class ExerciseApi extends RestBehavior { - private static final Logger LOGGER = Logger.getLogger(ExerciseApi.class.getName()); - - // region properties - @Value("${openex.mail.imap.enabled}") - private boolean imapEnabled; - - @Value("${openex.mail.imap.username}") - private String imapUsername; - - @Resource - private OpenExConfig openExConfig; - // endregion - - // region repositories - private LogRepository logRepository; - private TagRepository tagRepository; - private UserRepository userRepository; - private PauseRepository pauseRepository; - private GroupRepository groupRepository; - private GrantRepository grantRepository; - private DocumentRepository documentRepository; - private ExerciseRepository exerciseRepository; - private TeamRepository teamRepository; - private ExerciseTeamUserRepository exerciseTeamUserRepository; - private LogRepository exerciseLogRepository; - private DryRunRepository dryRunRepository; - private DryInjectRepository dryInjectRepository; - private ComcheckRepository comcheckRepository; - private ImportService importService; - private InjectRepository injectRepository; - private LessonsCategoryRepository lessonsCategoryRepository; - private LessonsQuestionRepository lessonsQuestionRepository; - private LessonsAnswerRepository lessonsAnswerRepository; - // endregion - - // region services - private DryrunService dryrunService; - private FileService fileService; - private InjectService injectService; - private ChallengeService challengeService; - private VariableService variableService; - // endregion - - // region setters - @Autowired - public void setChallengeService(ChallengeService challengeService) { - this.challengeService = challengeService; - } - - @Autowired - public void setInjectService(InjectService injectService) { - this.injectService = injectService; - } - - @Autowired - public void setImportService(ImportService importService) { - this.importService = importService; - } - - @Autowired - public void setLogRepository(LogRepository logRepository) { - this.logRepository = logRepository; - } - - @Autowired - public void setUserRepository(UserRepository userRepository) { - this.userRepository = userRepository; - } - - @Autowired - public void setPauseRepository(PauseRepository pauseRepository) { - this.pauseRepository = pauseRepository; - } - - @Autowired - public void setGrantRepository(GrantRepository grantRepository) { - this.grantRepository = grantRepository; - } - - @Autowired - public void setGroupRepository(GroupRepository groupRepository) { - this.groupRepository = groupRepository; - } - - @Autowired - public void setDryrunService(DryrunService dryrunService) { - this.dryrunService = dryrunService; - } - - @Autowired - public void setInjectRepository(InjectRepository injectRepository) { - this.injectRepository = injectRepository; - } - - @Autowired - public void setFileService(FileService fileService) { - this.fileService = fileService; - } - - @Autowired - public void setTagRepository(TagRepository tagRepository) { - this.tagRepository = tagRepository; - } - - @Autowired - public void setDocumentRepository(DocumentRepository documentRepository) { - this.documentRepository = documentRepository; - } - - @Autowired - public void setComcheckRepository(ComcheckRepository comcheckRepository) { - this.comcheckRepository = comcheckRepository; - } - - @Autowired - public void setDryRunRepository(DryRunRepository dryRunRepository) { - this.dryRunRepository = dryRunRepository; - } - - @Autowired - public void setDryInjectRepository(DryInjectRepository dryInjectRepository) { - this.dryInjectRepository = dryInjectRepository; - } - - @Autowired - public void setExerciseLogRepository(LogRepository exerciseLogRepository) { - this.exerciseLogRepository = exerciseLogRepository; - } - - @Autowired - public void setExerciseRepository(ExerciseRepository exerciseRepository) { - this.exerciseRepository = exerciseRepository; - } - - @Autowired - public void setTeamRepository(TeamRepository teamRepository) { - this.teamRepository = teamRepository; - } - - @Autowired - public void setExerciseTeamUserRepository(ExerciseTeamUserRepository exerciseTeamUserRepository) { - this.exerciseTeamUserRepository = exerciseTeamUserRepository; - } - - @Autowired - public void setLessonsCategoryRepository(LessonsCategoryRepository lessonsCategoryRepository) { - this.lessonsCategoryRepository = lessonsCategoryRepository; - } - - @Autowired - public void setLessonsQuestionRepository(LessonsQuestionRepository lessonsQuestionRepository) { - this.lessonsQuestionRepository = lessonsQuestionRepository; - } - - @Autowired - public void setLessonsAnswerRepository(LessonsAnswerRepository lessonsAnswerRepository) { - this.lessonsAnswerRepository = lessonsAnswerRepository; - } - - @Autowired - public void setVariableService(@NotNull final VariableService variableService) { - this.variableService = variableService; - } - // endregion - - // region logs - @GetMapping("/api/exercises/{exercise}/logs") - public Iterable logs(@PathVariable String exercise) { - return exerciseLogRepository.findAll(ExerciseLogSpecification.fromExercise(exercise)); - } - - @PostMapping("/api/exercises/{exerciseId}/logs") - public Log createLog(@PathVariable String exerciseId, @Valid @RequestBody LogCreateInput input) { - Exercise exercise = exerciseRepository.findById(exerciseId).orElseThrow(); - Log log = new Log(); - log.setUpdateAttributes(input); - log.setExercise(exercise); - log.setTags(fromIterable(tagRepository.findAllById(input.getTagIds()))); - log.setUser(userRepository.findById(currentUser().getId()).orElseThrow()); - return exerciseLogRepository.save(log); - } - - @PutMapping("/api/exercises/{exerciseId}/logs/{logId}") - @PreAuthorize("isExercisePlanner(#exerciseId)") - public Log updateLog(@PathVariable String exerciseId, @PathVariable String logId, @Valid @RequestBody LogCreateInput input) { - Log log = logRepository.findById(logId).orElseThrow(); - log.setUpdateAttributes(input); - log.setTags(fromIterable(tagRepository.findAllById(input.getTagIds()))); - return logRepository.save(log); - } - - @DeleteMapping("/api/exercises/{exerciseId}/logs/{logId}") - @PreAuthorize("isExercisePlanner(#exerciseId)") - public void deleteLog(@PathVariable String exerciseId, @PathVariable String logId) { - logRepository.deleteById(logId); - } - // endregion - - // region dryruns - @GetMapping("/api/exercises/{exerciseId}/dryruns") - public Iterable dryruns(@PathVariable String exerciseId) { - return dryRunRepository.findAll(DryRunSpecification.fromExercise(exerciseId)); - } - - @PostMapping("/api/exercises/{exerciseId}/dryruns") - @PreAuthorize("isExercisePlanner(#exerciseId)") - public Dryrun createDryrun(@PathVariable String exerciseId, @Valid @RequestBody DryrunCreateInput input) { - Exercise exercise = exerciseRepository.findById(exerciseId).orElseThrow(); - List userIds = input.getUserIds(); - List users = userIds.size() == 0 ? List.of(userRepository.findById(currentUser().getId()).orElseThrow()) : fromIterable(userRepository.findAllById(userIds)); - return dryrunService.provisionDryrun(exercise, users, input.getName()); - } - - @GetMapping("/api/exercises/{exerciseId}/dryruns/{dryrunId}") - @PreAuthorize("isExerciseObserver(#exerciseId)") - public Dryrun dryrun(@PathVariable String exerciseId, @PathVariable String dryrunId) { - Specification filters = DryRunSpecification.fromExercise(exerciseId).and(DryRunSpecification.id(dryrunId)); - return dryRunRepository.findOne(filters).orElseThrow(); - } - - @DeleteMapping("/api/exercises/{exerciseId}/dryruns/{dryrunId}") - @PreAuthorize("isExercisePlanner(#exerciseId)") - public void deleteDryrun(@PathVariable String exerciseId, @PathVariable String dryrunId) { - dryRunRepository.deleteById(dryrunId); - } - - @GetMapping("/api/exercises/{exerciseId}/dryruns/{dryrunId}/dryinjects") - @PreAuthorize("isExerciseObserver(#exerciseId)") - public List dryrunInjects(@PathVariable String exerciseId, @PathVariable String dryrunId) { - return dryInjectRepository.findAll(DryInjectSpecification.fromDryRun(dryrunId)); - } - // endregion - - // region comchecks - @GetMapping("/api/exercises/{exercise}/comchecks") - public Iterable comchecks(@PathVariable String exercise) { - return comcheckRepository.findAll(ComcheckSpecification.fromExercise(exercise)); - } - - @GetMapping("/api/exercises/{exercise}/comchecks/{comcheck}") - public Comcheck comcheck(@PathVariable String exercise, @PathVariable String comcheck) { - Specification filters = ComcheckSpecification.fromExercise(exercise).and(ComcheckSpecification.id(comcheck)); - return comcheckRepository.findOne(filters).orElseThrow(); - } - - @GetMapping("/api/exercises/{exercise}/comchecks/{comcheck}/statuses") - public List comcheckStatuses(@PathVariable String exercise, @PathVariable String comcheck) { - return comcheck(exercise, comcheck).getComcheckStatus(); - } - // endregion - - // region teams - @GetMapping("/api/exercises/{exerciseId}/teams") - @PreAuthorize("isExerciseObserver(#exerciseId)") - public Iterable getExerciseTeams(@PathVariable String exerciseId) { - Exercise exercise = exerciseRepository.findById(exerciseId).orElseThrow(); - return exercise.getTeams(); - } - - @Transactional(rollbackOn = Exception.class) - @PutMapping("/api/exercises/{exerciseId}/teams/add") - @PreAuthorize("isExercisePlanner(#exerciseId)") - public Iterable addExerciseTeams(@PathVariable String exerciseId, @Valid @RequestBody ExerciseUpdateTeamsInput input) { - Exercise exercise = exerciseRepository.findById(exerciseId).orElseThrow(); - List teams = exercise.getTeams(); - teams.addAll(fromIterable(teamRepository.findAllById(input.getTeamIds()))); - exercise.setTeams(teams); - exerciseRepository.save(exercise); - return teamRepository.findAllById(input.getTeamIds()); - } - - @Transactional(rollbackOn = Exception.class) - @PutMapping("/api/exercises/{exerciseId}/teams/remove") - @PreAuthorize("isExercisePlanner(#exerciseId)") - public Iterable removeExerciseTeams(@PathVariable String exerciseId, @Valid @RequestBody ExerciseUpdateTeamsInput input) { - Exercise exercise = exerciseRepository.findById(exerciseId).orElseThrow(); - // Remove teams from exercise - List teams = exercise.getTeams().stream().filter(team -> !input.getTeamIds().contains(team.getId())).toList(); - exercise.setTeams(fromIterable(teams)); - exerciseRepository.save(exercise); - // Remove all association between users / exercises / teams - input.getTeamIds().forEach(teamId -> { - exerciseTeamUserRepository.deleteTeamFromAllReferences(teamId); - }); - return teamRepository.findAllById(input.getTeamIds()); - } - - @Transactional(rollbackOn = Exception.class) - @PutMapping("/api/exercises/{exerciseId}/teams/{teamId}/players/add") - @PreAuthorize("isExercisePlanner(#exerciseId)") - public Exercise addExerciseTeamPlayers(@PathVariable String exerciseId, @PathVariable String teamId, @Valid @RequestBody ExerciseTeamPlayersEnableInput input) { - Exercise exercise = exerciseRepository.findById(exerciseId).orElseThrow(); - Team team = teamRepository.findById(teamId).orElseThrow(); - input.getPlayersIds().forEach(playerId -> { - ExerciseTeamUser exerciseTeamUser = new ExerciseTeamUser(); - exerciseTeamUser.setExercise(exercise); - exerciseTeamUser.setTeam(team); - exerciseTeamUser.setUser(userRepository.findById(playerId).orElseThrow()); - exerciseTeamUserRepository.save(exerciseTeamUser); - }); - return exerciseRepository.findById(exerciseId).orElseThrow(); - } - - @Transactional(rollbackOn = Exception.class) - @PutMapping("/api/exercises/{exerciseId}/teams/{teamId}/players/remove") - @PreAuthorize("isExercisePlanner(#exerciseId)") - public Exercise removeExerciseTeamPlayers(@PathVariable String exerciseId, @PathVariable String teamId, @Valid @RequestBody ExerciseTeamPlayersEnableInput input) { - input.getPlayersIds().forEach(playerId -> { - ExerciseTeamUserId exerciseTeamUserId = new ExerciseTeamUserId(); - exerciseTeamUserId.setExerciseId(exerciseId); - exerciseTeamUserId.setTeamId(teamId); - exerciseTeamUserId.setUserId(playerId); - exerciseTeamUserRepository.deleteById(exerciseTeamUserId); - }); - return exerciseRepository.findById(exerciseId).orElseThrow(); - } - // endregion - - // region exercises - @Transactional(rollbackOn = Exception.class) - @PostMapping("/api/exercises") - public Exercise createExercise(@Valid @RequestBody ExerciseCreateInput input) { - Exercise exercise = new Exercise(); - exercise.setUpdateAttributes(input); - exercise.setTags(fromIterable(tagRepository.findAllById(input.getTagIds()))); - if (imapEnabled) { - exercise.setReplyTo(imapUsername); - } else { - exercise.setReplyTo(openExConfig.getDefaultMailer()); - } - // Find automatic groups to grants - List groups = fromIterable(groupRepository.findAll()); - List grants = groups.stream().filter(group -> group.getExercisesDefaultGrants().size() > 0).flatMap(group -> group.getExercisesDefaultGrants().stream().map(s -> Tuples.of(group, s))).map(tuple -> { - Grant grant = new Grant(); - grant.setGroup(tuple.getT1()); - grant.setName(tuple.getT2()); - grant.setExercise(exercise); - return grant; + private static final Logger LOGGER = Logger.getLogger(ExerciseApi.class.getName()); + + // region properties + @Value("${openex.mail.imap.enabled}") + private boolean imapEnabled; + + @Value("${openex.mail.imap.username}") + private String imapUsername; + + @Resource + private OpenExConfig openExConfig; + // endregion + + // region repositories + private LogRepository logRepository; + private TagRepository tagRepository; + private UserRepository userRepository; + private PauseRepository pauseRepository; + private GroupRepository groupRepository; + private GrantRepository grantRepository; + private DocumentRepository documentRepository; + private ExerciseRepository exerciseRepository; + private TeamRepository teamRepository; + private ExerciseTeamUserRepository exerciseTeamUserRepository; + private LogRepository exerciseLogRepository; + private DryRunRepository dryRunRepository; + private DryInjectRepository dryInjectRepository; + private ComcheckRepository comcheckRepository; + private ImportService importService; + private InjectRepository injectRepository; + private LessonsCategoryRepository lessonsCategoryRepository; + private LessonsQuestionRepository lessonsQuestionRepository; + private LessonsAnswerRepository lessonsAnswerRepository; + // endregion + + // region services + private DryrunService dryrunService; + private FileService fileService; + private InjectService injectService; + private ChallengeService challengeService; + private VariableService variableService; + // endregion + + // region setters + @Autowired + public void setChallengeService(ChallengeService challengeService) { + this.challengeService = challengeService; + } + + @Autowired + public void setInjectService(InjectService injectService) { + this.injectService = injectService; + } + + @Autowired + public void setImportService(ImportService importService) { + this.importService = importService; + } + + @Autowired + public void setLogRepository(LogRepository logRepository) { + this.logRepository = logRepository; + } + + @Autowired + public void setUserRepository(UserRepository userRepository) { + this.userRepository = userRepository; + } + + @Autowired + public void setPauseRepository(PauseRepository pauseRepository) { + this.pauseRepository = pauseRepository; + } + + @Autowired + public void setGrantRepository(GrantRepository grantRepository) { + this.grantRepository = grantRepository; + } + + @Autowired + public void setGroupRepository(GroupRepository groupRepository) { + this.groupRepository = groupRepository; + } + + @Autowired + public void setDryrunService(DryrunService dryrunService) { + this.dryrunService = dryrunService; + } + + @Autowired + public void setInjectRepository(InjectRepository injectRepository) { + this.injectRepository = injectRepository; + } + + @Autowired + public void setFileService(FileService fileService) { + this.fileService = fileService; + } + + @Autowired + public void setTagRepository(TagRepository tagRepository) { + this.tagRepository = tagRepository; + } + + @Autowired + public void setDocumentRepository(DocumentRepository documentRepository) { + this.documentRepository = documentRepository; + } + + @Autowired + public void setComcheckRepository(ComcheckRepository comcheckRepository) { + this.comcheckRepository = comcheckRepository; + } + + @Autowired + public void setDryRunRepository(DryRunRepository dryRunRepository) { + this.dryRunRepository = dryRunRepository; + } + + @Autowired + public void setDryInjectRepository(DryInjectRepository dryInjectRepository) { + this.dryInjectRepository = dryInjectRepository; + } + + @Autowired + public void setExerciseLogRepository(LogRepository exerciseLogRepository) { + this.exerciseLogRepository = exerciseLogRepository; + } + + @Autowired + public void setExerciseRepository(ExerciseRepository exerciseRepository) { + this.exerciseRepository = exerciseRepository; + } + + @Autowired + public void setTeamRepository(TeamRepository teamRepository) { + this.teamRepository = teamRepository; + } + + @Autowired + public void setExerciseTeamUserRepository(ExerciseTeamUserRepository exerciseTeamUserRepository) { + this.exerciseTeamUserRepository = exerciseTeamUserRepository; + } + + @Autowired + public void setLessonsCategoryRepository(LessonsCategoryRepository lessonsCategoryRepository) { + this.lessonsCategoryRepository = lessonsCategoryRepository; + } + + @Autowired + public void setLessonsQuestionRepository(LessonsQuestionRepository lessonsQuestionRepository) { + this.lessonsQuestionRepository = lessonsQuestionRepository; + } + + @Autowired + public void setLessonsAnswerRepository(LessonsAnswerRepository lessonsAnswerRepository) { + this.lessonsAnswerRepository = lessonsAnswerRepository; + } + + @Autowired + public void setVariableService(@NotNull final VariableService variableService) { + this.variableService = variableService; + } + // endregion + + // region logs + @GetMapping("/api/exercises/{exercise}/logs") + public Iterable logs(@PathVariable String exercise) { + return exerciseLogRepository.findAll(ExerciseLogSpecification.fromExercise(exercise)); + } + + @PostMapping("/api/exercises/{exerciseId}/logs") + public Log createLog(@PathVariable String exerciseId, @Valid @RequestBody LogCreateInput input) { + Exercise exercise = exerciseRepository.findById(exerciseId).orElseThrow(); + Log log = new Log(); + log.setUpdateAttributes(input); + log.setExercise(exercise); + log.setTags(fromIterable(tagRepository.findAllById(input.getTagIds()))); + log.setUser(userRepository.findById(currentUser().getId()).orElseThrow()); + return exerciseLogRepository.save(log); + } + + @PutMapping("/api/exercises/{exerciseId}/logs/{logId}") + @PreAuthorize("isExercisePlanner(#exerciseId)") + public Log updateLog(@PathVariable String exerciseId, @PathVariable String logId, + @Valid @RequestBody LogCreateInput input) { + Log log = logRepository.findById(logId).orElseThrow(); + log.setUpdateAttributes(input); + log.setTags(fromIterable(tagRepository.findAllById(input.getTagIds()))); + return logRepository.save(log); + } + + @DeleteMapping("/api/exercises/{exerciseId}/logs/{logId}") + @PreAuthorize("isExercisePlanner(#exerciseId)") + public void deleteLog(@PathVariable String exerciseId, @PathVariable String logId) { + logRepository.deleteById(logId); + } + // endregion + + // region dryruns + @GetMapping("/api/exercises/{exerciseId}/dryruns") + public Iterable dryruns(@PathVariable String exerciseId) { + return dryRunRepository.findAll(DryRunSpecification.fromExercise(exerciseId)); + } + + @PostMapping("/api/exercises/{exerciseId}/dryruns") + @PreAuthorize("isExercisePlanner(#exerciseId)") + public Dryrun createDryrun(@PathVariable String exerciseId, @Valid @RequestBody DryrunCreateInput input) { + Exercise exercise = exerciseRepository.findById(exerciseId).orElseThrow(); + List userIds = input.getUserIds(); + List users = userIds.isEmpty() ? List.of(userRepository.findById(currentUser().getId()).orElseThrow()) + : fromIterable(userRepository.findAllById(userIds)); + return dryrunService.provisionDryrun(exercise, users, input.getName()); + } + + @GetMapping("/api/exercises/{exerciseId}/dryruns/{dryrunId}") + @PreAuthorize("isExerciseObserver(#exerciseId)") + public Dryrun dryrun(@PathVariable String exerciseId, @PathVariable String dryrunId) { + Specification filters = DryRunSpecification.fromExercise(exerciseId).and(DryRunSpecification.id(dryrunId)); + return dryRunRepository.findOne(filters).orElseThrow(); + } + + @DeleteMapping("/api/exercises/{exerciseId}/dryruns/{dryrunId}") + @PreAuthorize("isExercisePlanner(#exerciseId)") + public void deleteDryrun(@PathVariable String exerciseId, @PathVariable String dryrunId) { + dryRunRepository.deleteById(dryrunId); + } + + @GetMapping("/api/exercises/{exerciseId}/dryruns/{dryrunId}/dryinjects") + @PreAuthorize("isExerciseObserver(#exerciseId)") + public List dryrunInjects(@PathVariable String exerciseId, @PathVariable String dryrunId) { + return dryInjectRepository.findAll(DryInjectSpecification.fromDryRun(dryrunId)); + } + // endregion + + // region comchecks + @GetMapping("/api/exercises/{exercise}/comchecks") + public Iterable comchecks(@PathVariable String exercise) { + return comcheckRepository.findAll(ComcheckSpecification.fromExercise(exercise)); + } + + @GetMapping("/api/exercises/{exercise}/comchecks/{comcheck}") + public Comcheck comcheck(@PathVariable String exercise, @PathVariable String comcheck) { + Specification filters = ComcheckSpecification.fromExercise(exercise) + .and(ComcheckSpecification.id(comcheck)); + return comcheckRepository.findOne(filters).orElseThrow(); + } + + @GetMapping("/api/exercises/{exercise}/comchecks/{comcheck}/statuses") + public List comcheckStatuses(@PathVariable String exercise, @PathVariable String comcheck) { + return comcheck(exercise, comcheck).getComcheckStatus(); + } + // endregion + + // region teams + @GetMapping("/api/exercises/{exerciseId}/teams") + @PreAuthorize("isExerciseObserver(#exerciseId)") + public Iterable getExerciseTeams(@PathVariable String exerciseId) { + Exercise exercise = exerciseRepository.findById(exerciseId).orElseThrow(); + return exercise.getTeams(); + } + + @Transactional(rollbackOn = Exception.class) + @PutMapping("/api/exercises/{exerciseId}/teams/add") + @PreAuthorize("isExercisePlanner(#exerciseId)") + public Iterable addExerciseTeams(@PathVariable String exerciseId, + @Valid @RequestBody ExerciseUpdateTeamsInput input) { + Exercise exercise = exerciseRepository.findById(exerciseId).orElseThrow(); + List teams = exercise.getTeams(); + teams.addAll(fromIterable(teamRepository.findAllById(input.getTeamIds()))); + exercise.setTeams(teams); + exerciseRepository.save(exercise); + return teamRepository.findAllById(input.getTeamIds()); + } + + @Transactional(rollbackOn = Exception.class) + @PutMapping("/api/exercises/{exerciseId}/teams/remove") + @PreAuthorize("isExercisePlanner(#exerciseId)") + public Iterable removeExerciseTeams(@PathVariable String exerciseId, + @Valid @RequestBody ExerciseUpdateTeamsInput input) { + Exercise exercise = exerciseRepository.findById(exerciseId).orElseThrow(); + // Remove teams from exercise + List teams = exercise.getTeams().stream().filter(team -> !input.getTeamIds().contains(team.getId())).toList(); + exercise.setTeams(fromIterable(teams)); + exerciseRepository.save(exercise); + // Remove all association between users / exercises / teams + input.getTeamIds().forEach(teamId -> { + exerciseTeamUserRepository.deleteTeamFromAllReferences(teamId); + }); + return teamRepository.findAllById(input.getTeamIds()); + } + + @Transactional(rollbackOn = Exception.class) + @PutMapping("/api/exercises/{exerciseId}/teams/{teamId}/players/add") + @PreAuthorize("isExercisePlanner(#exerciseId)") + public Exercise addExerciseTeamPlayers(@PathVariable String exerciseId, @PathVariable String teamId, + @Valid @RequestBody ExerciseTeamPlayersEnableInput input) { + Exercise exercise = exerciseRepository.findById(exerciseId).orElseThrow(); + Team team = teamRepository.findById(teamId).orElseThrow(); + input.getPlayersIds().forEach(playerId -> { + ExerciseTeamUser exerciseTeamUser = new ExerciseTeamUser(); + exerciseTeamUser.setExercise(exercise); + exerciseTeamUser.setTeam(team); + exerciseTeamUser.setUser(userRepository.findById(playerId).orElseThrow()); + exerciseTeamUserRepository.save(exerciseTeamUser); + }); + return exerciseRepository.findById(exerciseId).orElseThrow(); + } + + @Transactional(rollbackOn = Exception.class) + @PutMapping("/api/exercises/{exerciseId}/teams/{teamId}/players/remove") + @PreAuthorize("isExercisePlanner(#exerciseId)") + public Exercise removeExerciseTeamPlayers(@PathVariable String exerciseId, @PathVariable String teamId, + @Valid @RequestBody ExerciseTeamPlayersEnableInput input) { + input.getPlayersIds().forEach(playerId -> { + ExerciseTeamUserId exerciseTeamUserId = new ExerciseTeamUserId(); + exerciseTeamUserId.setExerciseId(exerciseId); + exerciseTeamUserId.setTeamId(teamId); + exerciseTeamUserId.setUserId(playerId); + exerciseTeamUserRepository.deleteById(exerciseTeamUserId); + }); + return exerciseRepository.findById(exerciseId).orElseThrow(); + } + // endregion + + // region exercises + @Transactional(rollbackOn = Exception.class) + @PostMapping("/api/exercises") + public Exercise createExercise(@Valid @RequestBody ExerciseCreateInput input) { + Exercise exercise = new Exercise(); + exercise.setUpdateAttributes(input); + exercise.setTags(fromIterable(tagRepository.findAllById(input.getTagIds()))); + if (imapEnabled) { + exercise.setReplyTo(imapUsername); + } else { + exercise.setReplyTo(openExConfig.getDefaultMailer()); + } + // Find automatic groups to grants + List groups = fromIterable(groupRepository.findAll()); + List grants = groups.stream().filter(group -> !group.getExercisesDefaultGrants().isEmpty()) + .flatMap(group -> group.getExercisesDefaultGrants().stream().map(s -> Tuples.of(group, s))).map(tuple -> { + Grant grant = new Grant(); + grant.setGroup(tuple.getT1()); + grant.setName(tuple.getT2()); + grant.setExercise(exercise); + return grant; }).toList(); - if (grants.size() > 0) { - Iterable exerciseGrants = grantRepository.saveAll(grants); - exercise.setGrants(fromIterable(exerciseGrants)); - } - return exerciseRepository.save(exercise); - } - - @PutMapping("/api/exercises/{exerciseId}") - @PreAuthorize("isExercisePlanner(#exerciseId)") - public Exercise updateExerciseInformation(@PathVariable String exerciseId, @Valid @RequestBody ExerciseUpdateInput input) { - Exercise exercise = exerciseRepository.findById(exerciseId).orElseThrow(); - exercise.setUpdateAttributes(input); - return exerciseRepository.save(exercise); - } - - @PutMapping("/api/exercises/{exerciseId}/start_date") - @PreAuthorize("isExercisePlanner(#exerciseId)") - public Exercise updateExerciseStart(@PathVariable String exerciseId, @Valid @RequestBody ExerciseUpdateStartDateInput input) throws InputValidationException { - Exercise exercise = exerciseRepository.findById(exerciseId).orElseThrow(); - if (!exercise.getStatus().equals(SCHEDULED)) { - String message = "Change date is only possible in scheduling state"; - throw new InputValidationException("exercise_start_date", message); - } - exercise.setUpdateAttributes(input); - return exerciseRepository.save(exercise); - } - - @PutMapping("/api/exercises/{exerciseId}/tags") - @PreAuthorize("isExercisePlanner(#exerciseId)") - public Exercise updateExerciseTags(@PathVariable String exerciseId, @Valid @RequestBody ExerciseUpdateTagsInput input) { - Exercise exercise = exerciseRepository.findById(exerciseId).orElseThrow(); - exercise.setTags(fromIterable(tagRepository.findAllById(input.getTagIds()))); - return exerciseRepository.save(exercise); - } - - @PutMapping("/api/exercises/{exerciseId}/logos") - @PreAuthorize("isExercisePlanner(#exerciseId)") - public Exercise updateExerciseLogos(@PathVariable String exerciseId, @Valid @RequestBody ExerciseUpdateLogoInput input) { - Exercise exercise = exerciseRepository.findById(exerciseId).orElseThrow(); - exercise.setLogoDark(documentRepository.findById(input.getLogoDark()).orElse(null)); - exercise.setLogoLight(documentRepository.findById(input.getLogoLight()).orElse(null)); - return exerciseRepository.save(exercise); - } - - @PutMapping("/api/exercises/{exerciseId}/lessons") - @PreAuthorize("isExercisePlanner(#exerciseId)") - public Exercise updateExerciseLessons(@PathVariable String exerciseId, @Valid @RequestBody ExerciseLessonsInput input) { - Exercise exercise = exerciseRepository.findById(exerciseId).orElseThrow(); - exercise.setLessonsAnonymized(input.getLessonsAnonymized()); - return exerciseRepository.save(exercise); - } - - @DeleteMapping("/api/exercises/{exerciseId}") - @PreAuthorize("isExercisePlanner(#exerciseId)") - public void deleteExercise(@PathVariable String exerciseId) { - exerciseRepository.deleteById(exerciseId); - } - - @GetMapping("/api/exercises/{exerciseId}") - @PreAuthorize("isExerciseObserver(#exerciseId)") - public Exercise exercise(@PathVariable String exerciseId) { - return exerciseRepository.findById(exerciseId).orElseThrow(); - } - - @Transactional(rollbackOn = Exception.class) - @DeleteMapping("/api/exercises/{exerciseId}/{documentId}") - @PreAuthorize("isExercisePlanner(#exerciseId)") - public Exercise deleteDocument(@PathVariable String exerciseId, @PathVariable String documentId) { - Exercise exercise = exerciseRepository.findById(exerciseId).orElseThrow(); - exercise.setUpdatedAt(now()); - Document doc = documentRepository.findById(documentId).orElseThrow(); - List docExercises = doc.getExercises().stream().filter(ex -> !ex.getId().equals(exerciseId)).toList(); - if (docExercises.isEmpty()) { - // Document is no longer associate to any exercise, delete it - documentRepository.delete(doc); - // All associations with this document will be automatically cleanup. - } else { - // Document associated to other exercise, cleanup - doc.setExercises(docExercises); - documentRepository.save(doc); - // Delete document from all exercise injects - injectService.cleanInjectsDocExercise(exerciseId, documentId); - } - return exerciseRepository.save(exercise); - } - - @Transactional(rollbackOn = Exception.class) - @PutMapping("/api/exercises/{exerciseId}/status") - @PreAuthorize("isExercisePlanner(#exerciseId)") - public Exercise changeExerciseStatus(@PathVariable String exerciseId, @Valid @RequestBody ExerciseUpdateStatusInput input) { - STATUS status = input.getStatus(); - Exercise exercise = exerciseRepository.findById(exerciseId).orElseThrow(); - // Check if next status is possible - List nextPossibleStatus = exercise.nextPossibleStatus(); - if (!nextPossibleStatus.contains(status)) { - throw new UnsupportedOperationException("Exercise cant support moving to status " + status.name()); - } - // In case of rescheduled of an exercise. - boolean isCloseState = CANCELED.equals(exercise.getStatus()) || FINISHED.equals(exercise.getStatus()); - if (isCloseState && SCHEDULED.equals(status)) { - exercise.setStart(null); - exercise.setEnd(null); - // Reset pauses - exercise.setCurrentPause(null); - pauseRepository.deleteAll(pauseRepository.findAllForExercise(exerciseId)); - // Reset injects outcome, communications and expectations - injectRepository.saveAll(injectRepository.findAllForExercise(exerciseId).stream().peek(Inject::clean).toList()); - // Reset lessons learned answers - List lessonsAnswers = lessonsCategoryRepository.findAll(LessonsCategorySpecification.fromExercise(exerciseId)).stream().flatMap(lessonsCategory -> lessonsQuestionRepository.findAll(LessonsQuestionSpecification.fromCategory(lessonsCategory.getId())).stream().flatMap(lessonsQuestion -> lessonsAnswerRepository.findAll(LessonsAnswerSpecification.fromQuestion(lessonsQuestion.getId())).stream())).toList(); - lessonsAnswerRepository.deleteAll(lessonsAnswers); - // Delete exercise transient files (communications, ...) - fileService.deleteDirectory(exerciseId); - } - // In case of manual start - if (SCHEDULED.equals(exercise.getStatus()) && RUNNING.equals(status)) { - Instant nextMinute = now().truncatedTo(MINUTES).plus(1, MINUTES); - exercise.setStart(nextMinute); - } - // If exercise move from pause to running state, - // we log the pause date to be able to recompute inject dates. - if (PAUSED.equals(exercise.getStatus()) && RUNNING.equals(status)) { - Instant lastPause = exercise.getCurrentPause().orElseThrow(); - exercise.setCurrentPause(null); - Pause pause = new Pause(); - pause.setDate(lastPause); - pause.setExercise(exercise); - pause.setDuration(between(lastPause, now()).getSeconds()); - pauseRepository.save(pause); - } - // If pause is asked, just set the pause date. - if (RUNNING.equals(exercise.getStatus()) && PAUSED.equals(status)) { - exercise.setCurrentPause(Instant.now()); + if (!grants.isEmpty()) { + Iterable exerciseGrants = grantRepository.saveAll(grants); + exercise.setGrants(fromIterable(exerciseGrants)); + } + return exerciseRepository.save(exercise); + } + + @PutMapping("/api/exercises/{exerciseId}") + @PreAuthorize("isExercisePlanner(#exerciseId)") + public Exercise updateExerciseInformation(@PathVariable String exerciseId, + @Valid @RequestBody ExerciseUpdateInput input) { + Exercise exercise = exerciseRepository.findById(exerciseId).orElseThrow(); + exercise.setUpdateAttributes(input); + return exerciseRepository.save(exercise); + } + + @PutMapping("/api/exercises/{exerciseId}/start_date") + @PreAuthorize("isExercisePlanner(#exerciseId)") + public Exercise updateExerciseStart(@PathVariable String exerciseId, + @Valid @RequestBody ExerciseUpdateStartDateInput input) throws InputValidationException { + Exercise exercise = exerciseRepository.findById(exerciseId).orElseThrow(); + if (!exercise.getStatus().equals(SCHEDULED)) { + String message = "Change date is only possible in scheduling state"; + throw new InputValidationException("exercise_start_date", message); + } + exercise.setUpdateAttributes(input); + return exerciseRepository.save(exercise); + } + + @PutMapping("/api/exercises/{exerciseId}/tags") + @PreAuthorize("isExercisePlanner(#exerciseId)") + public Exercise updateExerciseTags(@PathVariable String exerciseId, + @Valid @RequestBody ExerciseUpdateTagsInput input) { + Exercise exercise = exerciseRepository.findById(exerciseId).orElseThrow(); + exercise.setTags(fromIterable(tagRepository.findAllById(input.getTagIds()))); + return exerciseRepository.save(exercise); + } + + @PutMapping("/api/exercises/{exerciseId}/logos") + @PreAuthorize("isExercisePlanner(#exerciseId)") + public Exercise updateExerciseLogos(@PathVariable String exerciseId, + @Valid @RequestBody ExerciseUpdateLogoInput input) { + Exercise exercise = exerciseRepository.findById(exerciseId).orElseThrow(); + exercise.setLogoDark(documentRepository.findById(input.getLogoDark()).orElse(null)); + exercise.setLogoLight(documentRepository.findById(input.getLogoLight()).orElse(null)); + return exerciseRepository.save(exercise); + } + + @PutMapping("/api/exercises/{exerciseId}/lessons") + @PreAuthorize("isExercisePlanner(#exerciseId)") + public Exercise updateExerciseLessons(@PathVariable String exerciseId, + @Valid @RequestBody ExerciseLessonsInput input) { + Exercise exercise = exerciseRepository.findById(exerciseId).orElseThrow(); + exercise.setLessonsAnonymized(input.getLessonsAnonymized()); + return exerciseRepository.save(exercise); + } + + @DeleteMapping("/api/exercises/{exerciseId}") + @PreAuthorize("isExercisePlanner(#exerciseId)") + public void deleteExercise(@PathVariable String exerciseId) { + exerciseRepository.deleteById(exerciseId); + } + + @GetMapping("/api/exercises/{exerciseId}") + @PreAuthorize("isExerciseObserver(#exerciseId)") + public Exercise exercise(@PathVariable String exerciseId) { + return exerciseRepository.findById(exerciseId).orElseThrow(); + } + + @Transactional(rollbackOn = Exception.class) + @DeleteMapping("/api/exercises/{exerciseId}/{documentId}") + @PreAuthorize("isExercisePlanner(#exerciseId)") + public Exercise deleteDocument(@PathVariable String exerciseId, @PathVariable String documentId) { + Exercise exercise = exerciseRepository.findById(exerciseId).orElseThrow(); + exercise.setUpdatedAt(now()); + Document doc = documentRepository.findById(documentId).orElseThrow(); + List docExercises = doc.getExercises().stream().filter(ex -> !ex.getId().equals(exerciseId)).toList(); + if (docExercises.isEmpty()) { + // Document is no longer associate to any exercise, delete it + documentRepository.delete(doc); + // All associations with this document will be automatically cleanup. + } else { + // Document associated to other exercise, cleanup + doc.setExercises(docExercises); + documentRepository.save(doc); + // Delete document from all exercise injects + injectService.cleanInjectsDocExercise(exerciseId, documentId); + } + return exerciseRepository.save(exercise); + } + + @Transactional(rollbackOn = Exception.class) + @PutMapping("/api/exercises/{exerciseId}/status") + @PreAuthorize("isExercisePlanner(#exerciseId)") + public Exercise changeExerciseStatus(@PathVariable String exerciseId, + @Valid @RequestBody ExerciseUpdateStatusInput input) { + STATUS status = input.getStatus(); + Exercise exercise = exerciseRepository.findById(exerciseId).orElseThrow(); + // Check if next status is possible + List nextPossibleStatus = exercise.nextPossibleStatus(); + if (!nextPossibleStatus.contains(status)) { + throw new UnsupportedOperationException("Exercise cant support moving to status " + status.name()); + } + // In case of rescheduled of an exercise. + boolean isCloseState = CANCELED.equals(exercise.getStatus()) || FINISHED.equals(exercise.getStatus()); + if (isCloseState && SCHEDULED.equals(status)) { + exercise.setStart(null); + exercise.setEnd(null); + // Reset pauses + exercise.setCurrentPause(null); + pauseRepository.deleteAll(pauseRepository.findAllForExercise(exerciseId)); + // Reset injects outcome, communications and expectations + injectRepository.saveAll(injectRepository.findAllForExercise(exerciseId).stream().peek(Inject::clean).toList()); + // Reset lessons learned answers + List lessonsAnswers = lessonsCategoryRepository.findAll( + LessonsCategorySpecification.fromExercise(exerciseId)).stream().flatMap( + lessonsCategory -> lessonsQuestionRepository.findAll( + LessonsQuestionSpecification.fromCategory(lessonsCategory.getId())).stream().flatMap( + lessonsQuestion -> lessonsAnswerRepository.findAll( + LessonsAnswerSpecification.fromQuestion(lessonsQuestion.getId())).stream())).toList(); + lessonsAnswerRepository.deleteAll(lessonsAnswers); + // Delete exercise transient files (communications, ...) + fileService.deleteDirectory(exerciseId); + } + // In case of manual start + if (SCHEDULED.equals(exercise.getStatus()) && RUNNING.equals(status)) { + Instant nextMinute = now().truncatedTo(MINUTES).plus(1, MINUTES); + exercise.setStart(nextMinute); + } + // If exercise move from pause to running state, + // we log the pause date to be able to recompute inject dates. + if (PAUSED.equals(exercise.getStatus()) && RUNNING.equals(status)) { + Instant lastPause = exercise.getCurrentPause().orElseThrow(); + exercise.setCurrentPause(null); + Pause pause = new Pause(); + pause.setDate(lastPause); + pause.setExercise(exercise); + pause.setDuration(between(lastPause, now()).getSeconds()); + pauseRepository.save(pause); + } + // If pause is asked, just set the pause date. + if (RUNNING.equals(exercise.getStatus()) && PAUSED.equals(status)) { + exercise.setCurrentPause(Instant.now()); + } + // Cancelation + if (RUNNING.equals(exercise.getStatus()) && CANCELED.equals(status)) { + exercise.setEnd(now()); + } + exercise.setUpdatedAt(now()); + exercise.setStatus(status); + return exerciseRepository.save(exercise); + } + + @GetMapping("/api/exercises") + @Secured(ROLE_USER) + public List exercises() { + Iterable exercises = currentUser().isAdmin() ? exerciseRepository.findAll() + : exerciseRepository.findAllGranted(currentUser().getId()); + return fromIterable(exercises).stream().map(ExerciseSimple::fromExercise).toList(); + } + // endregion + + // region communication + @GetMapping("/api/exercises/{exerciseId}/communications") + @PreAuthorize("isExerciseObserver(#exerciseId)") + public Iterable exerciseCommunications(@PathVariable String exerciseId) { + Exercise exercise = exerciseRepository.findById(exerciseId).orElseThrow(); + List communications = new ArrayList<>(); + exercise.getInjects().forEach(injectDoc -> communications.addAll(injectDoc.getCommunications())); + return communications; + } + + @GetMapping("/api/communications/attachment") + // @PreAuthorize("isExerciseObserver(#exerciseId)") + public void downloadAttachment(@RequestParam String file, HttpServletResponse response) throws IOException { + FileContainer fileContainer = fileService.getFileContainer(file).orElseThrow(); + response.addHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + fileContainer.getName()); + response.addHeader(HttpHeaders.CONTENT_TYPE, fileContainer.getContentType()); + response.setStatus(HttpServletResponse.SC_OK); + fileContainer.getInputStream().transferTo(response.getOutputStream()); + } + // endregion + + // region import/export + @GetMapping("/api/exercises/{exerciseId}/export") + @PreAuthorize("isExerciseObserver(#exerciseId)") + public void exerciseExport(@NotBlank @PathVariable final String exerciseId, + @RequestParam(required = false) final boolean isWithPlayers, + @RequestParam(required = false) final boolean isWithVariableValues, HttpServletResponse response) + throws IOException { + // Setup the mapper for export + List documentIds = new ArrayList<>(); + ObjectMapper objectMapper = mapper.copy(); + if (!isWithPlayers) { + objectMapper.addMixIn(ExerciseFileExport.class, ExerciseExportMixins.ExerciseFileExport.class); + } + // Start exporting exercise + ExerciseFileExport importExport = new ExerciseFileExport(); + importExport.setVersion(1); + Exercise exercise = exerciseRepository.findById(exerciseId).orElseThrow(); + objectMapper.addMixIn(Exercise.class, ExerciseExportMixins.Exercise.class); + // Build the export + importExport.setExercise(exercise); + importExport.setDocuments(exercise.getDocuments()); + documentIds.addAll(exercise.getDocuments().stream().map(Document::getId).toList()); + objectMapper.addMixIn(Document.class, ExerciseExportMixins.Document.class); + List exerciseTags = new ArrayList<>(exercise.getTags()); + // Objectives + List objectives = exercise.getObjectives(); + importExport.setObjectives(objectives); + objectMapper.addMixIn(Objective.class, ExerciseExportMixins.Objective.class); + // Lessons categories + List lessonsCategories = exercise.getLessonsCategories(); + importExport.setLessonsCategories(lessonsCategories); + objectMapper.addMixIn(LessonsCategory.class, ExerciseExportMixins.LessonsCategory.class); + // Lessons questions + List lessonsQuestions = lessonsCategories.stream() + .flatMap(category -> category.getQuestions().stream()).toList(); + importExport.setLessonsQuestions(lessonsQuestions); + objectMapper.addMixIn(LessonsQuestion.class, ExerciseExportMixins.LessonsQuestion.class); + // Teams + List teams = exercise.getTeams(); + importExport.setTeams(teams); + objectMapper.addMixIn(Team.class, + isWithPlayers ? ExerciseExportMixins.Team.class : ExerciseExportMixins.EmptyTeam.class); + exerciseTags.addAll(teams.stream().flatMap(team -> team.getTags().stream()).toList()); + if (isWithPlayers) { + // players + List players = teams.stream().flatMap(team -> team.getUsers().stream()).distinct().toList(); + exerciseTags.addAll(players.stream().flatMap(user -> user.getTags().stream()).toList()); + importExport.setUsers(players); + objectMapper.addMixIn(User.class, ExerciseExportMixins.User.class); + // organizations + List organizations = players.stream().map(User::getOrganization).filter(Objects::nonNull).toList(); + exerciseTags.addAll(organizations.stream().flatMap(org -> org.getTags().stream()).toList()); + importExport.setOrganizations(organizations); + objectMapper.addMixIn(Organization.class, ExerciseExportMixins.Organization.class); + } + // Injects + List injects = exercise.getInjects(); + exerciseTags.addAll(injects.stream().flatMap(inject -> inject.getTags().stream()).toList()); + importExport.setInjects(injects); + objectMapper.addMixIn(Inject.class, ExerciseExportMixins.Inject.class); + // Documents + exerciseTags.addAll(exercise.getDocuments().stream().flatMap(doc -> doc.getTags().stream()).toList()); + // Articles / Channels + List
articles = exercise.getArticles(); + importExport.setArticles(articles); + objectMapper.addMixIn(Article.class, ExerciseExportMixins.Article.class); + List channels = articles.stream().map(Article::getChannel).distinct().toList(); + documentIds.addAll(channels.stream().flatMap(channel -> channel.getLogos().stream()).map(Document::getId).toList()); + importExport.setChannels(channels); + objectMapper.addMixIn(Channel.class, ExerciseExportMixins.Channel.class); + // Challenges + List challenges = fromIterable(challengeService.getExerciseChallenges(exerciseId)); + importExport.setChallenges(challenges); + documentIds.addAll( + challenges.stream().flatMap(challenge -> challenge.getDocuments().stream()).map(Document::getId).toList()); + objectMapper.addMixIn(Challenge.class, ExerciseExportMixins.Challenge.class); + exerciseTags.addAll(challenges.stream().flatMap(challenge -> challenge.getTags().stream()).toList()); + // Tags + importExport.setTags(exerciseTags.stream().distinct().toList()); + objectMapper.addMixIn(Tag.class, ExerciseExportMixins.Tag.class); + // -- Variables -- + List variables = this.variableService.variables(exerciseId); + importExport.setVariables(variables); + if (isWithVariableValues) { + objectMapper.addMixIn(Variable.class, VariableWithValueMixin.class); + } else { + objectMapper.addMixIn(Variable.class, VariableMixin.class); + } + // Build the response + String infos = + "(" + (isWithPlayers ? "with_players" : "no_players") + " & " + (isWithVariableValues ? "with_variable_values" + : "no_variable_values") + ")"; + String zipName = (exercise.getName() + "_" + now().toString()) + "_" + infos + ".zip"; + response.addHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + zipName); + response.addHeader(HttpHeaders.CONTENT_TYPE, "application/zip"); + response.setStatus(HttpServletResponse.SC_OK); + ZipOutputStream zipExport = new ZipOutputStream(response.getOutputStream()); + ZipEntry zipEntry = new ZipEntry(exercise.getName() + ".json"); + zipEntry.setComment(EXPORT_ENTRY_EXERCISE); + zipExport.putNextEntry(zipEntry); + zipExport.write(objectMapper.writerWithDefaultPrettyPrinter().writeValueAsBytes(importExport)); + zipExport.closeEntry(); + // Add the documents + documentIds.stream().distinct().forEach(docId -> { + Document doc = documentRepository.findById(docId).orElseThrow(); + Optional docStream = fileService.getFile(doc); + if (docStream.isPresent()) { + try { + ZipEntry zipDoc = new ZipEntry(doc.getTarget()); + zipDoc.setComment(EXPORT_ENTRY_ATTACHMENT); + byte[] data = docStream.get().readAllBytes(); + zipExport.putNextEntry(zipDoc); + zipExport.write(data); + zipExport.closeEntry(); + } catch (IOException e) { + LOGGER.log(Level.SEVERE, e.getMessage(), e); } - // Cancelation - if (RUNNING.equals(exercise.getStatus()) && CANCELED.equals(status)) { - exercise.setEnd(now()); - } - exercise.setUpdatedAt(now()); - exercise.setStatus(status); - return exerciseRepository.save(exercise); - } - - @GetMapping("/api/exercises") - @RolesAllowed(ROLE_USER) - public List exercises() { - Iterable exercises = currentUser().isAdmin() ? exerciseRepository.findAll() : exerciseRepository.findAllGranted(currentUser().getId()); - return fromIterable(exercises).stream().map(ExerciseSimple::fromExercise).toList(); - } - // endregion - - // region communication - @GetMapping("/api/exercises/{exerciseId}/communications") - @PreAuthorize("isExerciseObserver(#exerciseId)") - public Iterable exerciseCommunications(@PathVariable String exerciseId) { - Exercise exercise = exerciseRepository.findById(exerciseId).orElseThrow(); - List communications = new ArrayList<>(); - exercise.getInjects().forEach(injectDoc -> communications.addAll(injectDoc.getCommunications())); - return communications; - } - - @GetMapping("/api/communications/attachment") - // @PreAuthorize("isExerciseObserver(#exerciseId)") - public void downloadAttachment(@RequestParam String file, HttpServletResponse response) throws IOException { - FileContainer fileContainer = fileService.getFileContainer(file).orElseThrow(); - response.addHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + fileContainer.getName()); - response.addHeader(HttpHeaders.CONTENT_TYPE, fileContainer.getContentType()); - response.setStatus(HttpServletResponse.SC_OK); - fileContainer.getInputStream().transferTo(response.getOutputStream()); - } - // endregion - - // region import/export - @GetMapping("/api/exercises/{exerciseId}/export") - @PreAuthorize("isExerciseObserver(#exerciseId)") - public void exerciseExport(@NotBlank @PathVariable final String exerciseId, @RequestParam(required = false) final boolean isWithPlayers, @RequestParam(required = false) final boolean isWithVariableValues, HttpServletResponse response) throws IOException { - // Setup the mapper for export - List documentIds = new ArrayList<>(); - ObjectMapper objectMapper = mapper.copy(); - if (!isWithPlayers) { - objectMapper.addMixIn(ExerciseFileExport.class, ExerciseExportMixins.ExerciseFileExport.class); - } - // Start exporting exercise - ExerciseFileExport importExport = new ExerciseFileExport(); - importExport.setVersion(1); - Exercise exercise = exerciseRepository.findById(exerciseId).orElseThrow(); - objectMapper.addMixIn(Exercise.class, ExerciseExportMixins.Exercise.class); - // Build the export - importExport.setExercise(exercise); - importExport.setDocuments(exercise.getDocuments()); - documentIds.addAll(exercise.getDocuments().stream().map(Document::getId).toList()); - objectMapper.addMixIn(Document.class, ExerciseExportMixins.Document.class); - List exerciseTags = new ArrayList<>(exercise.getTags()); - // Objectives - List objectives = exercise.getObjectives(); - importExport.setObjectives(objectives); - objectMapper.addMixIn(Objective.class, ExerciseExportMixins.Objective.class); - // Lessons categories - List lessonsCategories = exercise.getLessonsCategories(); - importExport.setLessonsCategories(lessonsCategories); - objectMapper.addMixIn(LessonsCategory.class, ExerciseExportMixins.LessonsCategory.class); - // Lessons questions - List lessonsQuestions = lessonsCategories.stream().flatMap(category -> category.getQuestions().stream()).toList(); - importExport.setLessonsQuestions(lessonsQuestions); - objectMapper.addMixIn(LessonsQuestion.class, ExerciseExportMixins.LessonsQuestion.class); - // Teams - List teams = exercise.getTeams(); - importExport.setTeams(teams); - objectMapper.addMixIn(Team.class, isWithPlayers ? ExerciseExportMixins.Team.class : ExerciseExportMixins.EmptyTeam.class); - exerciseTags.addAll(teams.stream().flatMap(team -> team.getTags().stream()).toList()); - if (isWithPlayers) { - // players - List players = teams.stream().flatMap(team -> team.getUsers().stream()).distinct().toList(); - exerciseTags.addAll(players.stream().flatMap(user -> user.getTags().stream()).toList()); - importExport.setUsers(players); - objectMapper.addMixIn(User.class, ExerciseExportMixins.User.class); - // organizations - List organizations = players.stream().map(User::getOrganization).filter(Objects::nonNull).toList(); - exerciseTags.addAll(organizations.stream().flatMap(org -> org.getTags().stream()).toList()); - importExport.setOrganizations(organizations); - objectMapper.addMixIn(Organization.class, ExerciseExportMixins.Organization.class); - } - // Injects - List injects = exercise.getInjects(); - exerciseTags.addAll(injects.stream().flatMap(inject -> inject.getTags().stream()).toList()); - importExport.setInjects(injects); - objectMapper.addMixIn(Inject.class, ExerciseExportMixins.Inject.class); - // Documents - exerciseTags.addAll(exercise.getDocuments().stream().flatMap(doc -> doc.getTags().stream()).toList()); - // Articles / Channels - List
articles = exercise.getArticles(); - importExport.setArticles(articles); - objectMapper.addMixIn(Article.class, ExerciseExportMixins.Article.class); - List channels = articles.stream().map(Article::getChannel).distinct().toList(); - documentIds.addAll(channels.stream().flatMap(channel -> channel.getLogos().stream()).map(Document::getId).toList()); - importExport.setChannels(channels); - objectMapper.addMixIn(Channel.class, ExerciseExportMixins.Channel.class); - // Challenges - List challenges = fromIterable(challengeService.getExerciseChallenges(exerciseId)); - importExport.setChallenges(challenges); - documentIds.addAll(challenges.stream().flatMap(challenge -> challenge.getDocuments().stream()).map(Document::getId).toList()); - objectMapper.addMixIn(Challenge.class, ExerciseExportMixins.Challenge.class); - exerciseTags.addAll(challenges.stream().flatMap(challenge -> challenge.getTags().stream()).toList()); - // Tags - importExport.setTags(exerciseTags.stream().distinct().toList()); - objectMapper.addMixIn(Tag.class, ExerciseExportMixins.Tag.class); - // -- Variables -- - List variables = this.variableService.variables(exerciseId); - importExport.setVariables(variables); - if (isWithVariableValues) { - objectMapper.addMixIn(Variable.class, VariableWithValueMixin.class); - } else { - objectMapper.addMixIn(Variable.class, VariableMixin.class); - } - // Build the response - String infos = "(" + (isWithPlayers ? "with_players" : "no_players") + " & " + (isWithVariableValues ? "with_variable_values" : "no_variable_values") + ")"; - String zipName = (exercise.getName() + "_" + now().toString()) + "_" + infos + ".zip"; - response.addHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + zipName); - response.addHeader(HttpHeaders.CONTENT_TYPE, "application/zip"); - response.setStatus(HttpServletResponse.SC_OK); - ZipOutputStream zipExport = new ZipOutputStream(response.getOutputStream()); - ZipEntry zipEntry = new ZipEntry(exercise.getName() + ".json"); - zipEntry.setComment(EXPORT_ENTRY_EXERCISE); - zipExport.putNextEntry(zipEntry); - zipExport.write(objectMapper.writerWithDefaultPrettyPrinter().writeValueAsBytes(importExport)); - zipExport.closeEntry(); - // Add the documents - documentIds.stream().distinct().forEach(docId -> { - Document doc = documentRepository.findById(docId).orElseThrow(); - Optional docStream = fileService.getFile(doc); - if (docStream.isPresent()) { - try { - ZipEntry zipDoc = new ZipEntry(doc.getTarget()); - zipDoc.setComment(EXPORT_ENTRY_ATTACHMENT); - byte[] data = docStream.get().readAllBytes(); - zipExport.putNextEntry(zipDoc); - zipExport.write(data); - zipExport.closeEntry(); - } catch (IOException e) { - LOGGER.log(Level.SEVERE, e.getMessage(), e); - } - } - }); - zipExport.finish(); - zipExport.close(); - } - - @PostMapping("/api/exercises/import") - @RolesAllowed(ROLE_ADMIN) - public void exerciseImport(@RequestPart("file") MultipartFile file) throws Exception { - importService.handleFileImport(file); - } - - @GetMapping("/api/player/exercises/{exerciseId}") - public PublicExercise playerExercise(@PathVariable String exerciseId, @RequestParam Optional userId) { - impersonateUser(userRepository, userId); // TODO Check Security - Exercise exercise = exerciseRepository.findById(exerciseId).orElseThrow(); - return new PublicExercise(exercise); - } - // endregion + } + }); + zipExport.finish(); + zipExport.close(); + } + + @PostMapping("/api/exercises/import") + @Secured(ROLE_ADMIN) + public void exerciseImport(@RequestPart("file") MultipartFile file) throws Exception { + importService.handleFileImport(file); + } + + @GetMapping("/api/player/exercises/{exerciseId}") + public PublicExercise playerExercise(@PathVariable String exerciseId, @RequestParam Optional userId) { + impersonateUser(userRepository, userId); // TODO Check Security + Exercise exercise = exerciseRepository.findById(exerciseId).orElseThrow(); + return new PublicExercise(exercise); + } + // endregion } diff --git a/openex-api/src/main/java/io/openex/rest/exercise/ExerciseExpectationApi.java b/openex-api/src/main/java/io/openex/rest/exercise/ExerciseExpectationApi.java index 40ab990875..b0da1a6d61 100644 --- a/openex-api/src/main/java/io/openex/rest/exercise/ExerciseExpectationApi.java +++ b/openex-api/src/main/java/io/openex/rest/exercise/ExerciseExpectationApi.java @@ -8,8 +8,8 @@ import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; -import javax.validation.Valid; -import javax.validation.constraints.NotBlank; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; import java.util.List; @RequiredArgsConstructor diff --git a/openex-api/src/main/java/io/openex/rest/exercise/exports/VariableWithValueMixin.java b/openex-api/src/main/java/io/openex/rest/exercise/exports/VariableWithValueMixin.java index a889354ceb..fb41623554 100644 --- a/openex-api/src/main/java/io/openex/rest/exercise/exports/VariableWithValueMixin.java +++ b/openex-api/src/main/java/io/openex/rest/exercise/exports/VariableWithValueMixin.java @@ -4,7 +4,7 @@ import com.fasterxml.jackson.databind.JsonNode; import io.openex.database.model.Variable; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import static io.openex.rest.exercise.exports.VariableMixin.*; import static io.openex.rest.exercise.exports.VariableWithValueMixin.VARIABLE_VALUE; diff --git a/openex-api/src/main/java/io/openex/rest/exercise/form/DryrunCreateInput.java b/openex-api/src/main/java/io/openex/rest/exercise/form/DryrunCreateInput.java index 1f168da1a6..977c9a67ab 100644 --- a/openex-api/src/main/java/io/openex/rest/exercise/form/DryrunCreateInput.java +++ b/openex-api/src/main/java/io/openex/rest/exercise/form/DryrunCreateInput.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; import java.util.ArrayList; import java.util.List; diff --git a/openex-api/src/main/java/io/openex/rest/exercise/form/ExerciseCreateInput.java b/openex-api/src/main/java/io/openex/rest/exercise/form/ExerciseCreateInput.java index 97e1fb59a8..66203ca5a4 100644 --- a/openex-api/src/main/java/io/openex/rest/exercise/form/ExerciseCreateInput.java +++ b/openex-api/src/main/java/io/openex/rest/exercise/form/ExerciseCreateInput.java @@ -2,8 +2,8 @@ import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.FutureOrPresent; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.FutureOrPresent; +import jakarta.validation.constraints.NotBlank; import java.time.Instant; import java.time.temporal.ChronoUnit; import java.util.ArrayList; diff --git a/openex-api/src/main/java/io/openex/rest/exercise/form/ExerciseSimple.java b/openex-api/src/main/java/io/openex/rest/exercise/form/ExerciseSimple.java index 94ceb15b4c..78b611a393 100644 --- a/openex-api/src/main/java/io/openex/rest/exercise/form/ExerciseSimple.java +++ b/openex-api/src/main/java/io/openex/rest/exercise/form/ExerciseSimple.java @@ -7,8 +7,8 @@ import io.openex.helper.MultiIdDeserializer; import org.springframework.beans.BeanUtils; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; import java.time.Instant; import java.util.ArrayList; import java.util.List; diff --git a/openex-api/src/main/java/io/openex/rest/exercise/form/ExerciseTeamPlayersEnableInput.java b/openex-api/src/main/java/io/openex/rest/exercise/form/ExerciseTeamPlayersEnableInput.java index 1dabec3425..2eaad74813 100644 --- a/openex-api/src/main/java/io/openex/rest/exercise/form/ExerciseTeamPlayersEnableInput.java +++ b/openex-api/src/main/java/io/openex/rest/exercise/form/ExerciseTeamPlayersEnableInput.java @@ -2,12 +2,9 @@ import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.NotBlank; import java.util.ArrayList; import java.util.List; -import static io.openex.config.AppConfig.MANDATORY_MESSAGE; - public class ExerciseTeamPlayersEnableInput { @JsonProperty("exercise_team_players") private List playersIds = new ArrayList<>(); diff --git a/openex-api/src/main/java/io/openex/rest/exercise/form/ExerciseUpdateInput.java b/openex-api/src/main/java/io/openex/rest/exercise/form/ExerciseUpdateInput.java index db38897312..294d2fc12a 100644 --- a/openex-api/src/main/java/io/openex/rest/exercise/form/ExerciseUpdateInput.java +++ b/openex-api/src/main/java/io/openex/rest/exercise/form/ExerciseUpdateInput.java @@ -2,8 +2,8 @@ import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.Email; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotBlank; import static io.openex.config.AppConfig.*; diff --git a/openex-api/src/main/java/io/openex/rest/exercise/form/ExerciseUpdateStartDateInput.java b/openex-api/src/main/java/io/openex/rest/exercise/form/ExerciseUpdateStartDateInput.java index ef81b60b0f..eccdbd5741 100644 --- a/openex-api/src/main/java/io/openex/rest/exercise/form/ExerciseUpdateStartDateInput.java +++ b/openex-api/src/main/java/io/openex/rest/exercise/form/ExerciseUpdateStartDateInput.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.FutureOrPresent; +import jakarta.validation.constraints.FutureOrPresent; import java.time.Instant; import java.time.temporal.ChronoUnit; diff --git a/openex-api/src/main/java/io/openex/rest/exercise/form/ExpectationUpdateInput.java b/openex-api/src/main/java/io/openex/rest/exercise/form/ExpectationUpdateInput.java index 1720f3cabe..79cfc5b985 100644 --- a/openex-api/src/main/java/io/openex/rest/exercise/form/ExpectationUpdateInput.java +++ b/openex-api/src/main/java/io/openex/rest/exercise/form/ExpectationUpdateInput.java @@ -5,7 +5,7 @@ import lombok.Getter; import lombok.Setter; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; @Getter @Setter diff --git a/openex-api/src/main/java/io/openex/rest/group/GroupApi.java b/openex-api/src/main/java/io/openex/rest/group/GroupApi.java index d91ff499a8..9a99ba3d92 100644 --- a/openex-api/src/main/java/io/openex/rest/group/GroupApi.java +++ b/openex-api/src/main/java/io/openex/rest/group/GroupApi.java @@ -8,13 +8,13 @@ import io.openex.rest.group.form.GroupUpdateUsersInput; import io.openex.rest.group.form.OrganizationGrantInput; import io.openex.rest.helper.RestBehavior; +import jakarta.transaction.Transactional; +import jakarta.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationEventPublisher; +import org.springframework.security.access.annotation.Secured; import org.springframework.web.bind.annotation.*; -import javax.annotation.security.RolesAllowed; -import javax.transaction.Transactional; -import javax.validation.Valid; import java.util.Spliterator; import static io.openex.database.audit.ModelBaseListener.DATA_UPDATE; @@ -25,7 +25,7 @@ import static java.util.stream.StreamSupport.stream; @RestController -@RolesAllowed(ROLE_USER) +@Secured(ROLE_USER) public class GroupApi extends RestBehavior { private ExerciseRepository exerciseRepository; @@ -75,7 +75,7 @@ public Group group(@PathVariable String groupId) { return groupRepository.findById(groupId).orElseThrow(); } - @RolesAllowed(ROLE_ADMIN) + @Secured(ROLE_ADMIN) @PostMapping("/api/groups") public Group createGroup(@Valid @RequestBody GroupCreateInput input) { Group group = new Group(); @@ -84,7 +84,7 @@ public Group createGroup(@Valid @RequestBody GroupCreateInput input) { return groupRepository.save(group); } - @RolesAllowed(ROLE_ADMIN) + @Secured(ROLE_ADMIN) @PutMapping("/api/groups/{groupId}/users") public Group updateGroupUsers(@PathVariable String groupId, @Valid @RequestBody GroupUpdateUsersInput input) { @@ -99,7 +99,7 @@ public Group updateGroupUsers(@PathVariable String groupId, return savedGroup; } - @RolesAllowed(ROLE_ADMIN) + @Secured(ROLE_ADMIN) @PutMapping("/api/groups/{groupId}/information") public Group updateGroupInformation(@PathVariable String groupId, @Valid @RequestBody GroupCreateInput input) { @@ -110,7 +110,7 @@ public Group updateGroupInformation(@PathVariable String groupId, } @Transactional(rollbackOn = Exception.class) - @RolesAllowed(ROLE_ADMIN) + @Secured(ROLE_ADMIN) @PostMapping("/api/groups/{groupId}/grants") public Grant groupGrant(@PathVariable String groupId, @Valid @RequestBody GroupGrantInput input) { // Resolve dependencies @@ -129,7 +129,7 @@ public Grant groupGrant(@PathVariable String groupId, @Valid @RequestBody GroupG } @Transactional(rollbackOn = Exception.class) - @RolesAllowed(ROLE_ADMIN) + @Secured(ROLE_ADMIN) @PostMapping("/api/groups/{groupId}/organizations") public Group groupOrganization(@PathVariable String groupId, @Valid @RequestBody OrganizationGrantInput input) { // Resolve dependencies @@ -139,7 +139,7 @@ public Group groupOrganization(@PathVariable String groupId, @Valid @RequestBody return groupRepository.save(group); } - @RolesAllowed(ROLE_ADMIN) + @Secured(ROLE_ADMIN) @DeleteMapping("/api/groups/{groupId}/organizations/{organizationId}") public Group deleteGroupOrganization(@PathVariable String groupId, @PathVariable String organizationId) { Group group = groupRepository.findById(groupId).orElseThrow(); @@ -148,13 +148,13 @@ public Group deleteGroupOrganization(@PathVariable String groupId, @PathVariable return groupRepository.save(group); } - @RolesAllowed(ROLE_ADMIN) + @Secured(ROLE_ADMIN) @DeleteMapping("/api/grants/{grantId}") public void deleteGrant(@PathVariable String grantId) { grantRepository.deleteById(grantId); } - @RolesAllowed(ROLE_ADMIN) + @Secured(ROLE_ADMIN) @DeleteMapping("/api/groups/{groupId}") public void deleteGroup(@PathVariable String groupId) { groupRepository.deleteById(groupId); diff --git a/openex-api/src/main/java/io/openex/rest/group/form/GroupCreateInput.java b/openex-api/src/main/java/io/openex/rest/group/form/GroupCreateInput.java index 7a5575bacf..0cb07fed91 100644 --- a/openex-api/src/main/java/io/openex/rest/group/form/GroupCreateInput.java +++ b/openex-api/src/main/java/io/openex/rest/group/form/GroupCreateInput.java @@ -4,7 +4,7 @@ import io.openex.database.model.Grant; import lombok.Getter; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; import java.util.ArrayList; import java.util.List; diff --git a/openex-api/src/main/java/io/openex/rest/group/form/GroupGrantInput.java b/openex-api/src/main/java/io/openex/rest/group/form/GroupGrantInput.java index 46501e9af5..b6154562ce 100644 --- a/openex-api/src/main/java/io/openex/rest/group/form/GroupGrantInput.java +++ b/openex-api/src/main/java/io/openex/rest/group/form/GroupGrantInput.java @@ -3,7 +3,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import io.openex.database.model.Grant; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; import static io.openex.config.AppConfig.MANDATORY_MESSAGE; diff --git a/openex-api/src/main/java/io/openex/rest/group/form/OrganizationGrantInput.java b/openex-api/src/main/java/io/openex/rest/group/form/OrganizationGrantInput.java index b297944ad0..ea325a9283 100644 --- a/openex-api/src/main/java/io/openex/rest/group/form/OrganizationGrantInput.java +++ b/openex-api/src/main/java/io/openex/rest/group/form/OrganizationGrantInput.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; import static io.openex.config.AppConfig.MANDATORY_MESSAGE; diff --git a/openex-api/src/main/java/io/openex/rest/helper/RestBehavior.java b/openex-api/src/main/java/io/openex/rest/helper/RestBehavior.java index ef8dd6e608..a07607f86c 100644 --- a/openex-api/src/main/java/io/openex/rest/helper/RestBehavior.java +++ b/openex-api/src/main/java/io/openex/rest/helper/RestBehavior.java @@ -18,7 +18,7 @@ import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; -import javax.annotation.Resource; +import jakarta.annotation.Resource; import java.util.*; import java.util.stream.Collectors; diff --git a/openex-api/src/main/java/io/openex/rest/inject/InjectApi.java b/openex-api/src/main/java/io/openex/rest/inject/InjectApi.java index e3dfcb28f0..ed5306118b 100644 --- a/openex-api/src/main/java/io/openex/rest/inject/InjectApi.java +++ b/openex-api/src/main/java/io/openex/rest/inject/InjectApi.java @@ -18,9 +18,9 @@ import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; -import javax.transaction.Transactional; -import javax.validation.Valid; -import javax.validation.constraints.NotNull; +import jakarta.transaction.Transactional; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; import java.util.Collection; import java.util.List; import java.util.Optional; diff --git a/openex-api/src/main/java/io/openex/rest/kill_chain_phase/KillChainPhaseApi.java b/openex-api/src/main/java/io/openex/rest/kill_chain_phase/KillChainPhaseApi.java index e3817ae11e..ec9acab69e 100644 --- a/openex-api/src/main/java/io/openex/rest/kill_chain_phase/KillChainPhaseApi.java +++ b/openex-api/src/main/java/io/openex/rest/kill_chain_phase/KillChainPhaseApi.java @@ -5,16 +5,16 @@ import io.openex.rest.helper.RestBehavior; import io.openex.rest.kill_chain_phase.form.KillChainPhaseCreateInput; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.annotation.Secured; import org.springframework.web.bind.annotation.*; -import javax.annotation.security.RolesAllowed; -import javax.validation.Valid; +import jakarta.validation.Valid; import static io.openex.database.model.User.ROLE_ADMIN; import static io.openex.database.model.User.ROLE_USER; @RestController -@RolesAllowed(ROLE_USER) +@Secured(ROLE_USER) public class KillChainPhaseApi extends RestBehavior { private KillChainPhaseRepository killChainPhaseRepository; @@ -34,7 +34,7 @@ public KillChainPhase killChainPhase(@PathVariable String killChainPhaseId) { return killChainPhaseRepository.findById(killChainPhaseId).orElseThrow(); } - @RolesAllowed(ROLE_ADMIN) + @Secured(ROLE_ADMIN) @PostMapping("/api/kill_chain_phases") public KillChainPhase createKillChainPhase(@Valid @RequestBody KillChainPhaseCreateInput input) { KillChainPhase killChainPhase = new KillChainPhase(); @@ -42,7 +42,7 @@ public KillChainPhase createKillChainPhase(@Valid @RequestBody KillChainPhaseCre return killChainPhaseRepository.save(killChainPhase); } - @RolesAllowed(ROLE_ADMIN) + @Secured(ROLE_ADMIN) @DeleteMapping("/api/kill_chain_phases/{killChainPhaseId}") public void deleteKillChainPhase(@PathVariable String killChainPhaseId) { killChainPhaseRepository.deleteById(killChainPhaseId); diff --git a/openex-api/src/main/java/io/openex/rest/kill_chain_phase/form/KillChainPhaseCreateInput.java b/openex-api/src/main/java/io/openex/rest/kill_chain_phase/form/KillChainPhaseCreateInput.java index 904096778a..0bf817ee3f 100644 --- a/openex-api/src/main/java/io/openex/rest/kill_chain_phase/form/KillChainPhaseCreateInput.java +++ b/openex-api/src/main/java/io/openex/rest/kill_chain_phase/form/KillChainPhaseCreateInput.java @@ -3,7 +3,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Getter; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; import static io.openex.config.AppConfig.MANDATORY_MESSAGE; @@ -43,4 +43,4 @@ public Long getOrder() { public void setOrder(Long order) { this.order = order; } -} \ No newline at end of file +} diff --git a/openex-api/src/main/java/io/openex/rest/lessons/LessonsApi.java b/openex-api/src/main/java/io/openex/rest/lessons/LessonsApi.java index 084e5f38f8..db112c9f8d 100644 --- a/openex-api/src/main/java/io/openex/rest/lessons/LessonsApi.java +++ b/openex-api/src/main/java/io/openex/rest/lessons/LessonsApi.java @@ -12,7 +12,7 @@ import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; -import javax.validation.Valid; +import jakarta.validation.Valid; import java.util.List; import java.util.Optional; diff --git a/openex-api/src/main/java/io/openex/rest/lessons/form/LessonsCategoryCreateInput.java b/openex-api/src/main/java/io/openex/rest/lessons/form/LessonsCategoryCreateInput.java index c351eacb0b..da958da214 100644 --- a/openex-api/src/main/java/io/openex/rest/lessons/form/LessonsCategoryCreateInput.java +++ b/openex-api/src/main/java/io/openex/rest/lessons/form/LessonsCategoryCreateInput.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; import static io.openex.config.AppConfig.MANDATORY_MESSAGE; diff --git a/openex-api/src/main/java/io/openex/rest/lessons/form/LessonsCategoryUpdateInput.java b/openex-api/src/main/java/io/openex/rest/lessons/form/LessonsCategoryUpdateInput.java index ed4ea5ccb9..1ca7cde9a2 100644 --- a/openex-api/src/main/java/io/openex/rest/lessons/form/LessonsCategoryUpdateInput.java +++ b/openex-api/src/main/java/io/openex/rest/lessons/form/LessonsCategoryUpdateInput.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; import static io.openex.config.AppConfig.MANDATORY_MESSAGE; diff --git a/openex-api/src/main/java/io/openex/rest/lessons/form/LessonsQuestionCreateInput.java b/openex-api/src/main/java/io/openex/rest/lessons/form/LessonsQuestionCreateInput.java index 8083fb26aa..f1aa94b39a 100644 --- a/openex-api/src/main/java/io/openex/rest/lessons/form/LessonsQuestionCreateInput.java +++ b/openex-api/src/main/java/io/openex/rest/lessons/form/LessonsQuestionCreateInput.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; import static io.openex.config.AppConfig.MANDATORY_MESSAGE; @@ -41,4 +41,4 @@ public int getOrder() { public void setOrder(int order) { this.order = order; } -} \ No newline at end of file +} diff --git a/openex-api/src/main/java/io/openex/rest/lessons/form/LessonsQuestionUpdateInput.java b/openex-api/src/main/java/io/openex/rest/lessons/form/LessonsQuestionUpdateInput.java index 62685dc8d5..394ae4efc0 100644 --- a/openex-api/src/main/java/io/openex/rest/lessons/form/LessonsQuestionUpdateInput.java +++ b/openex-api/src/main/java/io/openex/rest/lessons/form/LessonsQuestionUpdateInput.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; import static io.openex.config.AppConfig.MANDATORY_MESSAGE; diff --git a/openex-api/src/main/java/io/openex/rest/lessons_template/LessonsTemplateApi.java b/openex-api/src/main/java/io/openex/rest/lessons_template/LessonsTemplateApi.java index b8718d6fb4..10893cf87e 100644 --- a/openex-api/src/main/java/io/openex/rest/lessons_template/LessonsTemplateApi.java +++ b/openex-api/src/main/java/io/openex/rest/lessons_template/LessonsTemplateApi.java @@ -10,12 +10,11 @@ import io.openex.database.specification.LessonsTemplateQuestionSpecification; import io.openex.rest.helper.RestBehavior; import io.openex.rest.lessons_template.form.*; +import jakarta.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.annotation.Secured; import org.springframework.web.bind.annotation.*; -import javax.annotation.security.RolesAllowed; -import javax.validation.Valid; - import static io.openex.database.model.User.ROLE_ADMIN; import static io.openex.helper.StreamHelper.fromIterable; import static java.time.Instant.now; @@ -47,7 +46,7 @@ public Iterable lessonsTemplates() { return fromIterable(lessonsTemplateRepository.findAll()).stream().toList(); } - @RolesAllowed(ROLE_ADMIN) + @Secured(ROLE_ADMIN) @PostMapping("/api/lessons_templates") public LessonsTemplate createLessonsTemplate(@Valid @RequestBody LessonsTemplateCreateInput input) { LessonsTemplate lessonsTemplate = new LessonsTemplate(); @@ -55,7 +54,7 @@ public LessonsTemplate createLessonsTemplate(@Valid @RequestBody LessonsTemplate return lessonsTemplateRepository.save(lessonsTemplate); } - @RolesAllowed(ROLE_ADMIN) + @Secured(ROLE_ADMIN) @PutMapping("/api/lessons_templates/{lessonsTemplateId}") public LessonsTemplate updateLessonsTemplate(@PathVariable String lessonsTemplateId, @Valid @RequestBody LessonsTemplateUpdateInput input) { @@ -65,7 +64,7 @@ public LessonsTemplate updateLessonsTemplate(@PathVariable String lessonsTemplat return lessonsTemplateRepository.save(lessonsTemplate); } - @RolesAllowed(ROLE_ADMIN) + @Secured(ROLE_ADMIN) @DeleteMapping("/api/lessons_templates/{lessonsTemplateId}") public void deleteLessonsTemplate(@PathVariable String lessonsTemplateId) { lessonsTemplateRepository.deleteById(lessonsTemplateId); @@ -76,7 +75,7 @@ public Iterable lessonsTemplateCategories(@PathVariable return lessonsTemplateCategoryRepository.findAll(LessonsTemplateCategorySpecification.fromTemplate(lessonsTemplateId)); } - @RolesAllowed(ROLE_ADMIN) + @Secured(ROLE_ADMIN) @PostMapping("/api/lessons_templates/{lessonsTemplateId}/lessons_template_categories") public LessonsTemplateCategory createLessonsTemplateCategory(@PathVariable String lessonsTemplateId, @Valid @RequestBody LessonsTemplateCategoryCreateInput input) { LessonsTemplate lessonsTemplate = lessonsTemplateRepository.findById(lessonsTemplateId).orElseThrow(); @@ -86,7 +85,7 @@ public LessonsTemplateCategory createLessonsTemplateCategory(@PathVariable Strin return lessonsTemplateCategoryRepository.save(lessonsTemplateCategory); } - @RolesAllowed(ROLE_ADMIN) + @Secured(ROLE_ADMIN) @PutMapping("/api/lessons_templates/{lessonsTemplateId}/lessons_template_categories/{lessonsTemplateCategoryId}") public LessonsTemplateCategory updateLessonsTemplateCategory(@PathVariable String lessonsTemplateCategoryId, @Valid @RequestBody LessonsTemplateCategoryUpdateInput input) { LessonsTemplateCategory lessonsTemplateCategory = lessonsTemplateCategoryRepository.findById(lessonsTemplateCategoryId).orElseThrow(); @@ -95,7 +94,7 @@ public LessonsTemplateCategory updateLessonsTemplateCategory(@PathVariable Strin return lessonsTemplateCategoryRepository.save(lessonsTemplateCategory); } - @RolesAllowed(ROLE_ADMIN) + @Secured(ROLE_ADMIN) @DeleteMapping("/api/lessons_templates/{lessonsTemplateId}/lessons_template_categories/{lessonsTemplateCategoryId}") public void deleteLessonsTemplateCategory(@PathVariable String lessonsTemplateCategoryId) { lessonsTemplateCategoryRepository.deleteById(lessonsTemplateCategoryId); @@ -112,7 +111,7 @@ public Iterable lessonsTemplateCategoryQuestions(@PathV return lessonsTemplateQuestionRepository.findAll(LessonsTemplateQuestionSpecification.fromCategory(lessonsTemplateCategoryId)); } - @RolesAllowed(ROLE_ADMIN) + @Secured(ROLE_ADMIN) @PostMapping("/api/lessons_templates/{lessonsTemplateId}/lessons_template_categories/{lessonsTemplateCategoryId}/lessons_template_questions") public LessonsTemplateQuestion createLessonsTemplateQuestion(@PathVariable String lessonsTemplateCategoryId, @Valid @RequestBody LessonsTemplateQuestionCreateInput input) { LessonsTemplateCategory lessonsTemplateCategory = lessonsTemplateCategoryRepository.findById(lessonsTemplateCategoryId).orElseThrow(); @@ -122,7 +121,7 @@ public LessonsTemplateQuestion createLessonsTemplateQuestion(@PathVariable Strin return lessonsTemplateQuestionRepository.save(lessonsTemplateQuestion); } - @RolesAllowed(ROLE_ADMIN) + @Secured(ROLE_ADMIN) @PutMapping("/api/lessons_templates/{lessonsTemplateId}/lessons_template_categories/{lessonsTemplateCategoryId}/lessons_template_questions/{lessonsTemplateQuestionId}") public LessonsTemplateQuestion updateLessonsTemplateQuestion(@PathVariable String lessonsTemplateQuestionId, @Valid @RequestBody LessonsTemplateQuestionUpdateInput input) { LessonsTemplateQuestion lessonsTemplateQuestion = lessonsTemplateQuestionRepository.findById(lessonsTemplateQuestionId).orElseThrow(); @@ -131,7 +130,7 @@ public LessonsTemplateQuestion updateLessonsTemplateQuestion(@PathVariable Strin return lessonsTemplateQuestionRepository.save(lessonsTemplateQuestion); } - @RolesAllowed(ROLE_ADMIN) + @Secured(ROLE_ADMIN) @DeleteMapping("/api/lessons_templates/{lessonsTemplateId}/lessons_template_categories/{lessonsTemplateCategoryId}/lessons_template_questions/{lessonsTemplateQuestionId}") public void deleteLessonsTemplateQuestion(@PathVariable String lessonsTemplateQuestionId) { lessonsTemplateQuestionRepository.deleteById(lessonsTemplateQuestionId); diff --git a/openex-api/src/main/java/io/openex/rest/lessons_template/form/LessonsTemplateCategoryCreateInput.java b/openex-api/src/main/java/io/openex/rest/lessons_template/form/LessonsTemplateCategoryCreateInput.java index 66ec33c6af..bbfb0c9f7d 100644 --- a/openex-api/src/main/java/io/openex/rest/lessons_template/form/LessonsTemplateCategoryCreateInput.java +++ b/openex-api/src/main/java/io/openex/rest/lessons_template/form/LessonsTemplateCategoryCreateInput.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; import static io.openex.config.AppConfig.MANDATORY_MESSAGE; diff --git a/openex-api/src/main/java/io/openex/rest/lessons_template/form/LessonsTemplateCategoryUpdateInput.java b/openex-api/src/main/java/io/openex/rest/lessons_template/form/LessonsTemplateCategoryUpdateInput.java index 8374f9344d..a47fa4d480 100644 --- a/openex-api/src/main/java/io/openex/rest/lessons_template/form/LessonsTemplateCategoryUpdateInput.java +++ b/openex-api/src/main/java/io/openex/rest/lessons_template/form/LessonsTemplateCategoryUpdateInput.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; import static io.openex.config.AppConfig.MANDATORY_MESSAGE; diff --git a/openex-api/src/main/java/io/openex/rest/lessons_template/form/LessonsTemplateCreateInput.java b/openex-api/src/main/java/io/openex/rest/lessons_template/form/LessonsTemplateCreateInput.java index 12d96b147b..1f6794dfc7 100644 --- a/openex-api/src/main/java/io/openex/rest/lessons_template/form/LessonsTemplateCreateInput.java +++ b/openex-api/src/main/java/io/openex/rest/lessons_template/form/LessonsTemplateCreateInput.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; import static io.openex.config.AppConfig.MANDATORY_MESSAGE; diff --git a/openex-api/src/main/java/io/openex/rest/lessons_template/form/LessonsTemplateQuestionCreateInput.java b/openex-api/src/main/java/io/openex/rest/lessons_template/form/LessonsTemplateQuestionCreateInput.java index c5cfc8c12a..719c151bb4 100644 --- a/openex-api/src/main/java/io/openex/rest/lessons_template/form/LessonsTemplateQuestionCreateInput.java +++ b/openex-api/src/main/java/io/openex/rest/lessons_template/form/LessonsTemplateQuestionCreateInput.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; import static io.openex.config.AppConfig.MANDATORY_MESSAGE; diff --git a/openex-api/src/main/java/io/openex/rest/lessons_template/form/LessonsTemplateQuestionUpdateInput.java b/openex-api/src/main/java/io/openex/rest/lessons_template/form/LessonsTemplateQuestionUpdateInput.java index 0c00e95b06..6dbc20a530 100644 --- a/openex-api/src/main/java/io/openex/rest/lessons_template/form/LessonsTemplateQuestionUpdateInput.java +++ b/openex-api/src/main/java/io/openex/rest/lessons_template/form/LessonsTemplateQuestionUpdateInput.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; import static io.openex.config.AppConfig.MANDATORY_MESSAGE; diff --git a/openex-api/src/main/java/io/openex/rest/lessons_template/form/LessonsTemplateUpdateInput.java b/openex-api/src/main/java/io/openex/rest/lessons_template/form/LessonsTemplateUpdateInput.java index 0bd7b23cd5..9f5e741e1f 100644 --- a/openex-api/src/main/java/io/openex/rest/lessons_template/form/LessonsTemplateUpdateInput.java +++ b/openex-api/src/main/java/io/openex/rest/lessons_template/form/LessonsTemplateUpdateInput.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; import static io.openex.config.AppConfig.MANDATORY_MESSAGE; diff --git a/openex-api/src/main/java/io/openex/rest/objective/ObjectiveApi.java b/openex-api/src/main/java/io/openex/rest/objective/ObjectiveApi.java index d54ef3a7e9..89dac5cc81 100644 --- a/openex-api/src/main/java/io/openex/rest/objective/ObjectiveApi.java +++ b/openex-api/src/main/java/io/openex/rest/objective/ObjectiveApi.java @@ -16,8 +16,8 @@ import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; -import javax.transaction.Transactional; -import javax.validation.Valid; +import jakarta.transaction.Transactional; +import jakarta.validation.Valid; import static io.openex.config.SessionHelper.currentUser; import static io.openex.helper.DatabaseHelper.resolveRelation; diff --git a/openex-api/src/main/java/io/openex/rest/organization/OrganizationApi.java b/openex-api/src/main/java/io/openex/rest/organization/OrganizationApi.java index 5e06af146d..c0c2025906 100644 --- a/openex-api/src/main/java/io/openex/rest/organization/OrganizationApi.java +++ b/openex-api/src/main/java/io/openex/rest/organization/OrganizationApi.java @@ -11,12 +11,12 @@ import io.openex.rest.helper.RestBehavior; import io.openex.rest.organization.form.OrganizationCreateInput; import io.openex.rest.organization.form.OrganizationUpdateInput; +import jakarta.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.annotation.Secured; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; -import javax.annotation.security.RolesAllowed; -import javax.validation.Valid; import java.util.List; import static io.openex.config.SessionHelper.currentUser; @@ -68,7 +68,7 @@ public Iterable organizations() { return organizations.stream().peek(org -> org.resolveInjects(injects)).toList(); } - @RolesAllowed(ROLE_ADMIN) + @Secured(ROLE_ADMIN) @PostMapping("/api/organizations") public Organization createOrganization(@Valid @RequestBody OrganizationCreateInput input) { Organization organization = new Organization(); @@ -77,7 +77,7 @@ public Organization createOrganization(@Valid @RequestBody OrganizationCreateInp return organizationRepository.save(organization); } - @RolesAllowed(ROLE_ADMIN) + @Secured(ROLE_ADMIN) @PutMapping("/api/organizations/{organizationId}") public Organization updateOrganization(@PathVariable String organizationId, @Valid @RequestBody OrganizationUpdateInput input) { @@ -90,7 +90,7 @@ public Organization updateOrganization(@PathVariable String organizationId, } - @RolesAllowed(ROLE_ADMIN) + @Secured(ROLE_ADMIN) @DeleteMapping("/api/organizations/{organizationId}") public void deleteOrganization(@PathVariable String organizationId) { checkOrganizationAccess(userRepository, organizationId); diff --git a/openex-api/src/main/java/io/openex/rest/organization/form/OrganizationCreateInput.java b/openex-api/src/main/java/io/openex/rest/organization/form/OrganizationCreateInput.java index 9c014bae11..605d318d9c 100644 --- a/openex-api/src/main/java/io/openex/rest/organization/form/OrganizationCreateInput.java +++ b/openex-api/src/main/java/io/openex/rest/organization/form/OrganizationCreateInput.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; import java.util.ArrayList; import java.util.List; diff --git a/openex-api/src/main/java/io/openex/rest/organization/form/OrganizationUpdateInput.java b/openex-api/src/main/java/io/openex/rest/organization/form/OrganizationUpdateInput.java index 17d1f2869a..81d78395ea 100644 --- a/openex-api/src/main/java/io/openex/rest/organization/form/OrganizationUpdateInput.java +++ b/openex-api/src/main/java/io/openex/rest/organization/form/OrganizationUpdateInput.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; import java.util.ArrayList; import java.util.List; diff --git a/openex-api/src/main/java/io/openex/rest/report/ReportApi.java b/openex-api/src/main/java/io/openex/rest/report/ReportApi.java index 79bf4db429..afe6745cc2 100644 --- a/openex-api/src/main/java/io/openex/rest/report/ReportApi.java +++ b/openex-api/src/main/java/io/openex/rest/report/ReportApi.java @@ -10,7 +10,7 @@ import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; -import javax.validation.Valid; +import jakarta.validation.Valid; import static java.time.Instant.now; diff --git a/openex-api/src/main/java/io/openex/rest/report/form/ReportCreateInput.java b/openex-api/src/main/java/io/openex/rest/report/form/ReportCreateInput.java index 30751ca650..9aa3af6bdd 100644 --- a/openex-api/src/main/java/io/openex/rest/report/form/ReportCreateInput.java +++ b/openex-api/src/main/java/io/openex/rest/report/form/ReportCreateInput.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; import static io.openex.config.AppConfig.MANDATORY_MESSAGE; @@ -118,4 +118,4 @@ public boolean isLessonsDetails() { public void setLessonsDetails(boolean lessonsDetails) { this.lessonsDetails = lessonsDetails; } -} \ No newline at end of file +} diff --git a/openex-api/src/main/java/io/openex/rest/report/form/ReportUpdateInput.java b/openex-api/src/main/java/io/openex/rest/report/form/ReportUpdateInput.java index 713ace1d2c..c0e473b509 100644 --- a/openex-api/src/main/java/io/openex/rest/report/form/ReportUpdateInput.java +++ b/openex-api/src/main/java/io/openex/rest/report/form/ReportUpdateInput.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; import static io.openex.config.AppConfig.MANDATORY_MESSAGE; @@ -118,4 +118,4 @@ public boolean isLessonsDetails() { public void setLessonsDetails(boolean lessonsDetails) { this.lessonsDetails = lessonsDetails; } -} \ No newline at end of file +} diff --git a/openex-api/src/main/java/io/openex/rest/security/MethodSecurityConfig.java b/openex-api/src/main/java/io/openex/rest/security/MethodSecurityConfig.java index e070a811bc..99e6641012 100644 --- a/openex-api/src/main/java/io/openex/rest/security/MethodSecurityConfig.java +++ b/openex-api/src/main/java/io/openex/rest/security/MethodSecurityConfig.java @@ -2,31 +2,22 @@ import io.openex.database.repository.ExerciseRepository; import io.openex.database.repository.UserRepository; -import org.springframework.beans.factory.annotation.Autowired; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler; -import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; -import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration; +import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; @Configuration -@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true) -public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration { +@EnableMethodSecurity(securedEnabled = true) +@RequiredArgsConstructor +public class MethodSecurityConfig { - private ExerciseRepository exerciseRepository; - private UserRepository userRepository; + private final ExerciseRepository exerciseRepository; + private final UserRepository userRepository; - @Autowired - public void setExerciseRepository(ExerciseRepository exerciseRepository) { - this.exerciseRepository = exerciseRepository; - } - - @Autowired - public void setUserRepository(UserRepository userRepository) { - this.userRepository = userRepository; - } - - @Override - protected MethodSecurityExpressionHandler createExpressionHandler() { - return new SecurityExpressionHandler(userRepository, exerciseRepository); - } + @Bean + MethodSecurityExpressionHandler methodSecurityExpressionHandler() { + return new SecurityExpressionHandler(this.userRepository, this.exerciseRepository); + } } diff --git a/openex-api/src/main/java/io/openex/rest/security/SecurityExpression.java b/openex-api/src/main/java/io/openex/rest/security/SecurityExpression.java index e02f4c160b..11ce6ac5ee 100644 --- a/openex-api/src/main/java/io/openex/rest/security/SecurityExpression.java +++ b/openex-api/src/main/java/io/openex/rest/security/SecurityExpression.java @@ -132,4 +132,4 @@ public Object getThis() { return this; } // endregion -} \ No newline at end of file +} diff --git a/openex-api/src/main/java/io/openex/rest/security/SecurityExpressionHandler.java b/openex-api/src/main/java/io/openex/rest/security/SecurityExpressionHandler.java index 8994360d8a..bed8e001cb 100644 --- a/openex-api/src/main/java/io/openex/rest/security/SecurityExpressionHandler.java +++ b/openex-api/src/main/java/io/openex/rest/security/SecurityExpressionHandler.java @@ -3,29 +3,40 @@ import io.openex.database.repository.ExerciseRepository; import io.openex.database.repository.UserRepository; import org.aopalliance.intercept.MethodInvocation; +import org.springframework.expression.EvaluationContext; +import org.springframework.expression.spel.support.StandardEvaluationContext; import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler; import org.springframework.security.access.expression.method.MethodSecurityExpressionOperations; import org.springframework.security.authentication.AuthenticationTrustResolver; import org.springframework.security.authentication.AuthenticationTrustResolverImpl; import org.springframework.security.core.Authentication; +import java.util.function.Supplier; + public class SecurityExpressionHandler extends DefaultMethodSecurityExpressionHandler { - private final AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl(); - private final ExerciseRepository exerciseRepository; - private final UserRepository userRepository; + private final AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl(); + private final ExerciseRepository exerciseRepository; + private final UserRepository userRepository; - public SecurityExpressionHandler(UserRepository userRepository, ExerciseRepository exerciseRepository) { - this.userRepository = userRepository; - this.exerciseRepository = exerciseRepository; - } + public SecurityExpressionHandler(UserRepository userRepository, ExerciseRepository exerciseRepository) { + this.userRepository = userRepository; + this.exerciseRepository = exerciseRepository; + } - @Override - protected MethodSecurityExpressionOperations createSecurityExpressionRoot(Authentication authentication, MethodInvocation invocation) { - SecurityExpression root = new SecurityExpression(authentication, userRepository, exerciseRepository); - root.setPermissionEvaluator(getPermissionEvaluator()); - root.setTrustResolver(this.trustResolver); - root.setRoleHierarchy(getRoleHierarchy()); - return root; - } -} \ No newline at end of file + @Override + public EvaluationContext createEvaluationContext(Supplier authentication, + MethodInvocation invocation) { + StandardEvaluationContext context = (StandardEvaluationContext) super.createEvaluationContext(authentication, + invocation); + MethodSecurityExpressionOperations delegate = (MethodSecurityExpressionOperations) context.getRootObject() + .getValue(); + assert delegate != null; + SecurityExpression root = new SecurityExpression(delegate.getAuthentication(), userRepository, exerciseRepository); + root.setPermissionEvaluator(getPermissionEvaluator()); + root.setTrustResolver(this.trustResolver); + root.setRoleHierarchy(getRoleHierarchy()); + context.setRootObject(root); + return context; + } +} diff --git a/openex-api/src/main/java/io/openex/rest/settings/SettingsApi.java b/openex-api/src/main/java/io/openex/rest/settings/SettingsApi.java index df3e69430c..e990a00937 100644 --- a/openex-api/src/main/java/io/openex/rest/settings/SettingsApi.java +++ b/openex-api/src/main/java/io/openex/rest/settings/SettingsApi.java @@ -9,19 +9,19 @@ import io.openex.rest.settings.form.SettingsUpdateInput; import io.openex.rest.settings.response.OAuthProvider; import io.openex.rest.settings.response.PlatformSetting; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientProperties; import org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyProperties; import org.springframework.context.ApplicationContext; import org.springframework.core.env.Environment; +import org.springframework.security.access.annotation.Secured; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; -import javax.annotation.Resource; -import javax.annotation.security.RolesAllowed; -import javax.validation.Valid; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -158,7 +158,7 @@ public List settings() { return settings; } - @RolesAllowed(ROLE_ADMIN) + @Secured(ROLE_ADMIN) @PutMapping("/api/settings") public List updateSettings(@Valid @RequestBody SettingsUpdateInput input) { Map dbSettings = mapOfSettings(); diff --git a/openex-api/src/main/java/io/openex/rest/settings/form/SettingsUpdateInput.java b/openex-api/src/main/java/io/openex/rest/settings/form/SettingsUpdateInput.java index 535a7e7267..3e2e7bbb5b 100644 --- a/openex-api/src/main/java/io/openex/rest/settings/form/SettingsUpdateInput.java +++ b/openex-api/src/main/java/io/openex/rest/settings/form/SettingsUpdateInput.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; import static io.openex.config.AppConfig.MANDATORY_MESSAGE; diff --git a/openex-api/src/main/java/io/openex/rest/tag/TagApi.java b/openex-api/src/main/java/io/openex/rest/tag/TagApi.java index 632af221cd..2ebc5dba2a 100644 --- a/openex-api/src/main/java/io/openex/rest/tag/TagApi.java +++ b/openex-api/src/main/java/io/openex/rest/tag/TagApi.java @@ -5,12 +5,11 @@ import io.openex.rest.helper.RestBehavior; import io.openex.rest.tag.form.TagCreateInput; import io.openex.rest.tag.form.TagUpdateInput; +import jakarta.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.annotation.Secured; import org.springframework.web.bind.annotation.*; -import javax.annotation.security.RolesAllowed; -import javax.validation.Valid; - import static io.openex.database.model.User.ROLE_ADMIN; @RestController @@ -28,7 +27,7 @@ public Iterable tags() { return tagRepository.findAll(); } - @RolesAllowed(ROLE_ADMIN) + @Secured(ROLE_ADMIN) @PutMapping("/api/tags/{tagId}") public Tag updateTag(@PathVariable String tagId, @Valid @RequestBody TagUpdateInput input) { @@ -37,7 +36,7 @@ public Tag updateTag(@PathVariable String tagId, return tagRepository.save(tag); } - @RolesAllowed(ROLE_ADMIN) + @Secured(ROLE_ADMIN) @PostMapping("/api/tags") public Tag createTag(@Valid @RequestBody TagCreateInput input) { Tag tag = new Tag(); @@ -45,7 +44,7 @@ public Tag createTag(@Valid @RequestBody TagCreateInput input) { return tagRepository.save(tag); } - @RolesAllowed(ROLE_ADMIN) + @Secured(ROLE_ADMIN) @DeleteMapping("/api/tags/{tagId}") public void deleteTag(@PathVariable String tagId) { tagRepository.deleteById(tagId); diff --git a/openex-api/src/main/java/io/openex/rest/tag/form/TagCreateInput.java b/openex-api/src/main/java/io/openex/rest/tag/form/TagCreateInput.java index 09f2f601af..678b5d7631 100644 --- a/openex-api/src/main/java/io/openex/rest/tag/form/TagCreateInput.java +++ b/openex-api/src/main/java/io/openex/rest/tag/form/TagCreateInput.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; import static io.openex.config.AppConfig.MANDATORY_MESSAGE; diff --git a/openex-api/src/main/java/io/openex/rest/tag/form/TagUpdateInput.java b/openex-api/src/main/java/io/openex/rest/tag/form/TagUpdateInput.java index 0df41c7ec1..26f61e0cc8 100644 --- a/openex-api/src/main/java/io/openex/rest/tag/form/TagUpdateInput.java +++ b/openex-api/src/main/java/io/openex/rest/tag/form/TagUpdateInput.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; import static io.openex.config.AppConfig.MANDATORY_MESSAGE; diff --git a/openex-api/src/main/java/io/openex/rest/team/TeamApi.java b/openex-api/src/main/java/io/openex/rest/team/TeamApi.java index a695bb179d..cde5e551f2 100644 --- a/openex-api/src/main/java/io/openex/rest/team/TeamApi.java +++ b/openex-api/src/main/java/io/openex/rest/team/TeamApi.java @@ -1,32 +1,30 @@ package io.openex.rest.team; import io.openex.config.OpenexPrincipal; -import io.openex.database.model.*; +import io.openex.database.model.Organization; +import io.openex.database.model.Team; +import io.openex.database.model.User; import io.openex.database.repository.*; +import io.openex.rest.helper.RestBehavior; import io.openex.rest.team.form.TeamCreateInput; -import io.openex.rest.team.form.TeamUpdateActivationInput; import io.openex.rest.team.form.TeamUpdateInput; import io.openex.rest.team.form.UpdateUsersTeamInput; -import io.openex.rest.helper.RestBehavior; +import jakarta.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.annotation.Secured; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; -import javax.annotation.security.RolesAllowed; -import javax.validation.Valid; - -import java.util.ArrayList; import java.util.List; import static io.openex.config.SessionHelper.currentUser; import static io.openex.database.model.User.ROLE_USER; import static io.openex.helper.DatabaseHelper.updateRelation; import static io.openex.helper.StreamHelper.fromIterable; -import static java.time.Instant.from; import static java.time.Instant.now; @RestController -@RolesAllowed(ROLE_USER) +@Secured(ROLE_USER) public class TeamApi extends RestBehavior { private ExerciseRepository exerciseRepository; private TeamRepository teamRepository; diff --git a/openex-api/src/main/java/io/openex/rest/team/form/TeamCreateInput.java b/openex-api/src/main/java/io/openex/rest/team/form/TeamCreateInput.java index d5e72eb392..ea22252768 100644 --- a/openex-api/src/main/java/io/openex/rest/team/form/TeamCreateInput.java +++ b/openex-api/src/main/java/io/openex/rest/team/form/TeamCreateInput.java @@ -2,8 +2,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.NotBlank; - +import jakarta.validation.constraints.NotBlank; import java.util.ArrayList; import java.util.List; diff --git a/openex-api/src/main/java/io/openex/rest/team/form/TeamUpdateInput.java b/openex-api/src/main/java/io/openex/rest/team/form/TeamUpdateInput.java index a2dd9cd104..2d4387ef11 100644 --- a/openex-api/src/main/java/io/openex/rest/team/form/TeamUpdateInput.java +++ b/openex-api/src/main/java/io/openex/rest/team/form/TeamUpdateInput.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; import java.util.ArrayList; import java.util.List; diff --git a/openex-api/src/main/java/io/openex/rest/user/MeApi.java b/openex-api/src/main/java/io/openex/rest/user/MeApi.java index d094c0e51e..5880ebc19c 100644 --- a/openex-api/src/main/java/io/openex/rest/user/MeApi.java +++ b/openex-api/src/main/java/io/openex/rest/user/MeApi.java @@ -13,15 +13,15 @@ import io.openex.rest.user.form.user.RenewTokenInput; import io.openex.rest.user.form.user.UpdateUserInfoInput; import io.openex.service.UserService; +import jakarta.annotation.Resource; +import jakarta.transaction.Transactional; +import jakarta.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.security.access.AccessDeniedException; +import org.springframework.security.access.annotation.Secured; import org.springframework.web.bind.annotation.*; -import javax.annotation.Resource; -import javax.annotation.security.RolesAllowed; -import javax.transaction.Transactional; -import javax.validation.Valid; import java.util.List; import java.util.UUID; @@ -61,19 +61,19 @@ public void setTokenRepository(TokenRepository tokenRepository) { this.tokenRepository = tokenRepository; } - @RolesAllowed(ROLE_USER) + @Secured(ROLE_USER) @GetMapping("/api/logout") public ResponseEntity logout() { return ResponseEntity.ok().build(); } - @RolesAllowed(ROLE_USER) + @Secured(ROLE_USER) @GetMapping("/api/me") public User me() { return userRepository.findById(currentUser().getId()).orElseThrow(); } - @RolesAllowed(ROLE_USER) + @Secured(ROLE_USER) @PutMapping("/api/me/profile") public User updateProfile(@Valid @RequestBody UpdateProfileInput input) { User user = userRepository.findById(currentUser().getId()).orElseThrow(); @@ -84,7 +84,7 @@ public User updateProfile(@Valid @RequestBody UpdateProfileInput input) { return savedUser; } - @RolesAllowed(ROLE_USER) + @Secured(ROLE_USER) @PutMapping("/api/me/information") public User updateInformation(@Valid @RequestBody UpdateUserInfoInput input) { User user = userRepository.findById(currentUser().getId()).orElseThrow(); @@ -94,7 +94,7 @@ public User updateInformation(@Valid @RequestBody UpdateUserInfoInput input) { return savedUser; } - @RolesAllowed(ROLE_USER) + @Secured(ROLE_USER) @PutMapping("/api/me/password") public User updatePassword(@Valid @RequestBody UpdateMePasswordInput input) throws InputValidationException { User user = userRepository.findById(currentUser().getId()).orElseThrow(); @@ -106,7 +106,7 @@ public User updatePassword(@Valid @RequestBody UpdateMePasswordInput input) thro } } - @RolesAllowed(ROLE_USER) + @Secured(ROLE_USER) @PostMapping("/api/me/token/refresh") @Transactional(rollbackOn = Exception.class) public Token renewToken(@Valid @RequestBody RenewTokenInput input) throws InputValidationException { @@ -119,7 +119,7 @@ public Token renewToken(@Valid @RequestBody RenewTokenInput input) throws InputV return tokenRepository.save(token); } - @RolesAllowed(ROLE_USER) + @Secured(ROLE_USER) @GetMapping("/api/me/tokens") public List tokens() { return tokenRepository.findAll(fromUser(currentUser().getId())); diff --git a/openex-api/src/main/java/io/openex/rest/user/PlayerApi.java b/openex-api/src/main/java/io/openex/rest/user/PlayerApi.java index f8e534fe3b..83881eb00f 100644 --- a/openex-api/src/main/java/io/openex/rest/user/PlayerApi.java +++ b/openex-api/src/main/java/io/openex/rest/user/PlayerApi.java @@ -15,9 +15,9 @@ import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; -import javax.annotation.Resource; -import javax.transaction.Transactional; -import javax.validation.Valid; +import jakarta.annotation.Resource; +import jakarta.transaction.Transactional; +import jakarta.validation.Valid; import java.util.List; import static io.openex.config.SessionHelper.currentUser; diff --git a/openex-api/src/main/java/io/openex/rest/user/UserApi.java b/openex-api/src/main/java/io/openex/rest/user/UserApi.java index 16059a5391..9212b00fbf 100644 --- a/openex-api/src/main/java/io/openex/rest/user/UserApi.java +++ b/openex-api/src/main/java/io/openex/rest/user/UserApi.java @@ -14,16 +14,16 @@ import io.openex.rest.user.form.user.UpdateUserInput; import io.openex.service.MailingService; import io.openex.service.UserService; +import jakarta.annotation.Resource; +import jakarta.transaction.Transactional; +import jakarta.validation.Valid; import org.apache.commons.collections4.map.PassiveExpiringMap; import org.apache.commons.lang3.RandomStringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.AccessDeniedException; +import org.springframework.security.access.annotation.Secured; import org.springframework.web.bind.annotation.*; -import javax.annotation.Resource; -import javax.annotation.security.RolesAllowed; -import javax.transaction.Transactional; -import javax.validation.Valid; import java.util.List; import java.util.Optional; @@ -129,13 +129,13 @@ public boolean validatePasswordResetToken(@PathVariable String token) { return resetTokenMap.get(token) != null; } - @RolesAllowed(ROLE_ADMIN) + @Secured(ROLE_ADMIN) @GetMapping("/api/users") public Iterable users() { return userRepository.findAll(); } - @RolesAllowed(ROLE_ADMIN) + @Secured(ROLE_ADMIN) @PutMapping("/api/users/{userId}/password") public User changePassword(@PathVariable String userId, @Valid @RequestBody ChangePasswordInput input) { @@ -145,13 +145,13 @@ public User changePassword(@PathVariable String userId, } @Transactional(rollbackOn = Exception.class) - @RolesAllowed(ROLE_ADMIN) + @Secured(ROLE_ADMIN) @PostMapping("/api/users") public User createUser(@Valid @RequestBody CreateUserInput input) { return userService.createUser(input, 1); } - @RolesAllowed(ROLE_ADMIN) + @Secured(ROLE_ADMIN) @PutMapping("/api/users/{userId}") public User updateUser(@PathVariable String userId, @Valid @RequestBody UpdateUserInput input) { User user = userRepository.findById(userId).orElseThrow(); @@ -163,7 +163,7 @@ public User updateUser(@PathVariable String userId, @Valid @RequestBody UpdateUs return savedUser; } - @RolesAllowed(ROLE_ADMIN) + @Secured(ROLE_ADMIN) @DeleteMapping("/api/users/{userId}") public void deleteUser(@PathVariable String userId) { sessionManager.invalidateUserSession(userId); diff --git a/openex-api/src/main/java/io/openex/rest/user/form/login/LoginUserInput.java b/openex-api/src/main/java/io/openex/rest/user/form/login/LoginUserInput.java index e16b4c4af7..1a39ccc30b 100644 --- a/openex-api/src/main/java/io/openex/rest/user/form/login/LoginUserInput.java +++ b/openex-api/src/main/java/io/openex/rest/user/form/login/LoginUserInput.java @@ -1,6 +1,6 @@ package io.openex.rest.user.form.login; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; import static io.openex.config.AppConfig.MANDATORY_MESSAGE; diff --git a/openex-api/src/main/java/io/openex/rest/user/form/login/ResetUserInput.java b/openex-api/src/main/java/io/openex/rest/user/form/login/ResetUserInput.java index 5dba3013bb..6aaf4148e1 100644 --- a/openex-api/src/main/java/io/openex/rest/user/form/login/ResetUserInput.java +++ b/openex-api/src/main/java/io/openex/rest/user/form/login/ResetUserInput.java @@ -1,6 +1,6 @@ package io.openex.rest.user.form.login; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; import static io.openex.config.AppConfig.MANDATORY_MESSAGE; diff --git a/openex-api/src/main/java/io/openex/rest/user/form/me/UpdateMePasswordInput.java b/openex-api/src/main/java/io/openex/rest/user/form/me/UpdateMePasswordInput.java index 1506678c5e..7bddf19497 100644 --- a/openex-api/src/main/java/io/openex/rest/user/form/me/UpdateMePasswordInput.java +++ b/openex-api/src/main/java/io/openex/rest/user/form/me/UpdateMePasswordInput.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; import static io.openex.config.AppConfig.MANDATORY_MESSAGE; diff --git a/openex-api/src/main/java/io/openex/rest/user/form/me/UpdateProfileInput.java b/openex-api/src/main/java/io/openex/rest/user/form/me/UpdateProfileInput.java index 77ba216acd..7b8c155ca0 100644 --- a/openex-api/src/main/java/io/openex/rest/user/form/me/UpdateProfileInput.java +++ b/openex-api/src/main/java/io/openex/rest/user/form/me/UpdateProfileInput.java @@ -4,8 +4,8 @@ import lombok.Getter; import lombok.Setter; -import javax.validation.constraints.Email; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotBlank; import static io.openex.config.AppConfig.EMAIL_FORMAT; import static io.openex.config.AppConfig.MANDATORY_MESSAGE; diff --git a/openex-api/src/main/java/io/openex/rest/user/form/player/CreatePlayerInput.java b/openex-api/src/main/java/io/openex/rest/user/form/player/CreatePlayerInput.java index 3fc64fe90e..0089deb6a4 100644 --- a/openex-api/src/main/java/io/openex/rest/user/form/player/CreatePlayerInput.java +++ b/openex-api/src/main/java/io/openex/rest/user/form/player/CreatePlayerInput.java @@ -4,8 +4,8 @@ import lombok.Getter; import lombok.Setter; -import javax.validation.constraints.Email; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotBlank; import java.util.ArrayList; import java.util.List; diff --git a/openex-api/src/main/java/io/openex/rest/user/form/player/UpdatePlayerInput.java b/openex-api/src/main/java/io/openex/rest/user/form/player/UpdatePlayerInput.java index 860a6855a7..43ea1144e4 100644 --- a/openex-api/src/main/java/io/openex/rest/user/form/player/UpdatePlayerInput.java +++ b/openex-api/src/main/java/io/openex/rest/user/form/player/UpdatePlayerInput.java @@ -4,7 +4,7 @@ import lombok.Getter; import lombok.Setter; -import javax.validation.constraints.Pattern; +import jakarta.validation.constraints.Pattern; import static io.openex.config.AppConfig.PHONE_FORMAT; diff --git a/openex-api/src/main/java/io/openex/rest/user/form/user/ChangePasswordInput.java b/openex-api/src/main/java/io/openex/rest/user/form/user/ChangePasswordInput.java index 2546bb0cde..c0650d0c81 100644 --- a/openex-api/src/main/java/io/openex/rest/user/form/user/ChangePasswordInput.java +++ b/openex-api/src/main/java/io/openex/rest/user/form/user/ChangePasswordInput.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; import static io.openex.config.AppConfig.MANDATORY_MESSAGE; diff --git a/openex-api/src/main/java/io/openex/rest/user/form/user/CreateUserInput.java b/openex-api/src/main/java/io/openex/rest/user/form/user/CreateUserInput.java index 900a67869a..e39ea8abfe 100644 --- a/openex-api/src/main/java/io/openex/rest/user/form/user/CreateUserInput.java +++ b/openex-api/src/main/java/io/openex/rest/user/form/user/CreateUserInput.java @@ -4,8 +4,8 @@ import lombok.Getter; import lombok.Setter; -import javax.validation.constraints.Email; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotBlank; import java.util.ArrayList; import java.util.List; diff --git a/openex-api/src/main/java/io/openex/rest/user/form/user/RenewTokenInput.java b/openex-api/src/main/java/io/openex/rest/user/form/user/RenewTokenInput.java index 627bebbef9..c5a3afa69b 100644 --- a/openex-api/src/main/java/io/openex/rest/user/form/user/RenewTokenInput.java +++ b/openex-api/src/main/java/io/openex/rest/user/form/user/RenewTokenInput.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; import static io.openex.config.AppConfig.MANDATORY_MESSAGE; diff --git a/openex-api/src/main/java/io/openex/rest/user/form/user/UpdatePasswordInput.java b/openex-api/src/main/java/io/openex/rest/user/form/user/UpdatePasswordInput.java index 04358473da..6a7bb32901 100644 --- a/openex-api/src/main/java/io/openex/rest/user/form/user/UpdatePasswordInput.java +++ b/openex-api/src/main/java/io/openex/rest/user/form/user/UpdatePasswordInput.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; import static io.openex.config.AppConfig.MANDATORY_MESSAGE; diff --git a/openex-api/src/main/java/io/openex/rest/user/form/user/UpdateUserInput.java b/openex-api/src/main/java/io/openex/rest/user/form/user/UpdateUserInput.java index e8624ed8b4..00a3ce0749 100644 --- a/openex-api/src/main/java/io/openex/rest/user/form/user/UpdateUserInput.java +++ b/openex-api/src/main/java/io/openex/rest/user/form/user/UpdateUserInput.java @@ -4,7 +4,7 @@ import lombok.Getter; import lombok.Setter; -import javax.validation.constraints.Email; +import jakarta.validation.constraints.Email; import java.util.ArrayList; import java.util.List; diff --git a/openex-api/src/main/java/io/openex/rest/variable/VariableApi.java b/openex-api/src/main/java/io/openex/rest/variable/VariableApi.java index 0de56adfb0..a9f86523ac 100644 --- a/openex-api/src/main/java/io/openex/rest/variable/VariableApi.java +++ b/openex-api/src/main/java/io/openex/rest/variable/VariableApi.java @@ -4,19 +4,18 @@ import io.openex.rest.helper.RestBehavior; import io.openex.rest.variable.form.VariableInput; import io.openex.service.VariableService; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; import lombok.RequiredArgsConstructor; +import org.springframework.security.access.annotation.Secured; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; -import javax.annotation.security.RolesAllowed; -import javax.validation.Valid; -import javax.validation.constraints.NotBlank; - import static io.openex.database.model.User.ROLE_USER; @RequiredArgsConstructor @RestController -@RolesAllowed(ROLE_USER) +@Secured(ROLE_USER) public class VariableApi extends RestBehavior { private final VariableService variableService; diff --git a/openex-api/src/main/java/io/openex/rest/variable/form/VariableInput.java b/openex-api/src/main/java/io/openex/rest/variable/form/VariableInput.java index a01df14050..2725518d43 100644 --- a/openex-api/src/main/java/io/openex/rest/variable/form/VariableInput.java +++ b/openex-api/src/main/java/io/openex/rest/variable/form/VariableInput.java @@ -3,8 +3,8 @@ import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.Pattern; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Pattern; import static io.openex.config.AppConfig.MANDATORY_MESSAGE; diff --git a/openex-api/src/main/java/io/openex/runner/InitAdminCommandLineRunner.java b/openex-api/src/main/java/io/openex/runner/InitAdminCommandLineRunner.java index b52dce4df8..25c88f2a31 100644 --- a/openex-api/src/main/java/io/openex/runner/InitAdminCommandLineRunner.java +++ b/openex-api/src/main/java/io/openex/runner/InitAdminCommandLineRunner.java @@ -59,7 +59,7 @@ public void run(String... args) { // -- USER -- private String encodedPassword() { - Argon2PasswordEncoder passwordEncoder = new Argon2PasswordEncoder(); + Argon2PasswordEncoder passwordEncoder = Argon2PasswordEncoder.defaultsForSpringSecurity_v5_8(); return passwordEncoder.encode(this.adminPassword); } @@ -103,7 +103,7 @@ private void createToken(@NotNull final User user) { throw new IllegalArgumentException("Config properties 'openex.admin.token' should be a valid UUID"); } - this.tokenRepository.createToken(ADMIN_TOKEN_UUID, user, this.adminToken, Instant.now()); + this.tokenRepository.createToken(ADMIN_TOKEN_UUID, user.getId(), this.adminToken, Instant.now()); } private void updateToken(@NotNull final Token token) { diff --git a/openex-api/src/main/java/io/openex/scheduler/jobs/ComchecksExecutionJob.java b/openex-api/src/main/java/io/openex/scheduler/jobs/ComchecksExecutionJob.java index 802d9a2215..c6a4218248 100644 --- a/openex-api/src/main/java/io/openex/scheduler/jobs/ComchecksExecutionJob.java +++ b/openex-api/src/main/java/io/openex/scheduler/jobs/ComchecksExecutionJob.java @@ -22,9 +22,9 @@ import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Component; -import javax.annotation.Resource; -import javax.transaction.Transactional; -import javax.validation.constraints.NotNull; +import jakarta.annotation.Resource; +import jakarta.transaction.Transactional; +import jakarta.validation.constraints.NotNull; import java.time.Instant; import java.util.List; import java.util.Map; @@ -136,7 +136,7 @@ public void execute(JobExecutionContext jobExecutionContext) throws JobExecution List statusToUpdate = comcheckStatuses.stream() .filter(comcheckStatus -> usersSuccessfullyNotified.contains(comcheckStatus.getUser().getId())) .toList(); - if (statusToUpdate.size() > 0) { + if (!statusToUpdate.isEmpty()) { comcheckStatusRepository.saveAll(statusToUpdate.stream() .peek(comcheckStatus -> comcheckStatus.setLastSent(now)) .toList()); diff --git a/openex-api/src/main/java/io/openex/security/SsoRefererAuthenticationFailureHandler.java b/openex-api/src/main/java/io/openex/security/SsoRefererAuthenticationFailureHandler.java index 38627e51fe..d20fc18221 100644 --- a/openex-api/src/main/java/io/openex/security/SsoRefererAuthenticationFailureHandler.java +++ b/openex-api/src/main/java/io/openex/security/SsoRefererAuthenticationFailureHandler.java @@ -6,9 +6,9 @@ import org.springframework.security.web.savedrequest.RequestCache; import org.springframework.security.web.savedrequest.SavedRequest; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.List; diff --git a/openex-api/src/main/java/io/openex/security/SsoRefererAuthenticationSuccessHandler.java b/openex-api/src/main/java/io/openex/security/SsoRefererAuthenticationSuccessHandler.java index 3fad3db9bc..a40a037c15 100644 --- a/openex-api/src/main/java/io/openex/security/SsoRefererAuthenticationSuccessHandler.java +++ b/openex-api/src/main/java/io/openex/security/SsoRefererAuthenticationSuccessHandler.java @@ -6,9 +6,9 @@ import org.springframework.security.web.savedrequest.RequestCache; import org.springframework.security.web.savedrequest.SavedRequest; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.List; diff --git a/openex-api/src/main/java/io/openex/security/TokenAuthenticationFilter.java b/openex-api/src/main/java/io/openex/security/TokenAuthenticationFilter.java index 5a2d90309f..4c313f91ee 100644 --- a/openex-api/src/main/java/io/openex/security/TokenAuthenticationFilter.java +++ b/openex-api/src/main/java/io/openex/security/TokenAuthenticationFilter.java @@ -9,11 +9,11 @@ import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.filter.OncePerRequestFilter; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Arrays; import java.util.Optional; @@ -73,4 +73,4 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse } filterChain.doFilter(request, response); } -} \ No newline at end of file +} diff --git a/openex-api/src/main/java/io/openex/service/ChallengeService.java b/openex-api/src/main/java/io/openex/service/ChallengeService.java index df8f795e02..e55febcdc7 100644 --- a/openex-api/src/main/java/io/openex/service/ChallengeService.java +++ b/openex-api/src/main/java/io/openex/service/ChallengeService.java @@ -13,7 +13,7 @@ import org.springframework.stereotype.Service; import org.springframework.web.bind.annotation.PathVariable; -import javax.annotation.Resource; +import jakarta.annotation.Resource; import java.util.List; import java.util.stream.Stream; diff --git a/openex-api/src/main/java/io/openex/service/DryrunService.java b/openex-api/src/main/java/io/openex/service/DryrunService.java index 992c8a9af1..3cbc944962 100644 --- a/openex-api/src/main/java/io/openex/service/DryrunService.java +++ b/openex-api/src/main/java/io/openex/service/DryrunService.java @@ -10,7 +10,7 @@ import org.springframework.stereotype.Service; import org.springframework.util.Assert; -import javax.transaction.Transactional; +import jakarta.transaction.Transactional; import java.util.List; import static java.time.Instant.now; @@ -59,7 +59,7 @@ private Dryrun createDryRun(Exercise exercise, List users, String name) { public Dryrun provisionDryrun(Exercise exercise, List users, String name) { Specification injectFilters = InjectSpecification.forDryrun(exercise.getId()); List injects = injectRepository.findAll(injectFilters); - Assert.isTrue(injects.size() > 0, "Cant create dryrun without injects"); + Assert.isTrue(!injects.isEmpty(), "Cant create dryrun without injects"); Dryrun dryrun = createDryRun(exercise, users, name); List dryInjects = toDryInjects(injects, dryrun); dryInjectRepository.saveAll(dryInjects); diff --git a/openex-api/src/main/java/io/openex/service/ExerciseExpectationService.java b/openex-api/src/main/java/io/openex/service/ExerciseExpectationService.java index 4c51159e64..b2ae186d31 100644 --- a/openex-api/src/main/java/io/openex/service/ExerciseExpectationService.java +++ b/openex-api/src/main/java/io/openex/service/ExerciseExpectationService.java @@ -8,8 +8,8 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; import java.util.List; import static java.time.Instant.now; diff --git a/openex-api/src/main/java/io/openex/service/ImportService.java b/openex-api/src/main/java/io/openex/service/ImportService.java index 3837e707f2..18013259e5 100644 --- a/openex-api/src/main/java/io/openex/service/ImportService.java +++ b/openex-api/src/main/java/io/openex/service/ImportService.java @@ -10,8 +10,8 @@ import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; -import javax.annotation.Resource; -import javax.transaction.Transactional; +import jakarta.annotation.Resource; +import jakarta.transaction.Transactional; import java.io.File; import java.io.InputStream; import java.util.*; diff --git a/openex-api/src/main/java/io/openex/service/MailingService.java b/openex-api/src/main/java/io/openex/service/MailingService.java index 21691b84ac..ffd0b1bae5 100644 --- a/openex-api/src/main/java/io/openex/service/MailingService.java +++ b/openex-api/src/main/java/io/openex/service/MailingService.java @@ -15,8 +15,8 @@ import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Service; -import javax.annotation.Resource; -import javax.validation.constraints.NotNull; +import jakarta.annotation.Resource; +import jakarta.validation.constraints.NotNull; import java.util.List; import java.util.Optional; diff --git a/openex-api/src/main/java/io/openex/service/UserService.java b/openex-api/src/main/java/io/openex/service/UserService.java index 3ffe85855c..a9d25bdbdc 100644 --- a/openex-api/src/main/java/io/openex/service/UserService.java +++ b/openex-api/src/main/java/io/openex/service/UserService.java @@ -17,7 +17,7 @@ import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -32,7 +32,7 @@ @Service public class UserService { - private final Argon2PasswordEncoder passwordEncoder = new Argon2PasswordEncoder(); + private final Argon2PasswordEncoder passwordEncoder = Argon2PasswordEncoder.defaultsForSpringSecurity_v5_8(); private UserRepository userRepository; private TokenRepository tokenRepository; private TagRepository tagRepository; diff --git a/openex-api/src/main/java/io/openex/service/VariableService.java b/openex-api/src/main/java/io/openex/service/VariableService.java index 29b4c69146..e8fecffb11 100644 --- a/openex-api/src/main/java/io/openex/service/VariableService.java +++ b/openex-api/src/main/java/io/openex/service/VariableService.java @@ -8,8 +8,8 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; import java.util.List; import static java.time.Instant.now; diff --git a/openex-api/src/main/java/org/apache/commons/mail/util/MimeMessageParser.java b/openex-api/src/main/java/org/apache/commons/mail/util/MimeMessageParser.java new file mode 100644 index 0000000000..45396b7405 --- /dev/null +++ b/openex-api/src/main/java/org/apache/commons/mail/util/MimeMessageParser.java @@ -0,0 +1,455 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.mail.util; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import jakarta.activation.DataHandler; +import jakarta.activation.DataSource; +import jakarta.mail.Message; +import jakarta.mail.MessagingException; +import jakarta.mail.Multipart; +import jakarta.mail.Part; +import jakarta.mail.internet.ContentType; +import jakarta.mail.internet.InternetAddress; +import jakarta.mail.internet.MimeBodyPart; +import jakarta.mail.internet.MimeMessage; +import jakarta.mail.internet.MimePart; +import jakarta.mail.internet.MimeUtility; +import jakarta.mail.internet.ParseException; +import jakarta.mail.util.ByteArrayDataSource; + +/** + * Parses a MimeMessage and stores the individual parts such a plain text, + * HTML text and attachments. + * + * @since 1.3 + */ +public class MimeMessageParser +{ + /** The MimeMessage to convert */ + private final MimeMessage mimeMessage; + + /** Plain mail content from MimeMessage */ + private String plainContent; + + /** Html mail content from MimeMessage */ + private String htmlContent; + + /** List of attachments of MimeMessage */ + private final List attachmentList; + + /** Attachments stored by their content-id */ + private final Map cidMap; + + /** Is this a Multipart email */ + private boolean isMultiPart; + + /** + * Constructs an instance with the MimeMessage to be extracted. + * + * @param message the message to parse + */ + public MimeMessageParser(final MimeMessage message) + { + attachmentList = new ArrayList<>(); + cidMap = new HashMap<>(); + this.mimeMessage = message; + this.isMultiPart = false; + } + + /** + * Does the actual extraction. + * + * @return this instance + * @throws Exception parsing the mime message failed + */ + public MimeMessageParser parse() throws Exception + { + this.parse(null, mimeMessage); + return this; + } + + /** + * @return the 'to' recipients of the message + * @throws Exception determining the recipients failed + */ + public List getTo() throws Exception + { + final jakarta.mail.Address[] recipients = this.mimeMessage.getRecipients(Message.RecipientType.TO); + return recipients != null ? Arrays.asList(recipients) : new ArrayList(); + } + + /** + * @return the 'cc' recipients of the message + * @throws Exception determining the recipients failed + */ + public List getCc() throws Exception + { + final jakarta.mail.Address[] recipients = this.mimeMessage.getRecipients(Message.RecipientType.CC); + return recipients != null ? Arrays.asList(recipients) : new ArrayList(); + } + + /** + * @return the 'bcc' recipients of the message + * @throws Exception determining the recipients failed + */ + public List getBcc() throws Exception + { + final jakarta.mail.Address[] recipients = this.mimeMessage.getRecipients(Message.RecipientType.BCC); + return recipients != null ? Arrays.asList(recipients) : new ArrayList(); + } + + /** + * @return the 'from' field of the message + * @throws Exception parsing the mime message failed + */ + public String getFrom() throws Exception + { + final jakarta.mail.Address[] addresses = this.mimeMessage.getFrom(); + if (addresses == null || addresses.length == 0) + { + return null; + } + return ((InternetAddress) addresses[0]).getAddress(); + } + + /** + * @return the 'replyTo' address of the email + * @throws Exception parsing the mime message failed + */ + public String getReplyTo() throws Exception + { + final jakarta.mail.Address[] addresses = this.mimeMessage.getReplyTo(); + if (addresses == null || addresses.length == 0) + { + return null; + } + return ((InternetAddress) addresses[0]).getAddress(); + } + + /** + * @return the mail subject + * @throws Exception parsing the mime message failed + */ + public String getSubject() throws Exception + { + return this.mimeMessage.getSubject(); + } + + /** + * Extracts the content of a MimeMessage recursively. + * + * @param parent the parent multi-part + * @param part the current MimePart + * @throws MessagingException parsing the MimeMessage failed + * @throws IOException parsing the MimeMessage failed + */ + protected void parse(final Multipart parent, final MimePart part) + throws MessagingException, IOException + { + if (isMimeType(part, "text/plain") && plainContent == null + && !Part.ATTACHMENT.equalsIgnoreCase(part.getDisposition())) + { + plainContent = (String) part.getContent(); + } + else + { + if (isMimeType(part, "text/html") && htmlContent == null + && !Part.ATTACHMENT.equalsIgnoreCase(part.getDisposition())) + { + htmlContent = (String) part.getContent(); + } + else + { + if (isMimeType(part, "multipart/*")) + { + this.isMultiPart = true; + final Multipart mp = (Multipart) part.getContent(); + final int count = mp.getCount(); + + // iterate over all MimeBodyPart + + for (int i = 0; i < count; i++) + { + parse(mp, (MimeBodyPart) mp.getBodyPart(i)); + } + } + else + { + final String cid = stripContentId(part.getContentID()); + final DataSource ds = createDataSource(parent, part); + if (cid != null) + { + this.cidMap.put(cid, ds); + } + this.attachmentList.add(ds); + } + } + } + } + + /** + * Strips the content id of any whitespace and angle brackets. + * @param contentId the string to strip + * @return a stripped version of the content id + */ + private String stripContentId(final String contentId) + { + if (contentId == null) + { + return null; + } + return contentId.trim().replaceAll("[\\<\\>]", ""); + } + + /** + * Checks whether the MimePart contains an object of the given mime type. + * + * @param part the current MimePart + * @param mimeType the mime type to check + * @return {@code true} if the MimePart matches the given mime type, {@code false} otherwise + * @throws MessagingException parsing the MimeMessage failed + * @throws IOException parsing the MimeMessage failed + */ + private boolean isMimeType(final MimePart part, final String mimeType) + throws MessagingException, IOException + { + // Do not use part.isMimeType(String) as it is broken for MimeBodyPart + // and does not really check the actual content type. + + try + { + final ContentType ct = new ContentType(part.getDataHandler().getContentType()); + return ct.match(mimeType); + } + catch (final ParseException ex) + { + return part.getContentType().equalsIgnoreCase(mimeType); + } + } + + /** + * Parses the MimePart to create a DataSource. + * + * @param parent the parent multi-part + * @param part the current part to be processed + * @return the DataSource + * @throws MessagingException creating the DataSource failed + * @throws IOException creating the DataSource failed + */ + protected DataSource createDataSource(final Multipart parent, final MimePart part) + throws MessagingException, IOException + { + final DataHandler dataHandler = part.getDataHandler(); + final DataSource dataSource = dataHandler.getDataSource(); + final String contentType = getBaseMimeType(dataSource.getContentType()); + final byte[] content = this.getContent(dataSource.getInputStream()); + final ByteArrayDataSource result = new ByteArrayDataSource(content, contentType); + final String dataSourceName = getDataSourceName(part, dataSource); + + result.setName(dataSourceName); + return result; + } + + /** @return Returns the mimeMessage. */ + public MimeMessage getMimeMessage() + { + return mimeMessage; + } + + /** @return Returns the isMultiPart. */ + public boolean isMultipart() + { + return isMultiPart; + } + + /** @return Returns the plainContent if any */ + public String getPlainContent() + { + return plainContent; + } + + /** @return Returns the attachmentList. */ + public List getAttachmentList() + { + return attachmentList; + } + + /** + * Returns a collection of all content-ids in the parsed message. + *

+ * The content-ids are stripped of any angle brackets, i.e. "part1" instead + * of "<part1>". + * + * @return the collection of content ids. + * @since 1.3.4 + */ + public Collection getContentIds() + { + return Collections.unmodifiableSet(cidMap.keySet()); + } + + /** @return Returns the htmlContent if any */ + public String getHtmlContent() + { + return htmlContent; + } + + /** @return true if a plain content is available */ + public boolean hasPlainContent() + { + return this.plainContent != null; + } + + /** @return true if HTML content is available */ + public boolean hasHtmlContent() + { + return this.htmlContent != null; + } + + /** @return true if attachments are available */ + public boolean hasAttachments() + { + return !this.attachmentList.isEmpty(); + } + + /** + * Find an attachment using its name. + * + * @param name the name of the attachment + * @return the corresponding datasource or null if nothing was found + */ + public DataSource findAttachmentByName(final String name) + { + DataSource dataSource; + + for (final DataSource element : getAttachmentList()) { + dataSource = element; + if (name.equalsIgnoreCase(dataSource.getName())) + { + return dataSource; + } + } + + return null; + } + + /** + * Find an attachment using its content-id. + *

+ * The content-id must be stripped of any angle brackets, + * i.e. "part1" instead of "<part1>". + * + * @param cid the content-id of the attachment + * @return the corresponding datasource or null if nothing was found + * @since 1.3.4 + */ + public DataSource findAttachmentByCid(final String cid) + { + final DataSource dataSource = cidMap.get(cid); + return dataSource; + } + + /** + * Determines the name of the data source if it is not already set. + * + * @param part the mail part + * @param dataSource the data source + * @return the name of the data source or {@code null} if no name can be determined + * @throws MessagingException accessing the part failed + * @throws UnsupportedEncodingException decoding the text failed + */ + protected String getDataSourceName(final Part part, final DataSource dataSource) + throws MessagingException, UnsupportedEncodingException + { + String result = dataSource.getName(); + + if (result == null || result.isEmpty()) + { + result = part.getFileName(); + } + + if (result != null && !result.isEmpty()) + { + result = MimeUtility.decodeText(result); + } + else + { + result = null; + } + + return result; + } + + /** + * Read the content of the input stream. + * + * @param is the input stream to process + * @return the content of the input stream + * @throws IOException reading the input stream failed + */ + private byte[] getContent(final InputStream is) + throws IOException + { + int ch; + byte[] result; + + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + final BufferedInputStream isReader = new BufferedInputStream(is); + final BufferedOutputStream osWriter = new BufferedOutputStream(os); + + while ((ch = isReader.read()) != -1) + { + osWriter.write(ch); + } + + osWriter.flush(); + result = os.toByteArray(); + osWriter.close(); + + return result; + } + + /** + * Parses the mimeType. + * + * @param fullMimeType the mime type from the mail api + * @return the real mime type + */ + private String getBaseMimeType(final String fullMimeType) + { + final int pos = fullMimeType.indexOf(';'); + if (pos >= 0) + { + return fullMimeType.substring(0, pos); + } + return fullMimeType; + } +} diff --git a/openex-api/src/main/resources/application.properties b/openex-api/src/main/resources/application.properties index 2e15a3fc8e..5abaf332cd 100644 --- a/openex-api/src/main/resources/application.properties +++ b/openex-api/src/main/resources/application.properties @@ -92,7 +92,7 @@ server.servlet.encoding.charset=UTF-8 spring.datasource.url=jdbc:postgresql://... spring.datasource.username=openex spring.datasource.password= -spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQL92Dialect +spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect spring.jpa.hibernate.ddl-auto=validate # spring.jpa.show-sql=true # spring.jpa.properties.hibernate.format_sql=true @@ -172,4 +172,4 @@ lade.password= http.enable=true # Collectors -collector.users.enable=false \ No newline at end of file +collector.users.enable=false diff --git a/openex-api/src/test/java/io/openex/injects/InjectCrudTest.java b/openex-api/src/test/java/io/openex/injects/InjectCrudTest.java index b489bbb5f5..e6cdae23fc 100644 --- a/openex-api/src/test/java/io/openex/injects/InjectCrudTest.java +++ b/openex-api/src/test/java/io/openex/injects/InjectCrudTest.java @@ -10,8 +10,8 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.transaction.TransactionSystemException; -import javax.validation.ConstraintViolation; -import javax.validation.ConstraintViolationException; +import jakarta.validation.ConstraintViolation; +import jakarta.validation.ConstraintViolationException; import java.util.Set; import static io.openex.injects.email.EmailContract.EMAIL_DEFAULT; diff --git a/openex-api/src/test/java/io/openex/injects/email/EmailExecutorTest.java b/openex-api/src/test/java/io/openex/injects/email/EmailExecutorTest.java index beec14a909..ec4aec781d 100644 --- a/openex-api/src/test/java/io/openex/injects/email/EmailExecutorTest.java +++ b/openex-api/src/test/java/io/openex/injects/email/EmailExecutorTest.java @@ -17,7 +17,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import javax.annotation.Resource; +import jakarta.annotation.Resource; import java.util.List; import static io.openex.helper.StreamHelper.fromIterable; diff --git a/openex-api/src/test/resources/application.properties b/openex-api/src/test/resources/application.properties index a4abb14176..0aa984d579 100644 --- a/openex-api/src/test/resources/application.properties +++ b/openex-api/src/test/resources/application.properties @@ -40,7 +40,7 @@ spring.data.rest.basePath=/api spring.datasource.url=jdbc:postgresql://localhost:5433/openex spring.datasource.username=openex spring.datasource.password=openex -spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQL92Dialect +spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect spring.jpa.hibernate.ddl-auto=validate # Minio Properties diff --git a/openex-collectors b/openex-collectors index c5f8ab2eaa..e49eef238c 160000 --- a/openex-collectors +++ b/openex-collectors @@ -1 +1 @@ -Subproject commit c5f8ab2eaaeb99d8a6cbf02b7d38fb82d3f287eb +Subproject commit e49eef238c843c3b87fad63d357ea3510469ee8d diff --git a/openex-dev/docker-compose.yml b/openex-dev/docker-compose.yml index 4a83beec2a..db013f5eb4 100644 --- a/openex-dev/docker-compose.yml +++ b/openex-dev/docker-compose.yml @@ -7,7 +7,7 @@ services: environment: - POSTGRES_PASSWORD=admin ports: - - 5432:5432 + - "5432:5432" openex-dev-minio: container_name: openex-dev-minio image: minio/minio:latest @@ -23,4 +23,4 @@ services: interval: 30s timeout: 20s retries: 3 - restart: unless-stopped \ No newline at end of file + restart: unless-stopped diff --git a/openex-framework/src/main/java/io/openex/contract/Contract.java b/openex-framework/src/main/java/io/openex/contract/Contract.java index 73349ca24c..d93660051e 100644 --- a/openex-framework/src/main/java/io/openex/contract/Contract.java +++ b/openex-framework/src/main/java/io/openex/contract/Contract.java @@ -7,9 +7,9 @@ import lombok.Getter; import lombok.Setter; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; import java.util.ArrayList; import java.util.HashMap; import java.util.List; diff --git a/openex-framework/src/main/java/io/openex/contract/ContractVariable.java b/openex-framework/src/main/java/io/openex/contract/ContractVariable.java index a2cdf1f230..a1793b1ecf 100644 --- a/openex-framework/src/main/java/io/openex/contract/ContractVariable.java +++ b/openex-framework/src/main/java/io/openex/contract/ContractVariable.java @@ -3,8 +3,8 @@ import io.openex.database.model.Variable.VariableType; import lombok.Getter; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; import java.util.List; @Getter diff --git a/openex-framework/src/main/java/io/openex/contract/fields/ContractExpectations.java b/openex-framework/src/main/java/io/openex/contract/fields/ContractExpectations.java index 70e224ce48..355c9719ff 100644 --- a/openex-framework/src/main/java/io/openex/contract/fields/ContractExpectations.java +++ b/openex-framework/src/main/java/io/openex/contract/fields/ContractExpectations.java @@ -4,9 +4,9 @@ import io.openex.model.inject.form.Expectation; import lombok.Getter; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; import java.util.List; import static io.openex.contract.ContractCardinality.Multiple; diff --git a/openex-framework/src/main/java/io/openex/execution/Injector.java b/openex-framework/src/main/java/io/openex/execution/Injector.java index 98fad546e5..3d51528a5c 100644 --- a/openex-framework/src/main/java/io/openex/execution/Injector.java +++ b/openex-framework/src/main/java/io/openex/execution/Injector.java @@ -15,7 +15,7 @@ import org.apache.commons.io.IOUtils; import org.springframework.beans.factory.annotation.Autowired; -import javax.annotation.Resource; +import jakarta.annotation.Resource; import java.io.InputStream; import java.time.Duration; import java.time.Instant; diff --git a/openex-framework/src/main/java/io/openex/execution/ProtectUser.java b/openex-framework/src/main/java/io/openex/execution/ProtectUser.java index 4cc97b43b0..d297a6c41a 100644 --- a/openex-framework/src/main/java/io/openex/execution/ProtectUser.java +++ b/openex-framework/src/main/java/io/openex/execution/ProtectUser.java @@ -3,7 +3,7 @@ import io.openex.database.model.User; import lombok.Data; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; @Data public class ProtectUser { diff --git a/openex-framework/src/main/java/io/openex/model/expectation/ManualExpectation.java b/openex-framework/src/main/java/io/openex/model/expectation/ManualExpectation.java index 719c7f1bdc..1684be6e72 100644 --- a/openex-framework/src/main/java/io/openex/model/expectation/ManualExpectation.java +++ b/openex-framework/src/main/java/io/openex/model/expectation/ManualExpectation.java @@ -5,7 +5,7 @@ import lombok.Getter; import lombok.Setter; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; import java.util.Objects; @Getter diff --git a/openex-framework/src/main/java/io/openex/service/ExecutionContextService.java b/openex-framework/src/main/java/io/openex/service/ExecutionContextService.java index dbfa6891cc..d72d707b03 100644 --- a/openex-framework/src/main/java/io/openex/service/ExecutionContextService.java +++ b/openex-framework/src/main/java/io/openex/service/ExecutionContextService.java @@ -11,9 +11,9 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; -import javax.annotation.Resource; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; +import jakarta.annotation.Resource; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; import java.util.List; import static io.openex.contract.variables.VariableHelper.*; diff --git a/openex-injectors b/openex-injectors index 292cbe1340..d9f99aa235 160000 --- a/openex-injectors +++ b/openex-injectors @@ -1 +1 @@ -Subproject commit 292cbe1340f0fe34b6d0e9d0011a8a32591cb776 +Subproject commit d9f99aa235f5ee730304d9dc8e3dd312a3bf420e diff --git a/openex-model/pom.xml b/openex-model/pom.xml index 6ce81b3013..eaddaed81c 100644 --- a/openex-model/pom.xml +++ b/openex-model/pom.xml @@ -29,22 +29,19 @@ com.fasterxml.jackson.datatype - jackson-datatype-hibernate5 - ${jackson.version} + jackson-datatype-hibernate6 com.fasterxml.jackson.datatype jackson-datatype-jdk8 - ${jackson.version} com.fasterxml.jackson.datatype jackson-datatype-jsr310 - ${jackson.version} io.hypersistence - hypersistence-utils-hibernate-55 + hypersistence-utils-hibernate-63 3.7.0 @@ -53,9 +50,8 @@ ${minio.version} - javax.validation - validation-api - ${validation-api.version} + jakarta.validation + jakarta.validation-api diff --git a/openex-model/src/main/java/io/openex/config/MinioConfig.java b/openex-model/src/main/java/io/openex/config/MinioConfig.java index ad873153d4..f743363fab 100644 --- a/openex-model/src/main/java/io/openex/config/MinioConfig.java +++ b/openex-model/src/main/java/io/openex/config/MinioConfig.java @@ -3,7 +3,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; @Component @ConfigurationProperties(prefix = "minio") diff --git a/openex-model/src/main/java/io/openex/database/audit/ModelBaseListener.java b/openex-model/src/main/java/io/openex/database/audit/ModelBaseListener.java index 5380c8f1d5..735a47bbd0 100644 --- a/openex-model/src/main/java/io/openex/database/audit/ModelBaseListener.java +++ b/openex-model/src/main/java/io/openex/database/audit/ModelBaseListener.java @@ -6,10 +6,10 @@ import org.springframework.context.ApplicationEventPublisher; import org.springframework.stereotype.Component; -import javax.annotation.Resource; -import javax.persistence.PostPersist; -import javax.persistence.PostUpdate; -import javax.persistence.PreRemove; +import jakarta.annotation.Resource; +import jakarta.persistence.PostPersist; +import jakarta.persistence.PostUpdate; +import jakarta.persistence.PreRemove; @Component public class ModelBaseListener { diff --git a/openex-model/src/main/java/io/openex/database/converter/ContentConverter.java b/openex-model/src/main/java/io/openex/database/converter/ContentConverter.java index 5345b60b8e..bc1cbd32d0 100644 --- a/openex-model/src/main/java/io/openex/database/converter/ContentConverter.java +++ b/openex-model/src/main/java/io/openex/database/converter/ContentConverter.java @@ -4,9 +4,9 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; -import javax.annotation.Resource; -import javax.persistence.AttributeConverter; -import javax.persistence.Converter; +import jakarta.annotation.Resource; +import jakarta.persistence.AttributeConverter; +import jakarta.persistence.Converter; import java.io.IOException; @Converter @@ -35,4 +35,4 @@ public ObjectNode convertToEntityAttribute(String dbData) { } } -} \ No newline at end of file +} diff --git a/openex-model/src/main/java/io/openex/database/converter/ExecutionConverter.java b/openex-model/src/main/java/io/openex/database/converter/ExecutionConverter.java index 0147c8738f..43a4211657 100644 --- a/openex-model/src/main/java/io/openex/database/converter/ExecutionConverter.java +++ b/openex-model/src/main/java/io/openex/database/converter/ExecutionConverter.java @@ -4,9 +4,9 @@ import com.fasterxml.jackson.databind.ObjectMapper; import io.openex.database.model.Execution; -import javax.annotation.Resource; -import javax.persistence.AttributeConverter; -import javax.persistence.Converter; +import jakarta.annotation.Resource; +import jakarta.persistence.AttributeConverter; +import jakarta.persistence.Converter; import java.io.IOException; @Converter(autoApply = true) @@ -38,4 +38,4 @@ public Execution convertToEntityAttribute(String dbData) { } } -} \ No newline at end of file +} diff --git a/openex-model/src/main/java/io/openex/database/converter/PostgreSqlStringArrayType.java b/openex-model/src/main/java/io/openex/database/converter/PostgreSqlStringArrayType.java index 7dd9942530..85b0f72594 100644 --- a/openex-model/src/main/java/io/openex/database/converter/PostgreSqlStringArrayType.java +++ b/openex-model/src/main/java/io/openex/database/converter/PostgreSqlStringArrayType.java @@ -1,6 +1,5 @@ package io.openex.database.converter; -import org.hibernate.HibernateException; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.usertype.UserType; @@ -8,76 +7,76 @@ import java.sql.*; import java.util.Arrays; -public class PostgreSqlStringArrayType implements UserType { +public class PostgreSqlStringArrayType implements UserType { - @Override - public int[] sqlTypes() { - return new int[]{Types.ARRAY}; - } + @Override + public int getSqlType() { + return Types.ARRAY; + } - @Override - public Class returnedClass() { - return String[].class; - } + @Override + public Class returnedClass() { + return String[].class; + } - @Override - public boolean equals(Object x, Object y) throws HibernateException { - if (x instanceof String[] && y instanceof String[]) { - return Arrays.deepEquals((String[])x, (String[])y); - } else { - return false; - } + @Override + public boolean equals(String[] x, String[] y) { + if (x instanceof String[] && y instanceof String[]) { + return Arrays.deepEquals(x, y); + } else { + return false; } + } - @Override - public int hashCode(Object x) throws HibernateException { - return Arrays.hashCode((String[])x); - } + @Override + public int hashCode(String[] x) { + return Arrays.hashCode(x); + } - @Override - public Object nullSafeGet(ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner) - throws HibernateException, SQLException { - Array array = rs.getArray(names[0]); - return array != null ? array.getArray() : null; - } + @Override + public String[] nullSafeGet(ResultSet rs, int position, SharedSessionContractImplementor session, + Object owner) throws SQLException { + Array array = rs.getArray(position); + return array != null ? (String[]) array.getArray() : null; + } - @Override - public void nullSafeSet(PreparedStatement st, Object value, int index, SharedSessionContractImplementor session) - throws HibernateException, SQLException { - if (value != null && st != null) { - Array array = session.connection().createArrayOf("text", (String[])value); - st.setArray(index, array); - } else { - st.setNull(index, sqlTypes()[0]); - } + @Override + public void nullSafeSet(PreparedStatement st, String[] value, int index, + SharedSessionContractImplementor session) throws SQLException { + if (st != null) { + if (value != null) { + Array array = session.getJdbcConnectionAccess().obtainConnection() + .createArrayOf("text", value); + st.setArray(index, array); + } else { + st.setNull(index, Types.ARRAY); + } } + } - @Override - public Object deepCopy(Object value) throws HibernateException { - if (value != null) { - String[] a = (String[]) value; - return Arrays.copyOf(a, a.length); - } - return null; - } + @Override + public String[] deepCopy(String[] value) { + return value != null ? Arrays.copyOf(value, value.length) : null; + } - @Override - public boolean isMutable() { - return false; - } + @Override + public boolean isMutable() { + return false; + } - @Override - public Serializable disassemble(Object value) throws HibernateException { - return (Serializable) value; - } + @Override + public Serializable disassemble(String[] value) { + return value; + } - @Override - public Object assemble(Serializable cached, Object owner) throws HibernateException { - return cached; - } - @Override - public Object replace(Object original, Object target, Object owner) throws HibernateException { - return original; - } + @Override + public String[] assemble(Serializable cached, Object owner) { + return (String[]) cached; + } + + @Override + public String[] replace(String[] detached, String[] managed, Object owner) { + return detached; + } } diff --git a/openex-model/src/main/java/io/openex/database/model/Article.java b/openex-model/src/main/java/io/openex/database/model/Article.java index 2d403073b2..8f3713dacd 100644 --- a/openex-model/src/main/java/io/openex/database/model/Article.java +++ b/openex-model/src/main/java/io/openex/database/model/Article.java @@ -6,9 +6,10 @@ import io.openex.database.audit.ModelBaseListener; import io.openex.helper.MonoIdDeserializer; import io.openex.helper.MultiIdDeserializer; -import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.UuidGenerator; + +import jakarta.persistence.*; -import javax.persistence.*; import java.time.Instant; import java.util.ArrayList; import java.util.List; @@ -23,7 +24,7 @@ public class Article implements Base { @Id @Column(name = "article_id") @GeneratedValue(generator = "UUID") - @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + @UuidGenerator @JsonProperty("article_id") private String id; diff --git a/openex-model/src/main/java/io/openex/database/model/AttackPattern.java b/openex-model/src/main/java/io/openex/database/model/AttackPattern.java index 59d9359ca0..caa265fdf2 100644 --- a/openex-model/src/main/java/io/openex/database/model/AttackPattern.java +++ b/openex-model/src/main/java/io/openex/database/model/AttackPattern.java @@ -2,16 +2,15 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import io.hypersistence.utils.hibernate.type.array.ListArrayType; import io.openex.database.audit.ModelBaseListener; import io.openex.helper.MonoIdDeserializer; +import jakarta.persistence.*; +import jakarta.validation.constraints.NotBlank; import lombok.Getter; import lombok.Setter; -import org.hibernate.annotations.GenericGenerator; import org.hibernate.annotations.Type; +import org.hibernate.annotations.UuidGenerator; -import javax.persistence.*; -import javax.validation.constraints.NotBlank; import java.time.Instant; import java.util.ArrayList; import java.util.List; @@ -30,7 +29,7 @@ public class AttackPattern implements Base { @Id @Column(name = "attack_pattern_id") @GeneratedValue(generator = "UUID") - @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + @UuidGenerator @JsonProperty("attack_pattern_id") @NotBlank private String id; @@ -57,18 +56,14 @@ public class AttackPattern implements Base { @Getter @Setter - @Type(type = "list-array") - // @Type(ListArrayType.class) - // TODO: For migration to Hibernate 6 + @Type(value = io.openex.database.converter.PostgreSqlStringArrayType.class) @Column(name = "attack_pattern_platforms", columnDefinition = "text[]") @JsonProperty("attack_pattern_platforms") private List platforms = new ArrayList<>(); @Getter @Setter - @Type(type = "list-array") - // @Type(ListArrayType.class) - // TODO: For migration to Hibernate 6 + @Type(value = io.openex.database.converter.PostgreSqlStringArrayType.class) @Column(name = "attack_pattern_permissions_required") @JsonProperty("attack_pattern_permissions_required") private ArrayList permissionsRequired = new ArrayList<>(); diff --git a/openex-model/src/main/java/io/openex/database/model/Base.java b/openex-model/src/main/java/io/openex/database/model/Base.java index 406b0756f4..b3e5d595ae 100644 --- a/openex-model/src/main/java/io/openex/database/model/Base.java +++ b/openex-model/src/main/java/io/openex/database/model/Base.java @@ -2,7 +2,7 @@ import org.springframework.beans.BeanUtils; -import javax.persistence.Transient; +import jakarta.persistence.Transient; public interface Base { String getId(); diff --git a/openex-model/src/main/java/io/openex/database/model/Challenge.java b/openex-model/src/main/java/io/openex/database/model/Challenge.java index 15760f9736..4505fe8c4d 100644 --- a/openex-model/src/main/java/io/openex/database/model/Challenge.java +++ b/openex-model/src/main/java/io/openex/database/model/Challenge.java @@ -5,9 +5,9 @@ import io.openex.database.audit.ModelBaseListener; import io.openex.helper.MultiIdDeserializer; import io.openex.helper.MultiModelDeserializer; -import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.UuidGenerator; -import javax.persistence.*; +import jakarta.persistence.*; import java.time.Instant; import java.util.ArrayList; import java.util.List; @@ -22,7 +22,7 @@ public class Challenge implements Base { @Id @Column(name = "challenge_id") @GeneratedValue(generator = "UUID") - @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + @UuidGenerator @JsonProperty("challenge_id") private String id; diff --git a/openex-model/src/main/java/io/openex/database/model/ChallengeFlag.java b/openex-model/src/main/java/io/openex/database/model/ChallengeFlag.java index 720a48542f..bf3b828793 100644 --- a/openex-model/src/main/java/io/openex/database/model/ChallengeFlag.java +++ b/openex-model/src/main/java/io/openex/database/model/ChallengeFlag.java @@ -4,9 +4,9 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize; import io.openex.database.audit.ModelBaseListener; import io.openex.helper.MonoIdDeserializer; -import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.UuidGenerator; -import javax.persistence.*; +import jakarta.persistence.*; import java.time.Instant; import java.util.Objects; @@ -26,7 +26,7 @@ public enum FLAG_TYPE { @Id @Column(name = "flag_id") @GeneratedValue(generator = "UUID") - @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + @UuidGenerator @JsonProperty("flag_id") private String id; diff --git a/openex-model/src/main/java/io/openex/database/model/Channel.java b/openex-model/src/main/java/io/openex/database/model/Channel.java index 4adb11770c..4960858265 100644 --- a/openex-model/src/main/java/io/openex/database/model/Channel.java +++ b/openex-model/src/main/java/io/openex/database/model/Channel.java @@ -4,9 +4,9 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize; import io.openex.database.audit.ModelBaseListener; import io.openex.helper.MonoIdDeserializer; -import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.UuidGenerator; -import javax.persistence.*; +import jakarta.persistence.*; import java.time.Instant; import java.util.ArrayList; import java.util.List; @@ -21,7 +21,7 @@ public class Channel implements Base { @Id @Column(name = "channel_id") @GeneratedValue(generator = "UUID") - @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + @UuidGenerator @JsonProperty("channel_id") private String id; diff --git a/openex-model/src/main/java/io/openex/database/model/Comcheck.java b/openex-model/src/main/java/io/openex/database/model/Comcheck.java index d9e38de398..65c7bd82f4 100644 --- a/openex-model/src/main/java/io/openex/database/model/Comcheck.java +++ b/openex-model/src/main/java/io/openex/database/model/Comcheck.java @@ -5,9 +5,9 @@ import io.openex.database.audit.ModelBaseListener; import io.openex.helper.MonoIdDeserializer; import io.openex.helper.MultiIdDeserializer; -import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.UuidGenerator; -import javax.persistence.*; +import jakarta.persistence.*; import java.time.Instant; import java.util.ArrayList; import java.util.List; @@ -27,7 +27,7 @@ public enum COMCHECK_STATUS { @Id @Column(name = "comcheck_id") @GeneratedValue(generator = "UUID") - @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + @UuidGenerator @JsonProperty("comcheck_id") private String id; diff --git a/openex-model/src/main/java/io/openex/database/model/ComcheckStatus.java b/openex-model/src/main/java/io/openex/database/model/ComcheckStatus.java index fd5c012780..e9180bba16 100644 --- a/openex-model/src/main/java/io/openex/database/model/ComcheckStatus.java +++ b/openex-model/src/main/java/io/openex/database/model/ComcheckStatus.java @@ -4,9 +4,9 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize; import io.openex.database.audit.ModelBaseListener; import io.openex.helper.MonoIdDeserializer; -import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.UuidGenerator; -import javax.persistence.*; +import jakarta.persistence.*; import java.time.Instant; import java.util.Objects; import java.util.Optional; @@ -28,7 +28,7 @@ public enum CHECK_STATUS { @Id @Column(name = "status_id") @GeneratedValue(generator = "UUID") - @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + @UuidGenerator @JsonProperty("comcheckstatus_id") private String id; diff --git a/openex-model/src/main/java/io/openex/database/model/Communication.java b/openex-model/src/main/java/io/openex/database/model/Communication.java index ba1092d9bf..82c0c6d2e0 100644 --- a/openex-model/src/main/java/io/openex/database/model/Communication.java +++ b/openex-model/src/main/java/io/openex/database/model/Communication.java @@ -6,10 +6,10 @@ import io.openex.database.audit.ModelBaseListener; import io.openex.helper.MonoIdDeserializer; import io.openex.helper.MultiIdDeserializer; -import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.UuidGenerator; import org.hibernate.annotations.Type; -import javax.persistence.*; +import jakarta.persistence.*; import java.time.Instant; import java.util.ArrayList; import java.util.List; @@ -25,7 +25,7 @@ public class Communication implements Base { @Id @Column(name = "communication_id") @GeneratedValue(generator = "UUID") - @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + @UuidGenerator @JsonProperty("communication_id") private String id; @@ -53,7 +53,7 @@ public class Communication implements Base { @JsonProperty("communication_content_html") private String contentHtml; - @Type(type = "io.openex.database.converter.PostgreSqlStringArrayType") + @Type(value = io.openex.database.converter.PostgreSqlStringArrayType.class) @Column(name = "communication_attachments", columnDefinition = "text[]") @JsonProperty("communication_attachments") private String[] attachments; diff --git a/openex-model/src/main/java/io/openex/database/model/Document.java b/openex-model/src/main/java/io/openex/database/model/Document.java index 596d73b61a..c7019dda81 100644 --- a/openex-model/src/main/java/io/openex/database/model/Document.java +++ b/openex-model/src/main/java/io/openex/database/model/Document.java @@ -5,9 +5,9 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize; import io.openex.database.audit.ModelBaseListener; import io.openex.helper.MultiIdDeserializer; -import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.UuidGenerator; -import javax.persistence.*; +import jakarta.persistence.*; import java.util.ArrayList; import java.util.List; import java.util.Objects; @@ -19,7 +19,7 @@ public class Document implements Base { @Id @Column(name = "document_id") @GeneratedValue(generator = "UUID") - @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + @UuidGenerator @JsonProperty("document_id") private String id; diff --git a/openex-model/src/main/java/io/openex/database/model/DryInject.java b/openex-model/src/main/java/io/openex/database/model/DryInject.java index ccbec4796e..9886d28895 100644 --- a/openex-model/src/main/java/io/openex/database/model/DryInject.java +++ b/openex-model/src/main/java/io/openex/database/model/DryInject.java @@ -6,9 +6,9 @@ import io.openex.helper.MonoIdDeserializer; import lombok.Getter; import lombok.Setter; -import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.UuidGenerator; -import javax.persistence.*; +import jakarta.persistence.*; import java.time.Instant; import java.util.Comparator; import java.util.Objects; @@ -21,14 +21,14 @@ @EntityListeners(ModelBaseListener.class) public class DryInject implements Base, Injection { - public static Comparator executionComparator = Comparator.comparing(o -> o.getDate().orElseThrow()); + public static final Comparator executionComparator = Comparator.comparing(o -> o.getDate().orElseThrow()); @Getter @Setter @Id @Column(name = "dryinject_id") @GeneratedValue(generator = "UUID") - @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + @UuidGenerator @JsonProperty("dryinject_id") private String id; diff --git a/openex-model/src/main/java/io/openex/database/model/DryInjectStatus.java b/openex-model/src/main/java/io/openex/database/model/DryInjectStatus.java index a73c6de17a..bc0c3e3345 100644 --- a/openex-model/src/main/java/io/openex/database/model/DryInjectStatus.java +++ b/openex-model/src/main/java/io/openex/database/model/DryInjectStatus.java @@ -3,9 +3,9 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import io.openex.database.converter.ExecutionConverter; -import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.UuidGenerator; -import javax.persistence.*; +import jakarta.persistence.*; import java.time.Instant; import java.util.Objects; @@ -17,7 +17,7 @@ public class DryInjectStatus implements Base { @Id @Column(name = "status_id") @GeneratedValue(generator = "UUID") - @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + @UuidGenerator @JsonProperty("status_id") private String id; diff --git a/openex-model/src/main/java/io/openex/database/model/Dryrun.java b/openex-model/src/main/java/io/openex/database/model/Dryrun.java index 0be4bc5c1f..d03350abfc 100644 --- a/openex-model/src/main/java/io/openex/database/model/Dryrun.java +++ b/openex-model/src/main/java/io/openex/database/model/Dryrun.java @@ -6,9 +6,9 @@ import io.openex.database.audit.ModelBaseListener; import io.openex.helper.MonoIdDeserializer; import io.openex.helper.MultiIdDeserializer; -import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.UuidGenerator; -import javax.persistence.*; +import jakarta.persistence.*; import java.time.Instant; import java.util.ArrayList; import java.util.List; @@ -22,7 +22,7 @@ public class Dryrun implements Base { @Id @Column(name = "dryrun_id") @GeneratedValue(generator = "UUID") - @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + @UuidGenerator @JsonProperty("dryrun_id") private String id; diff --git a/openex-model/src/main/java/io/openex/database/model/Evaluation.java b/openex-model/src/main/java/io/openex/database/model/Evaluation.java index c3856570ee..56035ce60a 100644 --- a/openex-model/src/main/java/io/openex/database/model/Evaluation.java +++ b/openex-model/src/main/java/io/openex/database/model/Evaluation.java @@ -4,9 +4,9 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize; import io.openex.database.audit.ModelBaseListener; import io.openex.helper.MonoIdDeserializer; -import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.UuidGenerator; -import javax.persistence.*; +import jakarta.persistence.*; import java.time.Instant; import java.util.Objects; @@ -19,7 +19,7 @@ public class Evaluation implements Base { @Id @Column(name = "evaluation_id") @GeneratedValue(generator = "UUID") - @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + @UuidGenerator @JsonProperty("evaluation_id") private String id; diff --git a/openex-model/src/main/java/io/openex/database/model/Exercise.java b/openex-model/src/main/java/io/openex/database/model/Exercise.java index ddadbe7139..e37bc37ac1 100644 --- a/openex-model/src/main/java/io/openex/database/model/Exercise.java +++ b/openex-model/src/main/java/io/openex/database/model/Exercise.java @@ -9,10 +9,10 @@ import io.openex.helper.MultiModelDeserializer; import lombok.Getter; import lombok.Setter; -import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.UuidGenerator; -import javax.persistence.*; -import javax.validation.constraints.NotBlank; +import jakarta.persistence.*; +import jakarta.validation.constraints.NotBlank; import java.time.Instant; import java.util.*; @@ -38,7 +38,7 @@ public enum STATUS { @Id @Column(name = "exercise_id") @GeneratedValue(generator = "UUID") - @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + @UuidGenerator @JsonProperty("exercise_id") private String id; diff --git a/openex-model/src/main/java/io/openex/database/model/ExerciseTeamUser.java b/openex-model/src/main/java/io/openex/database/model/ExerciseTeamUser.java index 54ea002e62..f2ef00eece 100644 --- a/openex-model/src/main/java/io/openex/database/model/ExerciseTeamUser.java +++ b/openex-model/src/main/java/io/openex/database/model/ExerciseTeamUser.java @@ -4,8 +4,8 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import io.openex.helper.MonoIdDeserializer; +import jakarta.persistence.*; -import javax.persistence.*; import java.util.Objects; @Entity diff --git a/openex-model/src/main/java/io/openex/database/model/ExerciseTeamUserId.java b/openex-model/src/main/java/io/openex/database/model/ExerciseTeamUserId.java index 251f51cdf9..a6904e4786 100644 --- a/openex-model/src/main/java/io/openex/database/model/ExerciseTeamUserId.java +++ b/openex-model/src/main/java/io/openex/database/model/ExerciseTeamUserId.java @@ -1,6 +1,7 @@ package io.openex.database.model; -import javax.persistence.Embeddable; +import jakarta.persistence.Embeddable; + import java.io.Serial; import java.io.Serializable; import java.util.Objects; diff --git a/openex-model/src/main/java/io/openex/database/model/Grant.java b/openex-model/src/main/java/io/openex/database/model/Grant.java index 1177235e01..6413b89a39 100644 --- a/openex-model/src/main/java/io/openex/database/model/Grant.java +++ b/openex-model/src/main/java/io/openex/database/model/Grant.java @@ -3,9 +3,9 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import io.openex.helper.MonoIdDeserializer; -import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.UuidGenerator; -import javax.persistence.*; +import jakarta.persistence.*; import java.util.Objects; @Entity @@ -20,7 +20,7 @@ public enum GRANT_TYPE { @Id @Column(name = "grant_id") @GeneratedValue(generator = "UUID") - @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + @UuidGenerator @JsonProperty("grant_id") private String id; diff --git a/openex-model/src/main/java/io/openex/database/model/Group.java b/openex-model/src/main/java/io/openex/database/model/Group.java index cca25e393c..e471f1f8ce 100644 --- a/openex-model/src/main/java/io/openex/database/model/Group.java +++ b/openex-model/src/main/java/io/openex/database/model/Group.java @@ -7,9 +7,9 @@ import io.openex.helper.MultiModelDeserializer; import org.hibernate.annotations.Fetch; import org.hibernate.annotations.FetchMode; -import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.UuidGenerator; -import javax.persistence.*; +import jakarta.persistence.*; import java.util.ArrayList; import java.util.List; import java.util.Objects; @@ -21,7 +21,7 @@ public class Group implements Base { @Id @Column(name = "group_id") @GeneratedValue(generator = "UUID") - @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + @UuidGenerator @JsonProperty("group_id") private String id; diff --git a/openex-model/src/main/java/io/openex/database/model/Inject.java b/openex-model/src/main/java/io/openex/database/model/Inject.java index f9561ccc71..e75cf9a952 100644 --- a/openex-model/src/main/java/io/openex/database/model/Inject.java +++ b/openex-model/src/main/java/io/openex/database/model/Inject.java @@ -9,13 +9,13 @@ import io.openex.helper.MonoIdDeserializer; import io.openex.helper.MultiIdDeserializer; import io.openex.helper.MultiModelDeserializer; +import jakarta.persistence.*; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; import lombok.Getter; import lombok.Setter; -import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.UuidGenerator; -import javax.persistence.*; -import javax.validation.constraints.Min; -import javax.validation.constraints.NotNull; import java.time.Instant; import java.util.*; @@ -28,309 +28,309 @@ @EntityListeners(ModelBaseListener.class) public class Inject implements Base, Injection { - public static final int SPEED_STANDARD = 1; // Standard speed define by the user. - - public static Comparator executionComparator = (o1, o2) -> { - if (o1.getDate().isPresent() && o2.getDate().isPresent()) { - return o1.getDate().get().compareTo(o2.getDate().get()); - } - return o1.getId().compareTo(o2.getId()); - }; - - @Getter - @Setter - @Id - @Column(name = "inject_id") - @GeneratedValue(generator = "UUID") - @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") - @JsonProperty("inject_id") - private String id; - - @Getter - @Setter - @Column(name = "inject_title") - @JsonProperty("inject_title") - private String title; - - @Getter - @Setter - @Column(name = "inject_description") - @JsonProperty("inject_description") - private String description; - - @Getter - @Setter - @Column(name = "inject_contract") - @JsonProperty("inject_contract") - private String contract; - - @Getter - @Setter - @Column(name = "inject_country") - @JsonProperty("inject_country") - private String country; - - @Getter - @Setter - @Column(name = "inject_city") - @JsonProperty("inject_city") - private String city; - - @Getter - @Setter - @Column(name = "inject_enabled") - @JsonProperty("inject_enabled") - private boolean enabled = true; - - @Getter - @Setter - @Column(name = "inject_type", updatable = false) - @JsonProperty("inject_type") - private String type; - - @Getter - @Setter - @Column(name = "inject_content") - @Convert(converter = ContentConverter.class) - @JsonProperty("inject_content") - private ObjectNode content; - - @Getter - @Setter - @Column(name = "inject_created_at") - @JsonProperty("inject_created_at") - private Instant createdAt = now(); - - @Getter - @Setter - @Column(name = "inject_updated_at") - @JsonProperty("inject_updated_at") - private Instant updatedAt = now(); - - @Getter - @Setter - @Column(name = "inject_all_teams") - @JsonProperty("inject_all_teams") - private boolean allTeams; - - @Getter - @Setter - @ManyToOne(fetch = FetchType.EAGER) - @JoinColumn(name = "inject_exercise") - @JsonSerialize(using = MonoIdDeserializer.class) - @JsonProperty("inject_exercise") - private Exercise exercise; - - @Getter - @Setter - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "inject_depends_from_another") - @JsonSerialize(using = MonoIdDeserializer.class) - @JsonProperty("inject_depends_on") - private Inject dependsOn; - - @Getter - @Setter - @Column(name = "inject_depends_duration") - @JsonProperty("inject_depends_duration") - @NotNull - @Min(value = 0L, message = "The value must be positive") - private Long dependsDuration; - - @Getter - @Setter - @ManyToOne(fetch = FetchType.LAZY) - @JsonSerialize(using = MonoIdDeserializer.class) - @JoinColumn(name = "inject_user") - @JsonProperty("inject_user") - private User user; - - // CascadeType.ALL is required here because inject status are embedded - @Setter - @OneToOne(mappedBy = "inject", cascade = CascadeType.ALL, orphanRemoval = true) - @JsonProperty("inject_status") - private InjectStatus status; - - @Getter - @Setter - @ManyToMany(fetch = FetchType.LAZY) - @JoinTable(name = "injects_tags", - joinColumns = @JoinColumn(name = "inject_id"), - inverseJoinColumns = @JoinColumn(name = "tag_id")) - @JsonSerialize(using = MultiIdDeserializer.class) - @JsonProperty("inject_tags") - private List tags = new ArrayList<>(); - - @Getter - @Setter - @ManyToMany(fetch = FetchType.LAZY) - @JoinTable(name = "injects_teams", - joinColumns = @JoinColumn(name = "inject_id"), - inverseJoinColumns = @JoinColumn(name = "team_id")) - @JsonSerialize(using = MultiIdDeserializer.class) - @JsonProperty("inject_teams") - private List teams = new ArrayList<>(); - - // CascadeType.ALL is required here because of complex relationships - @Getter - @Setter - @OneToMany(mappedBy = "inject", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true) - @JsonProperty("inject_documents") - @JsonSerialize(using = MultiModelDeserializer.class) - private List documents = new ArrayList<>(); - - // CascadeType.ALL is required here because communications are embedded - @Getter - @Setter - @OneToMany(mappedBy = "inject", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true) - @JsonProperty("inject_communications") - @JsonSerialize(using = MultiModelDeserializer.class) - private List communications = new ArrayList<>(); - - // CascadeType.ALL is required here because expectations are embedded - @Getter - @Setter - @OneToMany(mappedBy = "inject", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true) - @JsonProperty("inject_expectations") - @JsonSerialize(using = MultiModelDeserializer.class) - private List expectations = new ArrayList<>(); - - // region transient - @Transient - public String getHeader() { - return ofNullable(this.getExercise()).map(Exercise::getHeader).orElse(""); - } - - @Transient - public String getFooter() { - return ofNullable(this.getExercise()).map(Exercise::getFooter).orElse(""); - } - - @JsonIgnore - @Override - public boolean isUserHasAccess(User user) { - return this.getExercise().isUserHasAccess(user); - } - - @JsonIgnore - public void clean() { - this.status = null; - this.communications.clear(); - this.expectations.clear(); - } + public static final int SPEED_STANDARD = 1; // Standard speed define by the user. - @JsonProperty("inject_users_number") - public long getNumberOfTargetUsers() { - if (this.allTeams) { - return getExercise().usersNumber(); - } - return getTeams().stream() - .map(team -> team.getUsersNumberInExercise(getExercise())) - .reduce(Long::sum).orElse(0L); + public static final Comparator executionComparator = (o1, o2) -> { + if (o1.getDate().isPresent() && o2.getDate().isPresent()) { + return o1.getDate().get().compareTo(o2.getDate().get()); } - - @JsonIgnore - public Instant computeInjectDate(Instant source, int speed) { - // Compute origin execution date - Optional dependsOnInject = ofNullable(getDependsOn()); - long duration = ofNullable(getDependsDuration()).orElse(0L) / speed; - Instant dependingStart = dependsOnInject - .map(inject -> inject.computeInjectDate(source, speed)) - .orElse(source); - Instant standardExecutionDate = dependingStart.plusSeconds(duration); - // Compute execution dates with previous terminated pauses - long previousPauseDelay = exercise.getPauses().stream() - .filter(pause -> pause.getDate().isBefore(standardExecutionDate)) - .mapToLong(pause -> pause.getDuration().orElse(0L)).sum(); - Instant afterPausesExecutionDate = standardExecutionDate.plusSeconds(previousPauseDelay); - // Add current pause duration in date computation if needed - long currentPauseDelay = exercise.getCurrentPause() - .map(last -> last.isBefore(afterPausesExecutionDate) ? between(last, now()).getSeconds() : 0L) - .orElse(0L); - long globalPauseDelay = previousPauseDelay + currentPauseDelay; - long minuteAlignModulo = globalPauseDelay % 60; - long alignedPauseDelay = minuteAlignModulo > 0 ? globalPauseDelay + (60 - minuteAlignModulo) : globalPauseDelay; - return standardExecutionDate.plusSeconds(alignedPauseDelay); - } - - @JsonProperty("inject_date") - public Optional getDate() { - if (this.getExercise().getStatus().equals(Exercise.STATUS.CANCELED)) { - return Optional.empty(); - } - return this.getExercise().getStart() - .map(source -> computeInjectDate(source, SPEED_STANDARD)); + return o1.getId().compareTo(o2.getId()); + }; + + @Getter + @Setter + @Id + @Column(name = "inject_id") + @GeneratedValue(generator = "UUID") + @UuidGenerator + @JsonProperty("inject_id") + private String id; + + @Getter + @Setter + @Column(name = "inject_title") + @JsonProperty("inject_title") + private String title; + + @Getter + @Setter + @Column(name = "inject_description") + @JsonProperty("inject_description") + private String description; + + @Getter + @Setter + @Column(name = "inject_contract") + @JsonProperty("inject_contract") + private String contract; + + @Getter + @Setter + @Column(name = "inject_country") + @JsonProperty("inject_country") + private String country; + + @Getter + @Setter + @Column(name = "inject_city") + @JsonProperty("inject_city") + private String city; + + @Getter + @Setter + @Column(name = "inject_enabled") + @JsonProperty("inject_enabled") + private boolean enabled = true; + + @Getter + @Setter + @Column(name = "inject_type", updatable = false) + @JsonProperty("inject_type") + private String type; + + @Getter + @Setter + @Column(name = "inject_content") + @Convert(converter = ContentConverter.class) + @JsonProperty("inject_content") + private ObjectNode content; + + @Getter + @Setter + @Column(name = "inject_created_at") + @JsonProperty("inject_created_at") + private Instant createdAt = now(); + + @Getter + @Setter + @Column(name = "inject_updated_at") + @JsonProperty("inject_updated_at") + private Instant updatedAt = now(); + + @Getter + @Setter + @Column(name = "inject_all_teams") + @JsonProperty("inject_all_teams") + private boolean allTeams; + + @Getter + @Setter + @ManyToOne(fetch = FetchType.EAGER) + @JoinColumn(name = "inject_exercise") + @JsonSerialize(using = MonoIdDeserializer.class) + @JsonProperty("inject_exercise") + private Exercise exercise; + + @Getter + @Setter + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "inject_depends_from_another") + @JsonSerialize(using = MonoIdDeserializer.class) + @JsonProperty("inject_depends_on") + private Inject dependsOn; + + @Getter + @Setter + @Column(name = "inject_depends_duration") + @JsonProperty("inject_depends_duration") + @NotNull + @Min(value = 0L, message = "The value must be positive") + private Long dependsDuration; + + @Getter + @Setter + @ManyToOne(fetch = FetchType.LAZY) + @JsonSerialize(using = MonoIdDeserializer.class) + @JoinColumn(name = "inject_user") + @JsonProperty("inject_user") + private User user; + + // CascadeType.ALL is required here because inject status are embedded + @Setter + @OneToOne(mappedBy = "inject", cascade = CascadeType.ALL, orphanRemoval = true) + @JsonProperty("inject_status") + private InjectStatus status; + + @Getter + @Setter + @ManyToMany(fetch = FetchType.LAZY) + @JoinTable(name = "injects_tags", + joinColumns = @JoinColumn(name = "inject_id"), + inverseJoinColumns = @JoinColumn(name = "tag_id")) + @JsonSerialize(using = MultiIdDeserializer.class) + @JsonProperty("inject_tags") + private List tags = new ArrayList<>(); + + @Getter + @Setter + @ManyToMany(fetch = FetchType.LAZY) + @JoinTable(name = "injects_teams", + joinColumns = @JoinColumn(name = "inject_id"), + inverseJoinColumns = @JoinColumn(name = "team_id")) + @JsonSerialize(using = MultiIdDeserializer.class) + @JsonProperty("inject_teams") + private List teams = new ArrayList<>(); + + // CascadeType.ALL is required here because of complex relationships + @Getter + @Setter + @OneToMany(mappedBy = "inject", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true) + @JsonProperty("inject_documents") + @JsonSerialize(using = MultiModelDeserializer.class) + private List documents = new ArrayList<>(); + + // CascadeType.ALL is required here because communications are embedded + @Getter + @Setter + @OneToMany(mappedBy = "inject", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true) + @JsonProperty("inject_communications") + @JsonSerialize(using = MultiModelDeserializer.class) + private List communications = new ArrayList<>(); + + // CascadeType.ALL is required here because expectations are embedded + @Getter + @Setter + @OneToMany(mappedBy = "inject", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true) + @JsonProperty("inject_expectations") + @JsonSerialize(using = MultiModelDeserializer.class) + private List expectations = new ArrayList<>(); + + // region transient + @Transient + public String getHeader() { + return ofNullable(this.getExercise()).map(Exercise::getHeader).orElse(""); + } + + @Transient + public String getFooter() { + return ofNullable(this.getExercise()).map(Exercise::getFooter).orElse(""); + } + + @JsonIgnore + @Override + public boolean isUserHasAccess(User user) { + return this.getExercise().isUserHasAccess(user); + } + + @JsonIgnore + public void clean() { + this.status = null; + this.communications.clear(); + this.expectations.clear(); + } + + @JsonProperty("inject_users_number") + public long getNumberOfTargetUsers() { + if (this.allTeams) { + return getExercise().usersNumber(); } - - @JsonIgnore - public boolean isNotExecuted() { - return this.getStatus().isEmpty(); + return getTeams().stream() + .map(team -> team.getUsersNumberInExercise(getExercise())) + .reduce(Long::sum).orElse(0L); + } + + @JsonIgnore + public Instant computeInjectDate(Instant source, int speed) { + // Compute origin execution date + Optional dependsOnInject = ofNullable(getDependsOn()); + long duration = ofNullable(getDependsDuration()).orElse(0L) / speed; + Instant dependingStart = dependsOnInject + .map(inject -> inject.computeInjectDate(source, speed)) + .orElse(source); + Instant standardExecutionDate = dependingStart.plusSeconds(duration); + // Compute execution dates with previous terminated pauses + long previousPauseDelay = exercise.getPauses().stream() + .filter(pause -> pause.getDate().isBefore(standardExecutionDate)) + .mapToLong(pause -> pause.getDuration().orElse(0L)).sum(); + Instant afterPausesExecutionDate = standardExecutionDate.plusSeconds(previousPauseDelay); + // Add current pause duration in date computation if needed + long currentPauseDelay = exercise.getCurrentPause() + .map(last -> last.isBefore(afterPausesExecutionDate) ? between(last, now()).getSeconds() : 0L) + .orElse(0L); + long globalPauseDelay = previousPauseDelay + currentPauseDelay; + long minuteAlignModulo = globalPauseDelay % 60; + long alignedPauseDelay = minuteAlignModulo > 0 ? globalPauseDelay + (60 - minuteAlignModulo) : globalPauseDelay; + return standardExecutionDate.plusSeconds(alignedPauseDelay); + } + + @JsonProperty("inject_date") + public Optional getDate() { + if (this.getExercise().getStatus().equals(Exercise.STATUS.CANCELED)) { + return Optional.empty(); } - - @JsonIgnore - public boolean isPastInject() { - return this.getDate().map(date -> date.isBefore(now())).orElse(false); - } - - @JsonIgnore - public boolean isFutureInject() { - return this.getDate().map(date -> date.isAfter(now())).orElse(false); + return this.getExercise().getStart() + .map(source -> computeInjectDate(source, SPEED_STANDARD)); + } + + @JsonIgnore + public boolean isNotExecuted() { + return this.getStatus().isEmpty(); + } + + @JsonIgnore + public boolean isPastInject() { + return this.getDate().map(date -> date.isBefore(now())).orElse(false); + } + + @JsonIgnore + public boolean isFutureInject() { + return this.getDate().map(date -> date.isAfter(now())).orElse(false); + } + // endregion + + public Optional getStatus() { + return ofNullable(this.status); + } + + public List getUserExpectationsForArticle(User user, Article article) { + return this.expectations.stream() + .filter(execution -> execution.getType().equals(InjectExpectation.EXPECTATION_TYPE.ARTICLE)) + .filter(execution -> execution.getArticle().equals(article)) + .filter(execution -> execution.getTeam().getUsers().contains(user)) + .toList(); + } + + @JsonIgnore + public DryInject toDryInject(Dryrun run) { + DryInject dryInject = new DryInject(); + dryInject.setRun(run); + dryInject.setInject(this); + dryInject.setDate(computeInjectDate(run.getDate(), run.getSpeed())); + return dryInject; + } + + @JsonProperty("inject_communications_number") + public long getCommunicationsNumber() { + return this.getCommunications().size(); + } + + @JsonProperty("inject_communications_not_ack_number") + public long getCommunicationsNotAckNumber() { + return this.getCommunications().stream().filter(communication -> !communication.getAck()).count(); + } + + @JsonProperty("inject_sent_at") + public Instant getSentAt() { + if (this.getStatus().isPresent()) { + return this.getStatus().orElseThrow().getDate(); } - // endregion + return null; + } - public Optional getStatus() { - return ofNullable(this.status); + @Override + public boolean equals(Object o) { + if (this == o) { + return true; } - - public List getUserExpectationsForArticle(User user, Article article) { - return this.expectations.stream() - .filter(execution -> execution.getType().equals(InjectExpectation.EXPECTATION_TYPE.ARTICLE)) - .filter(execution -> execution.getArticle().equals(article)) - .filter(execution -> execution.getTeam().getUsers().contains(user)) - .toList(); - } - - @JsonIgnore - public DryInject toDryInject(Dryrun run) { - DryInject dryInject = new DryInject(); - dryInject.setRun(run); - dryInject.setInject(this); - dryInject.setDate(computeInjectDate(run.getDate(), run.getSpeed())); - return dryInject; - } - - @JsonProperty("inject_communications_number") - public long getCommunicationsNumber() { - return this.getCommunications().size(); - } - - @JsonProperty("inject_communications_not_ack_number") - public long getCommunicationsNotAckNumber() { - return this.getCommunications().stream().filter(communication -> !communication.getAck()).count(); - } - - @JsonProperty("inject_sent_at") - public Instant getSentAt() { - if (this.getStatus().isPresent()) { - return this.getStatus().orElseThrow().getDate(); - } - return null; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || !Base.class.isAssignableFrom(o.getClass())) { - return false; - } - Base base = (Base) o; - return id.equals(base.getId()); - } - - @Override - public int hashCode() { - return Objects.hash(id); + if (o == null || !Base.class.isAssignableFrom(o.getClass())) { + return false; } + Base base = (Base) o; + return id.equals(base.getId()); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } } diff --git a/openex-model/src/main/java/io/openex/database/model/InjectDocument.java b/openex-model/src/main/java/io/openex/database/model/InjectDocument.java index 318f728011..d983a07d3a 100644 --- a/openex-model/src/main/java/io/openex/database/model/InjectDocument.java +++ b/openex-model/src/main/java/io/openex/database/model/InjectDocument.java @@ -5,7 +5,7 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize; import io.openex.helper.MonoIdDeserializer; -import javax.persistence.*; +import jakarta.persistence.*; import java.util.Objects; @Entity diff --git a/openex-model/src/main/java/io/openex/database/model/InjectDocumentId.java b/openex-model/src/main/java/io/openex/database/model/InjectDocumentId.java index ba1b08cb21..6aec13859d 100644 --- a/openex-model/src/main/java/io/openex/database/model/InjectDocumentId.java +++ b/openex-model/src/main/java/io/openex/database/model/InjectDocumentId.java @@ -1,6 +1,6 @@ package io.openex.database.model; -import javax.persistence.Embeddable; +import jakarta.persistence.Embeddable; import java.io.Serial; import java.io.Serializable; import java.util.Objects; diff --git a/openex-model/src/main/java/io/openex/database/model/InjectExpectation.java b/openex-model/src/main/java/io/openex/database/model/InjectExpectation.java index 8aa6f04e92..30979791f0 100644 --- a/openex-model/src/main/java/io/openex/database/model/InjectExpectation.java +++ b/openex-model/src/main/java/io/openex/database/model/InjectExpectation.java @@ -4,12 +4,12 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize; import io.openex.database.audit.ModelBaseListener; import io.openex.helper.MonoIdDeserializer; +import jakarta.persistence.*; +import jakarta.validation.constraints.NotBlank; import lombok.Getter; import lombok.Setter; -import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.UuidGenerator; -import javax.persistence.*; -import javax.validation.constraints.NotBlank; import java.time.Instant; import java.util.Objects; @@ -39,7 +39,7 @@ public enum EXPECTATION_TYPE { @NotBlank @Setter @GeneratedValue(generator = "UUID") - @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + @UuidGenerator @Column(name = "inject_expectation_id") @JsonProperty("injectexpectation_id") private String id; diff --git a/openex-model/src/main/java/io/openex/database/model/InjectStatus.java b/openex-model/src/main/java/io/openex/database/model/InjectStatus.java index 3e6d5e8832..8135ced251 100644 --- a/openex-model/src/main/java/io/openex/database/model/InjectStatus.java +++ b/openex-model/src/main/java/io/openex/database/model/InjectStatus.java @@ -5,9 +5,9 @@ import io.openex.database.converter.ExecutionConverter; import lombok.Getter; import lombok.Setter; -import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.UuidGenerator; -import javax.persistence.*; +import jakarta.persistence.*; import java.time.Instant; import java.util.Objects; @@ -22,7 +22,7 @@ public class InjectStatus implements Base { @Id @Column(name = "status_id") @GeneratedValue(generator = "UUID") - @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + @UuidGenerator @JsonProperty("status_id") private String id; diff --git a/openex-model/src/main/java/io/openex/database/model/KillChainPhase.java b/openex-model/src/main/java/io/openex/database/model/KillChainPhase.java index 4d34d285d7..c65303a8ed 100644 --- a/openex-model/src/main/java/io/openex/database/model/KillChainPhase.java +++ b/openex-model/src/main/java/io/openex/database/model/KillChainPhase.java @@ -4,9 +4,10 @@ import io.openex.database.audit.ModelBaseListener; import lombok.Getter; import lombok.Setter; -import org.hibernate.annotations.GenericGenerator; -import javax.persistence.*; +import jakarta.persistence.*; +import org.hibernate.annotations.UuidGenerator; + import java.time.Instant; import java.util.Objects; @@ -21,7 +22,7 @@ public class KillChainPhase implements Base { @Id @Column(name = "phase_id") @GeneratedValue(generator = "UUID") - @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + @UuidGenerator @JsonProperty("phase_id") private String id; diff --git a/openex-model/src/main/java/io/openex/database/model/LessonsAnswer.java b/openex-model/src/main/java/io/openex/database/model/LessonsAnswer.java index 5a17d8e84a..29664ce42a 100644 --- a/openex-model/src/main/java/io/openex/database/model/LessonsAnswer.java +++ b/openex-model/src/main/java/io/openex/database/model/LessonsAnswer.java @@ -4,9 +4,9 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize; import io.openex.database.audit.ModelBaseListener; import io.openex.helper.MonoIdDeserializer; -import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.UuidGenerator; -import javax.persistence.*; +import jakarta.persistence.*; import java.time.Instant; import java.util.Objects; @@ -19,7 +19,7 @@ public class LessonsAnswer implements Base { @Id @Column(name = "lessons_answer_id") @GeneratedValue(generator = "UUID") - @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + @UuidGenerator @JsonProperty("lessonsanswer_id") private String id; diff --git a/openex-model/src/main/java/io/openex/database/model/LessonsCategory.java b/openex-model/src/main/java/io/openex/database/model/LessonsCategory.java index 44224a4498..dbd223bf8e 100644 --- a/openex-model/src/main/java/io/openex/database/model/LessonsCategory.java +++ b/openex-model/src/main/java/io/openex/database/model/LessonsCategory.java @@ -5,9 +5,9 @@ import io.openex.database.audit.ModelBaseListener; import io.openex.helper.MonoIdDeserializer; import io.openex.helper.MultiIdDeserializer; -import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.UuidGenerator; -import javax.persistence.*; +import jakarta.persistence.*; import java.time.Instant; import java.util.ArrayList; import java.util.List; @@ -22,7 +22,7 @@ public class LessonsCategory implements Base { @Id @Column(name = "lessons_category_id") @GeneratedValue(generator = "UUID") - @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + @UuidGenerator @JsonProperty("lessonscategory_id") private String id; diff --git a/openex-model/src/main/java/io/openex/database/model/LessonsQuestion.java b/openex-model/src/main/java/io/openex/database/model/LessonsQuestion.java index f033f42036..7724cc92a8 100644 --- a/openex-model/src/main/java/io/openex/database/model/LessonsQuestion.java +++ b/openex-model/src/main/java/io/openex/database/model/LessonsQuestion.java @@ -5,9 +5,9 @@ import io.openex.database.audit.ModelBaseListener; import io.openex.helper.MonoIdDeserializer; import io.openex.helper.MultiIdDeserializer; -import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.UuidGenerator; -import javax.persistence.*; +import jakarta.persistence.*; import java.time.Instant; import java.util.ArrayList; import java.util.List; @@ -22,7 +22,7 @@ public class LessonsQuestion implements Base { @Id @Column(name = "lessons_question_id") @GeneratedValue(generator = "UUID") - @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + @UuidGenerator @JsonProperty("lessonsquestion_id") private String id; diff --git a/openex-model/src/main/java/io/openex/database/model/LessonsTemplate.java b/openex-model/src/main/java/io/openex/database/model/LessonsTemplate.java index 7923c17f62..84b53366aa 100644 --- a/openex-model/src/main/java/io/openex/database/model/LessonsTemplate.java +++ b/openex-model/src/main/java/io/openex/database/model/LessonsTemplate.java @@ -3,9 +3,9 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import io.openex.database.audit.ModelBaseListener; -import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.UuidGenerator; -import javax.persistence.*; +import jakarta.persistence.*; import java.time.Instant; import java.util.ArrayList; import java.util.List; @@ -20,7 +20,7 @@ public class LessonsTemplate implements Base { @Id @Column(name = "lessons_template_id") @GeneratedValue(generator = "UUID") - @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + @UuidGenerator @JsonProperty("lessonstemplate_id") private String id; diff --git a/openex-model/src/main/java/io/openex/database/model/LessonsTemplateCategory.java b/openex-model/src/main/java/io/openex/database/model/LessonsTemplateCategory.java index 8423dc5dab..5ad9fbb408 100644 --- a/openex-model/src/main/java/io/openex/database/model/LessonsTemplateCategory.java +++ b/openex-model/src/main/java/io/openex/database/model/LessonsTemplateCategory.java @@ -5,9 +5,9 @@ import io.openex.database.audit.ModelBaseListener; import io.openex.helper.MonoIdDeserializer; import io.openex.helper.MultiIdDeserializer; -import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.UuidGenerator; -import javax.persistence.*; +import jakarta.persistence.*; import java.time.Instant; import java.util.ArrayList; import java.util.List; @@ -22,7 +22,7 @@ public class LessonsTemplateCategory implements Base { @Id @Column(name = "lessons_template_category_id") @GeneratedValue(generator = "UUID") - @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + @UuidGenerator @JsonProperty("lessonstemplatecategory_id") private String id; diff --git a/openex-model/src/main/java/io/openex/database/model/LessonsTemplateQuestion.java b/openex-model/src/main/java/io/openex/database/model/LessonsTemplateQuestion.java index 920455a2d5..d142380821 100644 --- a/openex-model/src/main/java/io/openex/database/model/LessonsTemplateQuestion.java +++ b/openex-model/src/main/java/io/openex/database/model/LessonsTemplateQuestion.java @@ -4,9 +4,9 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize; import io.openex.database.audit.ModelBaseListener; import io.openex.helper.MonoIdDeserializer; -import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.UuidGenerator; -import javax.persistence.*; +import jakarta.persistence.*; import java.time.Instant; import java.util.Objects; @@ -19,7 +19,7 @@ public class LessonsTemplateQuestion implements Base { @Id @Column(name = "lessons_template_question_id") @GeneratedValue(generator = "UUID") - @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + @UuidGenerator @JsonProperty("lessonstemplatequestion_id") private String id; diff --git a/openex-model/src/main/java/io/openex/database/model/Log.java b/openex-model/src/main/java/io/openex/database/model/Log.java index 94a686591c..507a588b89 100644 --- a/openex-model/src/main/java/io/openex/database/model/Log.java +++ b/openex-model/src/main/java/io/openex/database/model/Log.java @@ -5,9 +5,9 @@ import io.openex.database.audit.ModelBaseListener; import io.openex.helper.MonoIdDeserializer; import io.openex.helper.MultiIdDeserializer; -import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.UuidGenerator; -import javax.persistence.*; +import jakarta.persistence.*; import java.time.Instant; import java.util.ArrayList; import java.util.List; @@ -22,7 +22,7 @@ public class Log implements Base { @Id @Column(name = "log_id") @GeneratedValue(generator = "UUID") - @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + @UuidGenerator @JsonProperty("log_id") private String id; diff --git a/openex-model/src/main/java/io/openex/database/model/Objective.java b/openex-model/src/main/java/io/openex/database/model/Objective.java index dbfb83a139..e09eea580f 100644 --- a/openex-model/src/main/java/io/openex/database/model/Objective.java +++ b/openex-model/src/main/java/io/openex/database/model/Objective.java @@ -5,9 +5,9 @@ import io.openex.database.audit.ModelBaseListener; import io.openex.helper.MonoIdDeserializer; import io.openex.helper.MultiIdDeserializer; -import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.UuidGenerator; -import javax.persistence.*; +import jakarta.persistence.*; import java.time.Instant; import java.util.ArrayList; import java.util.List; @@ -22,7 +22,7 @@ public class Objective implements Base { @Id @Column(name = "objective_id") @GeneratedValue(generator = "UUID") - @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + @UuidGenerator @JsonProperty("objective_id") private String id; diff --git a/openex-model/src/main/java/io/openex/database/model/Organization.java b/openex-model/src/main/java/io/openex/database/model/Organization.java index 635ce915ac..9efcb48e5f 100644 --- a/openex-model/src/main/java/io/openex/database/model/Organization.java +++ b/openex-model/src/main/java/io/openex/database/model/Organization.java @@ -5,9 +5,9 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize; import io.openex.database.audit.ModelBaseListener; import io.openex.helper.MultiIdDeserializer; -import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.UuidGenerator; -import javax.persistence.*; +import jakarta.persistence.*; import java.time.Instant; import java.util.ArrayList; import java.util.List; @@ -24,7 +24,7 @@ public class Organization implements Base { @Id @Column(name = "organization_id") @GeneratedValue(generator = "UUID") - @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + @UuidGenerator @JsonProperty("organization_id") private String id; diff --git a/openex-model/src/main/java/io/openex/database/model/Pause.java b/openex-model/src/main/java/io/openex/database/model/Pause.java index a8107d61cd..9daa8675f7 100644 --- a/openex-model/src/main/java/io/openex/database/model/Pause.java +++ b/openex-model/src/main/java/io/openex/database/model/Pause.java @@ -3,9 +3,9 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import io.openex.helper.MonoIdDeserializer; -import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.UuidGenerator; -import javax.persistence.*; +import jakarta.persistence.*; import java.time.Instant; import java.util.Objects; import java.util.Optional; @@ -16,7 +16,7 @@ public class Pause implements Base { @Id @Column(name = "pause_id") @GeneratedValue(generator = "UUID") - @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + @UuidGenerator @JsonProperty("log_id") private String id; diff --git a/openex-model/src/main/java/io/openex/database/model/Report.java b/openex-model/src/main/java/io/openex/database/model/Report.java index 0e5427bc4c..adc8afba18 100644 --- a/openex-model/src/main/java/io/openex/database/model/Report.java +++ b/openex-model/src/main/java/io/openex/database/model/Report.java @@ -4,9 +4,9 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize; import io.openex.database.audit.ModelBaseListener; import io.openex.helper.MonoIdDeserializer; -import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.UuidGenerator; -import javax.persistence.*; +import jakarta.persistence.*; import java.time.Instant; import java.util.Objects; @@ -19,7 +19,7 @@ public class Report implements Base { @Id @Column(name = "report_id") @GeneratedValue(generator = "UUID") - @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + @UuidGenerator @JsonProperty("report_id") private String id; diff --git a/openex-model/src/main/java/io/openex/database/model/Setting.java b/openex-model/src/main/java/io/openex/database/model/Setting.java index d82a972acd..5c8b2c1f02 100644 --- a/openex-model/src/main/java/io/openex/database/model/Setting.java +++ b/openex-model/src/main/java/io/openex/database/model/Setting.java @@ -2,9 +2,9 @@ import com.fasterxml.jackson.annotation.JsonProperty; import io.openex.database.audit.ModelBaseListener; -import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.UuidGenerator; -import javax.persistence.*; +import jakarta.persistence.*; import java.util.Objects; @Entity @@ -46,7 +46,7 @@ public Setting(String key, String value) { @Id @Column(name = "parameter_id") @GeneratedValue(generator = "UUID") - @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + @UuidGenerator @JsonProperty("setting_id") private String id; diff --git a/openex-model/src/main/java/io/openex/database/model/Tag.java b/openex-model/src/main/java/io/openex/database/model/Tag.java index a3a16d45bb..3b141859c2 100644 --- a/openex-model/src/main/java/io/openex/database/model/Tag.java +++ b/openex-model/src/main/java/io/openex/database/model/Tag.java @@ -5,9 +5,9 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize; import io.openex.database.audit.ModelBaseListener; import io.openex.helper.MultiIdDeserializer; -import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.UuidGenerator; -import javax.persistence.*; +import jakarta.persistence.*; import java.util.ArrayList; import java.util.List; import java.util.Objects; @@ -19,7 +19,7 @@ public class Tag implements Base { @Id @Column(name = "tag_id") @GeneratedValue(generator = "UUID") - @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + @UuidGenerator @JsonProperty("tag_id") private String id; diff --git a/openex-model/src/main/java/io/openex/database/model/Team.java b/openex-model/src/main/java/io/openex/database/model/Team.java index 433465a7d4..8cce2ae8f2 100644 --- a/openex-model/src/main/java/io/openex/database/model/Team.java +++ b/openex-model/src/main/java/io/openex/database/model/Team.java @@ -1,18 +1,17 @@ package io.openex.database.model; -import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import io.openex.database.audit.ModelBaseListener; import io.openex.helper.MonoIdDeserializer; import io.openex.helper.MultiIdDeserializer; import io.openex.helper.MultiModelDeserializer; +import jakarta.persistence.*; +import jakarta.validation.constraints.NotBlank; import lombok.Getter; import lombok.Setter; -import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.UuidGenerator; -import javax.persistence.*; -import javax.validation.constraints.NotBlank; import java.time.Instant; import java.util.ArrayList; import java.util.List; @@ -28,7 +27,7 @@ public class Team implements Base { @Id @Column(name = "team_id") @GeneratedValue(generator = "UUID") - @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + @UuidGenerator @JsonProperty("team_id") private String id; diff --git a/openex-model/src/main/java/io/openex/database/model/Token.java b/openex-model/src/main/java/io/openex/database/model/Token.java index 60021c52c3..41ead45297 100644 --- a/openex-model/src/main/java/io/openex/database/model/Token.java +++ b/openex-model/src/main/java/io/openex/database/model/Token.java @@ -5,9 +5,9 @@ import io.openex.helper.MonoIdDeserializer; import lombok.Getter; import lombok.Setter; -import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.UuidGenerator; -import javax.persistence.*; +import jakarta.persistence.*; import java.time.Instant; import java.util.Objects; @@ -22,7 +22,7 @@ public class Token implements Base { @Id @Column(name = "token_id") @GeneratedValue(generator = "UUID") - @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + @UuidGenerator @JsonProperty("token_id") private String id; diff --git a/openex-model/src/main/java/io/openex/database/model/User.java b/openex-model/src/main/java/io/openex/database/model/User.java index 61f34a47ef..3ad0a03a33 100644 --- a/openex-model/src/main/java/io/openex/database/model/User.java +++ b/openex-model/src/main/java/io/openex/database/model/User.java @@ -9,11 +9,11 @@ import io.openex.helper.MultiIdDeserializer; import lombok.Getter; import lombok.Setter; -import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.UuidGenerator; -import javax.persistence.*; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; +import jakarta.persistence.*; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; import java.time.Instant; import java.util.*; import java.util.stream.Collectors; @@ -39,7 +39,7 @@ public class User implements Base { @Id @Column(name = "user_id") @GeneratedValue(generator = "UUID") - @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + @UuidGenerator @JsonProperty("user_id") @NotBlank private String id; diff --git a/openex-model/src/main/java/io/openex/database/model/Variable.java b/openex-model/src/main/java/io/openex/database/model/Variable.java index a2f14c801e..48f8f08d49 100644 --- a/openex-model/src/main/java/io/openex/database/model/Variable.java +++ b/openex-model/src/main/java/io/openex/database/model/Variable.java @@ -5,12 +5,12 @@ import io.openex.database.audit.ModelBaseListener; import io.openex.helper.MonoIdDeserializer; import lombok.Data; -import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.UuidGenerator; -import javax.persistence.*; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Pattern; +import jakarta.persistence.*; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; import java.time.Instant; import static java.time.Instant.now; @@ -32,7 +32,7 @@ public enum VariableType { @Id @Column(name = "variable_id") @GeneratedValue(generator = "UUID") - @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + @UuidGenerator @JsonProperty("variable_id") @NotBlank private String id; @@ -52,6 +52,7 @@ public enum VariableType { private String description; @Column(name = "variable_type") + @Enumerated(EnumType.STRING) @JsonProperty("variable_type") @NotNull private VariableType type = VariableType.String; diff --git a/openex-model/src/main/java/io/openex/database/repository/ArticleRepository.java b/openex-model/src/main/java/io/openex/database/repository/ArticleRepository.java index 26afe8fcb9..5161e45745 100644 --- a/openex-model/src/main/java/io/openex/database/repository/ArticleRepository.java +++ b/openex-model/src/main/java/io/openex/database/repository/ArticleRepository.java @@ -5,7 +5,7 @@ import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import java.util.Optional; @Repository diff --git a/openex-model/src/main/java/io/openex/database/repository/AttackPatternRepository.java b/openex-model/src/main/java/io/openex/database/repository/AttackPatternRepository.java index ec58158a93..0dff98b9c0 100644 --- a/openex-model/src/main/java/io/openex/database/repository/AttackPatternRepository.java +++ b/openex-model/src/main/java/io/openex/database/repository/AttackPatternRepository.java @@ -5,7 +5,7 @@ import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import java.util.Optional; @Repository diff --git a/openex-model/src/main/java/io/openex/database/repository/AudienceRepository.java b/openex-model/src/main/java/io/openex/database/repository/AudienceRepository.java new file mode 100644 index 0000000000..e69de29bb2 diff --git a/openex-model/src/main/java/io/openex/database/repository/ChallengeFlagRepository.java b/openex-model/src/main/java/io/openex/database/repository/ChallengeFlagRepository.java index c86ff44337..16a389441d 100644 --- a/openex-model/src/main/java/io/openex/database/repository/ChallengeFlagRepository.java +++ b/openex-model/src/main/java/io/openex/database/repository/ChallengeFlagRepository.java @@ -5,7 +5,7 @@ import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import java.util.Optional; @Repository diff --git a/openex-model/src/main/java/io/openex/database/repository/ChallengeRepository.java b/openex-model/src/main/java/io/openex/database/repository/ChallengeRepository.java index 13dede777a..5bc7f1ca3f 100644 --- a/openex-model/src/main/java/io/openex/database/repository/ChallengeRepository.java +++ b/openex-model/src/main/java/io/openex/database/repository/ChallengeRepository.java @@ -5,7 +5,7 @@ import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import java.util.List; import java.util.Optional; diff --git a/openex-model/src/main/java/io/openex/database/repository/ChannelRepository.java b/openex-model/src/main/java/io/openex/database/repository/ChannelRepository.java index 90804d002c..146dbc49eb 100644 --- a/openex-model/src/main/java/io/openex/database/repository/ChannelRepository.java +++ b/openex-model/src/main/java/io/openex/database/repository/ChannelRepository.java @@ -5,7 +5,7 @@ import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import java.util.List; import java.util.Optional; diff --git a/openex-model/src/main/java/io/openex/database/repository/ComcheckRepository.java b/openex-model/src/main/java/io/openex/database/repository/ComcheckRepository.java index 4569431949..5451d78f20 100644 --- a/openex-model/src/main/java/io/openex/database/repository/ComcheckRepository.java +++ b/openex-model/src/main/java/io/openex/database/repository/ComcheckRepository.java @@ -1,7 +1,7 @@ package io.openex.database.repository; import io.openex.database.model.Comcheck; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.CrudRepository; diff --git a/openex-model/src/main/java/io/openex/database/repository/ComcheckStatusRepository.java b/openex-model/src/main/java/io/openex/database/repository/ComcheckStatusRepository.java index a228ab97d3..a331e04723 100644 --- a/openex-model/src/main/java/io/openex/database/repository/ComcheckStatusRepository.java +++ b/openex-model/src/main/java/io/openex/database/repository/ComcheckStatusRepository.java @@ -1,7 +1,7 @@ package io.openex.database.repository; import io.openex.database.model.ComcheckStatus; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; diff --git a/openex-model/src/main/java/io/openex/database/repository/CommunicationRepository.java b/openex-model/src/main/java/io/openex/database/repository/CommunicationRepository.java index ae9da56305..ba10b820d0 100644 --- a/openex-model/src/main/java/io/openex/database/repository/CommunicationRepository.java +++ b/openex-model/src/main/java/io/openex/database/repository/CommunicationRepository.java @@ -1,7 +1,7 @@ package io.openex.database.repository; import io.openex.database.model.Communication; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.CrudRepository; diff --git a/openex-model/src/main/java/io/openex/database/repository/DocumentRepository.java b/openex-model/src/main/java/io/openex/database/repository/DocumentRepository.java index 74a70d0758..9a879cc777 100644 --- a/openex-model/src/main/java/io/openex/database/repository/DocumentRepository.java +++ b/openex-model/src/main/java/io/openex/database/repository/DocumentRepository.java @@ -8,7 +8,7 @@ import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import java.util.List; import java.util.Optional; diff --git a/openex-model/src/main/java/io/openex/database/repository/DryInjectReportingRepository.java b/openex-model/src/main/java/io/openex/database/repository/DryInjectReportingRepository.java index 8fabf4d2e9..a31004eff8 100644 --- a/openex-model/src/main/java/io/openex/database/repository/DryInjectReportingRepository.java +++ b/openex-model/src/main/java/io/openex/database/repository/DryInjectReportingRepository.java @@ -1,7 +1,7 @@ package io.openex.database.repository; import io.openex.database.model.DryInjectStatus; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; diff --git a/openex-model/src/main/java/io/openex/database/repository/DryInjectRepository.java b/openex-model/src/main/java/io/openex/database/repository/DryInjectRepository.java index ff223c35b9..39d7e7c888 100644 --- a/openex-model/src/main/java/io/openex/database/repository/DryInjectRepository.java +++ b/openex-model/src/main/java/io/openex/database/repository/DryInjectRepository.java @@ -5,7 +5,7 @@ import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import java.util.Optional; @Repository diff --git a/openex-model/src/main/java/io/openex/database/repository/DryRunRepository.java b/openex-model/src/main/java/io/openex/database/repository/DryRunRepository.java index d42fba9852..54eee642f8 100644 --- a/openex-model/src/main/java/io/openex/database/repository/DryRunRepository.java +++ b/openex-model/src/main/java/io/openex/database/repository/DryRunRepository.java @@ -1,7 +1,7 @@ package io.openex.database.repository; import io.openex.database.model.Dryrun; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; diff --git a/openex-model/src/main/java/io/openex/database/repository/EvaluationRepository.java b/openex-model/src/main/java/io/openex/database/repository/EvaluationRepository.java index f5b5530754..0723d2ea46 100644 --- a/openex-model/src/main/java/io/openex/database/repository/EvaluationRepository.java +++ b/openex-model/src/main/java/io/openex/database/repository/EvaluationRepository.java @@ -1,7 +1,7 @@ package io.openex.database.repository; import io.openex.database.model.Evaluation; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; diff --git a/openex-model/src/main/java/io/openex/database/repository/ExerciseRepository.java b/openex-model/src/main/java/io/openex/database/repository/ExerciseRepository.java index 1c0599aaa1..c768f313eb 100644 --- a/openex-model/src/main/java/io/openex/database/repository/ExerciseRepository.java +++ b/openex-model/src/main/java/io/openex/database/repository/ExerciseRepository.java @@ -1,7 +1,7 @@ package io.openex.database.repository; import io.openex.database.model.Exercise; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.query.Param; diff --git a/openex-model/src/main/java/io/openex/database/repository/ExerciseTeamUserRepository.java b/openex-model/src/main/java/io/openex/database/repository/ExerciseTeamUserRepository.java index 5c3d92dab5..9e6cdbe44a 100644 --- a/openex-model/src/main/java/io/openex/database/repository/ExerciseTeamUserRepository.java +++ b/openex-model/src/main/java/io/openex/database/repository/ExerciseTeamUserRepository.java @@ -2,8 +2,7 @@ import io.openex.database.model.ExerciseTeamUser; import io.openex.database.model.ExerciseTeamUserId; -import io.openex.database.model.InjectDocument; -import io.openex.database.model.InjectDocumentId; +import jakarta.validation.constraints.NotNull; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; @@ -11,7 +10,6 @@ import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; -import javax.validation.constraints.NotNull; import java.util.Optional; @Repository diff --git a/openex-model/src/main/java/io/openex/database/repository/GrantRepository.java b/openex-model/src/main/java/io/openex/database/repository/GrantRepository.java index ec99739fde..3ed6f422bc 100644 --- a/openex-model/src/main/java/io/openex/database/repository/GrantRepository.java +++ b/openex-model/src/main/java/io/openex/database/repository/GrantRepository.java @@ -1,7 +1,7 @@ package io.openex.database.repository; import io.openex.database.model.Grant; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; diff --git a/openex-model/src/main/java/io/openex/database/repository/GroupRepository.java b/openex-model/src/main/java/io/openex/database/repository/GroupRepository.java index 9572764ae5..26ad23c3c1 100644 --- a/openex-model/src/main/java/io/openex/database/repository/GroupRepository.java +++ b/openex-model/src/main/java/io/openex/database/repository/GroupRepository.java @@ -1,7 +1,7 @@ package io.openex.database.repository; import io.openex.database.model.Group; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; diff --git a/openex-model/src/main/java/io/openex/database/repository/InjectDocumentRepository.java b/openex-model/src/main/java/io/openex/database/repository/InjectDocumentRepository.java index 063b7c9573..5e0d228dde 100644 --- a/openex-model/src/main/java/io/openex/database/repository/InjectDocumentRepository.java +++ b/openex-model/src/main/java/io/openex/database/repository/InjectDocumentRepository.java @@ -9,7 +9,7 @@ import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import java.util.Optional; @Repository diff --git a/openex-model/src/main/java/io/openex/database/repository/InjectExpectationRepository.java b/openex-model/src/main/java/io/openex/database/repository/InjectExpectationRepository.java index 4102388344..0ee7bce7db 100644 --- a/openex-model/src/main/java/io/openex/database/repository/InjectExpectationRepository.java +++ b/openex-model/src/main/java/io/openex/database/repository/InjectExpectationRepository.java @@ -8,8 +8,8 @@ import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; import java.util.List; import java.util.Optional; diff --git a/openex-model/src/main/java/io/openex/database/repository/InjectReportingRepository.java b/openex-model/src/main/java/io/openex/database/repository/InjectReportingRepository.java index 7379b6aa49..08b98204f8 100644 --- a/openex-model/src/main/java/io/openex/database/repository/InjectReportingRepository.java +++ b/openex-model/src/main/java/io/openex/database/repository/InjectReportingRepository.java @@ -1,7 +1,7 @@ package io.openex.database.repository; import io.openex.database.model.InjectStatus; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; diff --git a/openex-model/src/main/java/io/openex/database/repository/InjectRepository.java b/openex-model/src/main/java/io/openex/database/repository/InjectRepository.java index 01b30030fe..7cc3e06436 100644 --- a/openex-model/src/main/java/io/openex/database/repository/InjectRepository.java +++ b/openex-model/src/main/java/io/openex/database/repository/InjectRepository.java @@ -8,7 +8,7 @@ import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import java.time.Instant; import java.util.List; import java.util.Optional; diff --git a/openex-model/src/main/java/io/openex/database/repository/InjectStatusRepository.java b/openex-model/src/main/java/io/openex/database/repository/InjectStatusRepository.java index ea0fcd1f3c..de2f352142 100644 --- a/openex-model/src/main/java/io/openex/database/repository/InjectStatusRepository.java +++ b/openex-model/src/main/java/io/openex/database/repository/InjectStatusRepository.java @@ -7,7 +7,7 @@ import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import java.util.List; import java.util.Optional; diff --git a/openex-model/src/main/java/io/openex/database/repository/KillChainPhaseRepository.java b/openex-model/src/main/java/io/openex/database/repository/KillChainPhaseRepository.java index e985d6f61d..6fc97c2915 100644 --- a/openex-model/src/main/java/io/openex/database/repository/KillChainPhaseRepository.java +++ b/openex-model/src/main/java/io/openex/database/repository/KillChainPhaseRepository.java @@ -5,7 +5,7 @@ import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import java.util.Optional; @Repository diff --git a/openex-model/src/main/java/io/openex/database/repository/LessonsAnswerRepository.java b/openex-model/src/main/java/io/openex/database/repository/LessonsAnswerRepository.java index 2a878420dc..e8041c1dd0 100644 --- a/openex-model/src/main/java/io/openex/database/repository/LessonsAnswerRepository.java +++ b/openex-model/src/main/java/io/openex/database/repository/LessonsAnswerRepository.java @@ -5,7 +5,7 @@ import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import java.util.Optional; @Repository diff --git a/openex-model/src/main/java/io/openex/database/repository/LessonsCategoryRepository.java b/openex-model/src/main/java/io/openex/database/repository/LessonsCategoryRepository.java index 6d12b5cf43..da224b6375 100644 --- a/openex-model/src/main/java/io/openex/database/repository/LessonsCategoryRepository.java +++ b/openex-model/src/main/java/io/openex/database/repository/LessonsCategoryRepository.java @@ -5,7 +5,7 @@ import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import java.util.Optional; @Repository diff --git a/openex-model/src/main/java/io/openex/database/repository/LessonsQuestionRepository.java b/openex-model/src/main/java/io/openex/database/repository/LessonsQuestionRepository.java index a40f44bcec..1b32d23425 100644 --- a/openex-model/src/main/java/io/openex/database/repository/LessonsQuestionRepository.java +++ b/openex-model/src/main/java/io/openex/database/repository/LessonsQuestionRepository.java @@ -5,7 +5,7 @@ import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import java.util.Optional; @Repository diff --git a/openex-model/src/main/java/io/openex/database/repository/LessonsTemplateCategoryRepository.java b/openex-model/src/main/java/io/openex/database/repository/LessonsTemplateCategoryRepository.java index 766c3a9206..a4b8a0ba7d 100644 --- a/openex-model/src/main/java/io/openex/database/repository/LessonsTemplateCategoryRepository.java +++ b/openex-model/src/main/java/io/openex/database/repository/LessonsTemplateCategoryRepository.java @@ -5,7 +5,7 @@ import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import java.util.Optional; @Repository diff --git a/openex-model/src/main/java/io/openex/database/repository/LessonsTemplateQuestionRepository.java b/openex-model/src/main/java/io/openex/database/repository/LessonsTemplateQuestionRepository.java index 53da9a785f..b3d52c0c06 100644 --- a/openex-model/src/main/java/io/openex/database/repository/LessonsTemplateQuestionRepository.java +++ b/openex-model/src/main/java/io/openex/database/repository/LessonsTemplateQuestionRepository.java @@ -5,7 +5,7 @@ import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import java.util.Optional; @Repository diff --git a/openex-model/src/main/java/io/openex/database/repository/LessonsTemplateRepository.java b/openex-model/src/main/java/io/openex/database/repository/LessonsTemplateRepository.java index 1ea8038e8a..31da208ef3 100644 --- a/openex-model/src/main/java/io/openex/database/repository/LessonsTemplateRepository.java +++ b/openex-model/src/main/java/io/openex/database/repository/LessonsTemplateRepository.java @@ -1,11 +1,11 @@ package io.openex.database.repository; import io.openex.database.model.LessonsTemplate; +import jakarta.validation.constraints.NotNull; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; -import javax.validation.constraints.NotNull; import java.util.Optional; @Repository diff --git a/openex-model/src/main/java/io/openex/database/repository/LogRepository.java b/openex-model/src/main/java/io/openex/database/repository/LogRepository.java index fd3c363cd8..229e5b9480 100644 --- a/openex-model/src/main/java/io/openex/database/repository/LogRepository.java +++ b/openex-model/src/main/java/io/openex/database/repository/LogRepository.java @@ -1,7 +1,7 @@ package io.openex.database.repository; import io.openex.database.model.Log; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; diff --git a/openex-model/src/main/java/io/openex/database/repository/ObjectiveRepository.java b/openex-model/src/main/java/io/openex/database/repository/ObjectiveRepository.java index 4ab3ef9b41..0d7322aef6 100644 --- a/openex-model/src/main/java/io/openex/database/repository/ObjectiveRepository.java +++ b/openex-model/src/main/java/io/openex/database/repository/ObjectiveRepository.java @@ -1,7 +1,7 @@ package io.openex.database.repository; import io.openex.database.model.Objective; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; diff --git a/openex-model/src/main/java/io/openex/database/repository/OrganizationRepository.java b/openex-model/src/main/java/io/openex/database/repository/OrganizationRepository.java index c5736c4fab..69a6cdfb90 100644 --- a/openex-model/src/main/java/io/openex/database/repository/OrganizationRepository.java +++ b/openex-model/src/main/java/io/openex/database/repository/OrganizationRepository.java @@ -1,7 +1,7 @@ package io.openex.database.repository; import io.openex.database.model.Organization; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; diff --git a/openex-model/src/main/java/io/openex/database/repository/PauseRepository.java b/openex-model/src/main/java/io/openex/database/repository/PauseRepository.java index 4a609dcd22..2756b68106 100644 --- a/openex-model/src/main/java/io/openex/database/repository/PauseRepository.java +++ b/openex-model/src/main/java/io/openex/database/repository/PauseRepository.java @@ -1,7 +1,7 @@ package io.openex.database.repository; import io.openex.database.model.Pause; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.CrudRepository; diff --git a/openex-model/src/main/java/io/openex/database/repository/ReportRepository.java b/openex-model/src/main/java/io/openex/database/repository/ReportRepository.java index 985bbd069f..c90eb3f5f9 100644 --- a/openex-model/src/main/java/io/openex/database/repository/ReportRepository.java +++ b/openex-model/src/main/java/io/openex/database/repository/ReportRepository.java @@ -5,7 +5,7 @@ import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import java.util.Optional; @Repository diff --git a/openex-model/src/main/java/io/openex/database/repository/SettingRepository.java b/openex-model/src/main/java/io/openex/database/repository/SettingRepository.java index 6b7459e5d4..0b6e72d71f 100644 --- a/openex-model/src/main/java/io/openex/database/repository/SettingRepository.java +++ b/openex-model/src/main/java/io/openex/database/repository/SettingRepository.java @@ -1,7 +1,7 @@ package io.openex.database.repository; import io.openex.database.model.Setting; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.CrudRepository; diff --git a/openex-model/src/main/java/io/openex/database/repository/TagRepository.java b/openex-model/src/main/java/io/openex/database/repository/TagRepository.java index 5e5e598bd5..db7449cb73 100644 --- a/openex-model/src/main/java/io/openex/database/repository/TagRepository.java +++ b/openex-model/src/main/java/io/openex/database/repository/TagRepository.java @@ -1,7 +1,7 @@ package io.openex.database.repository; import io.openex.database.model.Tag; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; diff --git a/openex-model/src/main/java/io/openex/database/repository/TeamRepository.java b/openex-model/src/main/java/io/openex/database/repository/TeamRepository.java index 5b58f3a4b0..a6c379681f 100644 --- a/openex-model/src/main/java/io/openex/database/repository/TeamRepository.java +++ b/openex-model/src/main/java/io/openex/database/repository/TeamRepository.java @@ -1,10 +1,7 @@ package io.openex.database.repository; -import io.openex.database.model.Challenge; import io.openex.database.model.Team; -import javax.validation.constraints.NotNull; - -import io.openex.database.model.User; +import jakarta.validation.constraints.NotNull; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.CrudRepository; diff --git a/openex-model/src/main/java/io/openex/database/repository/TokenRepository.java b/openex-model/src/main/java/io/openex/database/repository/TokenRepository.java index b170912507..30e6bb142e 100644 --- a/openex-model/src/main/java/io/openex/database/repository/TokenRepository.java +++ b/openex-model/src/main/java/io/openex/database/repository/TokenRepository.java @@ -1,7 +1,7 @@ package io.openex.database.repository; import io.openex.database.model.Token; -import io.openex.database.model.User; +import jakarta.validation.constraints.NotNull; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; @@ -9,7 +9,6 @@ import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; -import javax.validation.constraints.NotNull; import java.time.Instant; import java.util.Optional; @@ -29,7 +28,7 @@ public interface TokenRepository extends CrudRepository, JpaSpeci + "values (:id, :user, :value, :createdAt)", nativeQuery = true) void createToken( @Param("id") String tokenId, - @Param("user") User adminUser, + @Param("user") String adminUser, @Param("value") String tokenValue, @Param("createdAt") Instant createdAt ); diff --git a/openex-model/src/main/java/io/openex/database/repository/UserRepository.java b/openex-model/src/main/java/io/openex/database/repository/UserRepository.java index 683564ef2a..7d166671df 100644 --- a/openex-model/src/main/java/io/openex/database/repository/UserRepository.java +++ b/openex-model/src/main/java/io/openex/database/repository/UserRepository.java @@ -8,7 +8,7 @@ import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import java.time.Instant; import java.util.List; import java.util.Optional; diff --git a/openex-model/src/main/java/io/openex/database/specification/DryInjectSpecification.java b/openex-model/src/main/java/io/openex/database/specification/DryInjectSpecification.java index e8c1abd3ae..ae74c7076e 100644 --- a/openex-model/src/main/java/io/openex/database/specification/DryInjectSpecification.java +++ b/openex-model/src/main/java/io/openex/database/specification/DryInjectSpecification.java @@ -3,7 +3,7 @@ import io.openex.database.model.DryInject; import org.springframework.data.jpa.domain.Specification; -import javax.persistence.criteria.JoinType; +import jakarta.persistence.criteria.JoinType; public class DryInjectSpecification { diff --git a/openex-model/src/main/java/io/openex/database/specification/InjectSpecification.java b/openex-model/src/main/java/io/openex/database/specification/InjectSpecification.java index c348c0d90b..aa6fe7a566 100644 --- a/openex-model/src/main/java/io/openex/database/specification/InjectSpecification.java +++ b/openex-model/src/main/java/io/openex/database/specification/InjectSpecification.java @@ -2,11 +2,10 @@ import io.openex.database.model.Exercise; import io.openex.database.model.Inject; -// import io.openex.injects.manual.ManualContract; import org.springframework.data.jpa.domain.Specification; -import javax.persistence.criteria.JoinType; -import javax.persistence.criteria.Path; +import jakarta.persistence.criteria.JoinType; +import jakarta.persistence.criteria.Path; public class InjectSpecification { diff --git a/pom.xml b/pom.xml index 776feb373f..681b480659 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ org.springframework.boot spring-boot-starter-parent - 2.7.17 + 3.2.0 io.openex @@ -18,12 +18,9 @@ OpenEx platform - 2.17.2 - 2.15.3 - 1.18.30 8.5.7 - 2.0.1.Final - 2.15.0 + 2.15.1 + 3.11.0 @@ -59,7 +56,6 @@ org.projectlombok lombok - ${lombok.version} provided @@ -69,10 +65,10 @@ org.apache.maven.plugins maven-compiler-plugin - 3.11.0 + ${maven-compiler-plugin.version} - 18 - 18 + 21 + 21