From 31ef22914375c07df825e5f50a877d300bd62c9b Mon Sep 17 00:00:00 2001 From: siarhei_hrabko Date: Fri, 8 Nov 2024 18:23:24 +0300 Subject: [PATCH 1/7] EPMRPP-96333 spring boot 3 --- build.gradle | 124 +++++++----------- gradle.properties | 6 +- gradle/wrapper/gradle-wrapper.properties | 2 +- project-properties.gradle | 4 - .../reportportal/auth/CombinedTokenStore.java | 4 +- .../UiAuthenticationFailureEventHandler.java | 8 +- .../AssignedToProjectPermission.java | 3 +- .../permissions/BaseProjectPermission.java | 3 +- .../ta/reportportal/auth/util/AuthUtils.java | 1 - .../CreateRegexPatternTemplateHandler.java | 2 +- .../core/annotation/Datastore.java | 2 +- .../reportportal/core/annotation/Regular.java | 2 +- .../core/configs/JacksonConfiguration.java | 14 +- .../core/configs/MultipartDataConfig.java | 2 +- .../reportportal/core/configs/MvcConfig.java | 27 ++-- .../core/configs/PluginConfiguration.java | 2 +- .../core/configs/SchedulerConfiguration.java | 2 +- .../core/configs/SecurityConfiguration.java | 7 +- .../core/configs/SpringDocConfiguration.java | 8 +- .../impl/DeleteDashboardHandlerImpl.java | 2 +- .../impl/UpdateDashboardHandlerImpl.java | 4 +- .../events/annotations/WidgetLimitRange.java | 2 +- .../WidgetLimitRangeValidator.java | 7 +- .../plugin/binary/PluginFilesProvider.java | 2 +- .../plugin/impl/PluginLoaderImpl.java | 2 +- .../util/EmailServerIntegrationService.java | 2 +- .../item/impl/StartTestItemHandlerImpl.java | 4 +- .../history/TestItemsHistoryHandlerImpl.java | 2 +- .../core/launch/GetLaunchHandler.java | 4 +- .../core/launch/util/LinkGenerator.java | 21 ++- .../core/log/impl/GetLogHandlerImpl.java | 2 +- .../core/logging/HttpLoggingAspect.java | 14 +- .../logging/RabbitMessageLoggingAspect.java | 3 +- .../core/project/GetProjectHandler.java | 4 +- .../core/user/GetUserHandler.java | 2 +- .../core/user/impl/ApiKeyHandlerImpl.java | 2 +- .../core/user/impl/CreateUserHandlerImpl.java | 8 +- .../job/CleanOutdatedPluginsJob.java | 2 +- .../reportportal/job/SelfCancelableJob.java | 3 +- .../model/ActivityEventResource.java | 2 +- .../epam/ta/reportportal/model/ApiKeyRQ.java | 2 +- .../epam/ta/reportportal/model/ApiKeyRS.java | 2 +- .../epam/ta/reportportal/model/ApiKeysRS.java | 2 +- .../ta/reportportal/model/BaseEntityRQ.java | 4 +- .../epam/ta/reportportal/model/BulkRQ.java | 4 +- .../ta/reportportal/model/CollectionsRQ.java | 6 +- .../ta/reportportal/model/DeleteBulkRQ.java | 2 +- .../ta/reportportal/model/PagedResponse.java | 4 +- .../ta/reportportal/model/SearchCriteria.java | 4 +- .../reportportal/model/SearchCriteriaRQ.java | 4 +- .../model/dashboard/AddWidgetRq.java | 4 +- .../model/dashboard/CreateDashboardRQ.java | 4 +- .../model/dashboard/DashboardResource.java | 6 +- .../model/dashboard/UpdateDashboardRQ.java | 6 +- .../externalsystem/BtsConnectionTestRQ.java | 2 +- .../model/filter/BulkUpdateFilterRQ.java | 4 +- .../ta/reportportal/model/filter/Order.java | 2 +- .../model/filter/UpdateUserFilterRQ.java | 14 +- .../model/filter/UserFilterCondition.java | 4 +- .../model/filter/UserFilterResource.java | 10 +- .../integration/UpdatePluginStateRQ.java | 2 +- .../model/issue/DefineIssueRQ.java | 8 +- .../model/issue/IssueDefinition.java | 6 +- .../model/item/ExternalIssueRQ.java | 4 +- .../model/item/LinkExternalIssueRQ.java | 8 +- .../model/item/UnlinkExternalIssueRQ.java | 6 +- .../model/item/UpdateTestItemRQ.java | 6 +- .../model/launch/AnalyzeLaunchRQ.java | 4 +- .../model/launch/LaunchImportRQ.java | 4 +- .../model/launch/UpdateLaunchRQ.java | 6 +- .../launch/cluster/CreateClustersRQ.java | 2 +- .../model/log/GetLogsUnderRq.java | 2 +- .../reportportal/model/log/LogResource.java | 2 +- .../reportportal/model/log/SearchLogRq.java | 4 +- .../notification/EmailNotificationRQ.java | 2 +- .../model/project/AssignUsersRQ.java | 4 +- .../model/project/CreateProjectRQ.java | 8 +- .../model/project/DeleteProjectRQ.java | 6 +- .../model/project/ProjectInfoResource.java | 4 +- .../model/project/ProjectResource.java | 2 +- .../model/project/UnassignUsersRQ.java | 4 +- .../model/project/UpdateProjectRQ.java | 4 +- .../project/config/CreateIssueSubTypeRQ.java | 6 +- .../config/ProjectConfigurationUpdate.java | 2 +- .../project/config/UpdateIssueSubTypeRQ.java | 4 +- .../config/UpdateOneIssueSubTypeRQ.java | 8 +- .../pattern/CreatePatternTemplateRQ.java | 6 +- .../pattern/UpdatePatternTemplateRQ.java | 6 +- .../email/ProjectNotificationConfigDTO.java | 4 +- .../model/project/email/SenderCaseDTO.java | 8 +- .../reportportal/model/role/SaveRoleRQ.java | 4 +- .../model/settings/AnalyticsResource.java | 2 +- .../model/settings/ServerEmailResource.java | 2 +- .../model/user/ChangePasswordRQ.java | 6 +- .../reportportal/model/user/CreateUserRQ.java | 6 +- .../model/user/CreateUserRQConfirm.java | 8 +- .../model/user/CreateUserRQFull.java | 13 +- .../reportportal/model/user/EditUserRQ.java | 9 +- .../model/user/ResetPasswordRQ.java | 6 +- .../model/user/RestorePasswordRQ.java | 18 +-- .../reportportal/model/user/UserResource.java | 2 +- .../validation/NotBlankWithSizeValidator.java | 6 +- .../model/widget/ContentParameters.java | 10 +- .../model/widget/WidgetPreviewRQ.java | 6 +- .../reportportal/model/widget/WidgetRQ.java | 42 ++---- .../model/widget/WidgetResource.java | 10 +- .../plugin/PluginStartUpService.java | 4 +- .../controller/LaunchAsyncController.java | 2 +- .../async/controller/LogAsyncController.java | 4 +- .../async/handler/LogMessageHandler.java | 7 +- .../async/message/MessageRetriever.java | 6 +- .../reporting/async/producer/LogProducer.java | 6 +- .../reporting/event/EventBasedReporting.java | 6 +- .../util/BinaryDataResponseWriter.java | 2 +- .../ta/reportportal/util/ControllerUtils.java | 12 +- .../reportportal/util/MultipartFileUtils.java | 10 +- .../reportportal/util/email/EmailService.java | 6 +- .../controller/ActivityEventController.java | 4 +- .../ws/controller/FileStorageController.java | 2 +- .../ws/controller/IntegrationController.java | 2 +- .../ws/controller/LaunchController.java | 6 +- .../ws/controller/LogController.java | 4 +- .../ws/controller/PluginController.java | 4 +- .../ws/controller/PluginPublicController.java | 2 +- .../ws/controller/ProjectController.java | 2 +- .../ws/controller/UserController.java | 4 +- .../converter/builders/DashboardBuilder.java | 2 +- .../builders/IntegrationTypeBuilder.java | 2 +- .../converters/DashboardConverter.java | 2 +- .../converters/ItemAttributeConverter.java | 6 +- src/main/resources/application.properties | 3 + .../EmailServerIntegrationServiceTest.java | 4 +- .../impl/CreateLogHandlerAsyncImplTest.java | 4 +- .../core/logging/HttpLoggingAspectTest.java | 4 +- .../job/SelfCancalableJobTest.java | 8 +- .../util/MultipartFileUtilsTest.java | 8 +- .../util/email/MailServiceFactoryTest.java | 4 +- .../BugTrackingSystemControllerTest.java | 6 +- .../controller/LaunchAsyncControllerTest.java | 4 +- .../ws/controller/LogAsyncControllerTest.java | 6 +- .../PluginPublicControllerTest.java | 4 +- .../converters/DashboardConverterTest.java | 2 +- .../ws/validation/TicketsValidationTest.java | 6 +- .../ws/validation/WidgetRqValidatorTest.java | 6 +- 144 files changed, 417 insertions(+), 458 deletions(-) diff --git a/build.gradle b/build.gradle index f6dff6f9e7..9c52db3594 100644 --- a/build.gradle +++ b/build.gradle @@ -15,10 +15,11 @@ */ plugins { - id "io.spring.dependency-management" version "1.1.4" - id 'org.springframework.boot' version '2.5.15' + id 'io.spring.dependency-management' version '1.1.6' id 'java' - id "org.owasp.dependencycheck" version "9.0.9" + id 'java-library' + id 'org.owasp.dependencycheck' version '10.0.4' + id 'org.springframework.boot' version "${springBootVersion}" } import org.owasp.dependencycheck.reporting.ReportGenerator @@ -35,25 +36,20 @@ apply plugin: 'jacoco' project.hasProperty('sealightsSession') && sealightsSession?.trim() ? apply(from: 'sealights.gradle') : println('No sealights session') repositories { - mavenCentral { url "https://repo1.maven.org/maven2" } - if (!releaseMode) { maven { url 'https://jitpack.io' } } - maven { url "https://jaspersoft.jfrog.io/artifactory/third-party-ce-artifacts" } + mavenCentral { url "https://repo1.maven.org/maven2" } +} + +java { + targetCompatibility = JavaVersion.VERSION_21 + toolchain { + languageVersion = JavaLanguageVersion.of(21) + } } -//https://nvd.nist.gov/vuln/detail/CVE-2020-10683 (dom4j 2.1.3 version dependency) AND https://nvd.nist.gov/vuln/detail/CVE-2019-14900 -ext['hibernate.version'] = '5.6.15.Final' -//https://nvd.nist.gov/vuln/detail/CVE-2020-10693 -ext['hibernate-validator.version'] = '6.2.5.Final' -//https://nvd.nist.gov/vuln/detail/CVE-2020-13692 -//ext['postgresql.version'] = '42.2.13' -//https://nvd.nist.gov/vuln/detail/CVE-2020-9488 and https://nvd.nist.gov/vuln/detail/CVE-2021-44228 and https://nvd.nist.gov/vuln/detail/CVE-2021-45046 -ext['log4j2.version'] = '2.21.1' -ext['log4j-to-slf4j.version'] = '2.21.1' -//https://nvd.nist.gov/vuln/detail/cve-2022-22965 -ext['spring-boot.version'] = '2.5.15' +ext['spring-boot.version'] = "${springBootVersion}" dependencyManagement { imports { @@ -68,9 +64,9 @@ dependencies { implementation 'com.epam.reportportal:commons' implementation 'com.epam.reportportal:plugin-api:5.11.1' } else { - implementation 'com.github.reportportal:commons-dao:develop-SNAPSHOT' - implementation 'com.github.reportportal:commons:develop-SNAPSHOT' - implementation 'com.github.reportportal:plugin-api:develop-SNAPSHOT' + implementation 'com.github.reportportal:commons-dao:43dce52' + implementation 'com.github.reportportal:commons:e55b9e6' + implementation 'com.github.reportportal:plugin-api:bffdccf' } implementation 'org.springframework.boot:spring-boot-starter-aop' @@ -80,78 +76,46 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-actuator' implementation 'org.springframework.boot:spring-boot-starter-amqp' implementation 'org.springframework.boot:spring-boot-starter-batch' + implementation 'org.springframework.boot:spring-boot-starter-security' + implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' + implementation 'org.springframework:spring-context-support' + implementation 'org.springframework.security:spring-security-jwt:1.1.1.RELEASE' + implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0' - implementation 'org.springframework:spring-jdbc:6.1.5' - //Fix CVE-2023-34050 - implementation 'org.springframework.amqp:spring-amqp:2.4.17' - - //Fix CVE-2023-40827, CVE-2023-40828, CVE-2023-40826 - implementation 'org.springframework:spring-webmvc:5.3.39' - implementation 'org.springframework:spring-web:5.3.39' - - implementation 'com.opencsv:opencsv:5.8' - - // Fix CVE-2023-46589, CVE-2024-24549 - implementation 'org.apache.tomcat.embed:tomcat-embed-core:9.0.86' - implementation 'org.apache.tomcat.embed:tomcat-embed-el:9.0.86' - implementation 'org.apache.tomcat.embed:tomcat-embed-websocket:9.0.86' - // - - //https://nvd.nist.gov/vuln/detail/CVE-2020-5411 - implementation('org.springframework.batch:spring-batch-core:4.3.9') - implementation('org.springframework.batch:spring-batch-infrastructure:4.3.9') - + implementation 'com.opencsv:opencsv:5.9' + implementation "org.jooq:jooq:${jooqVersion}" // Optional for spring-boot-starter-amqp implementation "com.rabbitmq:http-client:5.2.0" - implementation 'com.sun.mail:javax.mail:1.6.2' // check authentication error response format for versions higher than 6.21.3 implementation('net.sf.jasperreports:jasperreports:6.21.3') { exclude group: 'com.fasterxml.jackson.dataformat', module: 'jackson-dataformat-xml' } + implementation 'jakarta.inject:jakarta.inject-api:2.0.1' + implementation 'com.sun.mail:jakarta.mail:2.0.1' + implementation 'xerces:xercesImpl:2.12.2' implementation 'com.lowagie:itext:4.2.2' - // Fix CVE-2020-15522 in com.lowagie:itext:2.1.7.js7 - implementation 'org.bouncycastle:bcprov-jdk15on:1.70' // JasperReport's export to XLS uses Apache POI implementation 'org.apache.poi:poi:4.1.2' - implementation 'org.springdoc:springdoc-openapi-ui:1.7.0' - implementation 'com.google.code.gson:gson:2.8.9' - implementation 'com.google.api-client:google-api-client:2.3.0' - - ///// Security - //https://nvd.nist.gov/vuln/detail/CVE-2020-5407 AND https://nvd.nist.gov/vuln/detail/CVE-2020-5408 - implementation 'org.springframework.security:spring-security-core:5.8.14' - implementation 'org.springframework.security:spring-security-config:5.8.14' - implementation 'org.springframework.security:spring-security-web:5.8.14' - // - - // Fix CVE-2022-22969 - implementation 'org.springframework.security.oauth:spring-security-oauth2:2.5.2.RELEASE' - implementation 'org.springframework.security:spring-security-jwt:1.1.1.RELEASE' + implementation 'com.google.api-client:google-api-client:2.6.0' + + implementation('commons-validator:commons-validator:1.9.0') { + exclude group: 'commons-beanutils', module: 'commons-beanutils' + } implementation 'org.springframework.security:spring-security-acl' - implementation 'com.github.ben-manes.caffeine:caffeine:2.9.3' - - // Fix CVE-2022-22965, CVE-2022-22970 - implementation 'org.springframework:spring-beans:5.3.31' - // Fix CVE-2021-22060, CVE-2021-22096 - implementation 'org.springframework:spring-core:5.3.39' - // Fix CVE-2022-45685, CVE-2022-40150, CVE-2022-40149 - implementation 'org.codehaus.jettison:jettison:1.5.4' - // Fix CVE-2024-25710, CVE-2024-26308 - implementation 'org.apache.commons:commons-compress:1.26.0' -// TODO: SnakeYaml 2 can't be used in Spring Boot 2.5.15. -// We avoid using application.yaml and user application.properties instead for safe configuration. - implementation 'org.yaml:snakeyaml:2.2' - implementation 'org.hibernate:hibernate-core:5.6.15.Final' - - //Fix CVE-2023-6378, CVE-2023-6481, CVE-2023-6378, CVE-2023-6481 - implementation 'ch.qos.logback:logback-classic:1.2.13' - implementation 'ch.qos.logback:logback-core:1.2.13' + implementation 'com.github.ben-manes.caffeine:caffeine' + implementation 'commons-fileupload:commons-fileupload:1.5' // TODO to delete + + implementation "org.apache.jclouds.api:filesystem:${jcloudsVersion}" + + implementation 'org.apache.commons:commons-compress:1.27.1' + + implementation "org.hibernate.validator:hibernate-validator:${hibernateValidatorVersion}" // Metrics - implementation 'io.micrometer:micrometer-registry-prometheus:1.8.13' + implementation 'io.micrometer:micrometer-registry-prometheus:1.13.2' // add lombok support compileOnly "org.projectlombok:lombok:${lombokVersion}" @@ -161,9 +125,10 @@ dependencies { // Tests testImplementation 'org.springframework.boot:spring-boot-starter-test' - testImplementation 'org.mockito:mockito-core:5.7.0' - testImplementation 'net.bytebuddy:byte-buddy:1.14.9' - testImplementation 'org.flywaydb.flyway-test-extensions:flyway-spring-test:9.5.0' + implementation 'org.springframework:spring-web' + implementation 'org.springframework:spring-test' + testImplementation 'net.bytebuddy:byte-buddy:1.14.17' + testImplementation 'org.flywaydb.flyway-test-extensions:flyway-spring-test:10.0.0' } processResources { @@ -188,6 +153,7 @@ dependencyCheck { } bootJar { + duplicatesStrategy = duplicatesStrategy.EXCLUDE project.hasProperty('gcp') ? getArchiveFileName().set('app.jar') : archiveClassifier.set('' + 'exec') } diff --git a/gradle.properties b/gradle.properties index 7835e0bb71..f77af76507 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,4 +12,8 @@ dockerJavaOptsDev=-DLOG_FILE=app.log \ -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 dockerServerUrl=unix:///var/run/docker.sock org.gradle.jvmargs=-Xmx2048m -lombokVersion=1.18.30 +lombokVersion=1.18.34 +springBootVersion=3.3.5 +jooqVersion=3.19.13 +hibernateValidatorVersion=8.0.1.Final +jcloudsVersion=2.6.0 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 1af9e0930b..df97d72b8b 100755 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/project-properties.gradle b/project-properties.gradle index 457a58de8a..29ff2d58f2 100755 --- a/project-properties.gradle +++ b/project-properties.gradle @@ -84,7 +84,3 @@ project.ext { '**/model/**' ] } - -wrapper { - gradleVersion = '8.10' -} diff --git a/src/main/java/com/epam/ta/reportportal/auth/CombinedTokenStore.java b/src/main/java/com/epam/ta/reportportal/auth/CombinedTokenStore.java index 457c416d5b..9c81637335 100644 --- a/src/main/java/com/epam/ta/reportportal/auth/CombinedTokenStore.java +++ b/src/main/java/com/epam/ta/reportportal/auth/CombinedTokenStore.java @@ -29,7 +29,7 @@ import java.util.HashSet; import java.util.Optional; import java.util.Set; -import javax.xml.bind.DatatypeConverter; +import jakarta.xml.bind.DatatypeConverter; import org.apache.commons.codec.digest.DigestUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.support.MessageSourceAccessor; @@ -37,7 +37,7 @@ import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.SpringSecurityMessageSource; import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken; +import org.springframework.security.oauth2.core.DefaultOAuth2AccessToken; import org.springframework.security.oauth2.common.OAuth2AccessToken; import org.springframework.security.oauth2.common.exceptions.InvalidTokenException; import org.springframework.security.oauth2.provider.OAuth2Authentication; diff --git a/src/main/java/com/epam/ta/reportportal/auth/event/UiAuthenticationFailureEventHandler.java b/src/main/java/com/epam/ta/reportportal/auth/event/UiAuthenticationFailureEventHandler.java index 073f1e3fa3..780e013687 100644 --- a/src/main/java/com/epam/ta/reportportal/auth/event/UiAuthenticationFailureEventHandler.java +++ b/src/main/java/com/epam/ta/reportportal/auth/event/UiAuthenticationFailureEventHandler.java @@ -21,9 +21,9 @@ import com.google.common.net.HttpHeaders; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; -import javax.inject.Inject; -import javax.inject.Provider; -import javax.servlet.http.HttpServletRequest; +import jakarta.inject.Inject; +import jakarta.inject.Provider; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.context.ApplicationListener; import org.springframework.security.authentication.event.AuthenticationFailureBadCredentialsEvent; import org.springframework.security.web.util.matcher.RequestHeaderRequestMatcher; @@ -85,4 +85,4 @@ private String getClientIP(HttpServletRequest request) { public void onApplicationEvent(AuthenticationFailureBadCredentialsEvent event) { onAjaxFailure(request.get()); } -} \ No newline at end of file +} diff --git a/src/main/java/com/epam/ta/reportportal/auth/permissions/AssignedToProjectPermission.java b/src/main/java/com/epam/ta/reportportal/auth/permissions/AssignedToProjectPermission.java index cef0796fe4..4a623eb14c 100644 --- a/src/main/java/com/epam/ta/reportportal/auth/permissions/AssignedToProjectPermission.java +++ b/src/main/java/com/epam/ta/reportportal/auth/permissions/AssignedToProjectPermission.java @@ -26,7 +26,6 @@ import java.util.Optional; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.Authentication; -import org.springframework.security.oauth2.provider.OAuth2Authentication; import org.springframework.stereotype.Component; /** @@ -78,4 +77,4 @@ private void fillProjectDetails(ReportPortalUser rpUser, String resolvedProjectN projectDetailsMapping.put(resolvedProjectName, projectDetails); rpUser.setProjectDetails(projectDetailsMapping); } -} \ No newline at end of file +} diff --git a/src/main/java/com/epam/ta/reportportal/auth/permissions/BaseProjectPermission.java b/src/main/java/com/epam/ta/reportportal/auth/permissions/BaseProjectPermission.java index 8d054d34a4..76c303a3d1 100644 --- a/src/main/java/com/epam/ta/reportportal/auth/permissions/BaseProjectPermission.java +++ b/src/main/java/com/epam/ta/reportportal/auth/permissions/BaseProjectPermission.java @@ -26,7 +26,6 @@ import java.util.Map; import java.util.Objects; import org.springframework.security.core.Authentication; -import org.springframework.security.oauth2.provider.OAuth2Authentication; /** * Base logic for project-related permissions. Validates project exists and there is provided in @@ -83,4 +82,4 @@ private void fillProjectDetails(ReportPortalUser rpUser, String resolvedProjectN * @return TRUE if access allowed */ abstract protected boolean checkAllowed(ReportPortalUser user, String project, ProjectRole role); -} \ No newline at end of file +} diff --git a/src/main/java/com/epam/ta/reportportal/auth/util/AuthUtils.java b/src/main/java/com/epam/ta/reportportal/auth/util/AuthUtils.java index 6e7dc8a246..2cc9ecde1e 100644 --- a/src/main/java/com/epam/ta/reportportal/auth/util/AuthUtils.java +++ b/src/main/java/com/epam/ta/reportportal/auth/util/AuthUtils.java @@ -31,7 +31,6 @@ import org.slf4j.LoggerFactory; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.oauth2.common.util.SerializationUtils; /** * Authentication utils diff --git a/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/service/impl/CreateRegexPatternTemplateHandler.java b/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/service/impl/CreateRegexPatternTemplateHandler.java index 51eb077776..1680616d80 100644 --- a/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/service/impl/CreateRegexPatternTemplateHandler.java +++ b/src/main/java/com/epam/ta/reportportal/core/analyzer/pattern/service/impl/CreateRegexPatternTemplateHandler.java @@ -22,7 +22,7 @@ import com.epam.reportportal.rules.exception.ReportPortalException; import com.epam.ta.reportportal.model.project.config.pattern.CreatePatternTemplateRQ; import com.epam.reportportal.rules.exception.ErrorType; -import javax.persistence.PersistenceException; +import jakarta.persistence.PersistenceException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; diff --git a/src/main/java/com/epam/ta/reportportal/core/annotation/Datastore.java b/src/main/java/com/epam/ta/reportportal/core/annotation/Datastore.java index f51801cfb3..d1e636d908 100644 --- a/src/main/java/com/epam/ta/reportportal/core/annotation/Datastore.java +++ b/src/main/java/com/epam/ta/reportportal/core/annotation/Datastore.java @@ -20,7 +20,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import javax.inject.Qualifier; +import jakarta.inject.Qualifier; @Target({ElementType.FIELD, ElementType.METHOD, ElementType.TYPE, ElementType.PARAMETER}) diff --git a/src/main/java/com/epam/ta/reportportal/core/annotation/Regular.java b/src/main/java/com/epam/ta/reportportal/core/annotation/Regular.java index c67a5fda38..f40bba6d19 100644 --- a/src/main/java/com/epam/ta/reportportal/core/annotation/Regular.java +++ b/src/main/java/com/epam/ta/reportportal/core/annotation/Regular.java @@ -20,7 +20,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import javax.inject.Qualifier; +import jakarta.inject.Qualifier; @Target({ElementType.FIELD, ElementType.METHOD, ElementType.TYPE, ElementType.PARAMETER}) diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/JacksonConfiguration.java b/src/main/java/com/epam/ta/reportportal/core/configs/JacksonConfiguration.java index b460a728ce..e1602f5037 100644 --- a/src/main/java/com/epam/ta/reportportal/core/configs/JacksonConfiguration.java +++ b/src/main/java/com/epam/ta/reportportal/core/configs/JacksonConfiguration.java @@ -22,6 +22,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector; +import com.fasterxml.jackson.databind.json.JsonMapper; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -37,13 +38,16 @@ public class JacksonConfiguration { */ @Bean(name = "objectMapper") public ObjectMapper objectMapper() { - ObjectMapper om = new ObjectMapper(); - om.setAnnotationIntrospector(new JacksonAnnotationIntrospector()); - om.configure(MapperFeature.DEFAULT_VIEW_INCLUSION, true); - om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - om.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); + ObjectMapper om = JsonMapper.builder() + .annotationIntrospector(new JacksonAnnotationIntrospector()) + .configure(MapperFeature.DEFAULT_VIEW_INCLUSION, true) + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) + .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false) + .build(); + om.registerModule(new JacksonViewAwareModule(om)); om.registerModule(new JavaTimeModule()); + return om; } } diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/MultipartDataConfig.java b/src/main/java/com/epam/ta/reportportal/core/configs/MultipartDataConfig.java index dfc5000a0c..33a44cca61 100644 --- a/src/main/java/com/epam/ta/reportportal/core/configs/MultipartDataConfig.java +++ b/src/main/java/com/epam/ta/reportportal/core/configs/MultipartDataConfig.java @@ -1,7 +1,7 @@ package com.epam.ta.reportportal.core.configs; import com.epam.ta.reportportal.util.BinaryDataResponseWriter; -import javax.activation.MimetypesFileTypeMap; +import jakarta.activation.MimetypesFileTypeMap; import org.apache.tika.parser.AutoDetectParser; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/MvcConfig.java b/src/main/java/com/epam/ta/reportportal/core/configs/MvcConfig.java index 606379e2f5..be5c19b024 100644 --- a/src/main/java/com/epam/ta/reportportal/core/configs/MvcConfig.java +++ b/src/main/java/com/epam/ta/reportportal/core/configs/MvcConfig.java @@ -31,6 +31,7 @@ import com.epam.ta.reportportal.ws.resolver.SortArgumentResolver; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.base.Preconditions; +import jakarta.servlet.http.HttpServletRequest; import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.List; @@ -51,9 +52,12 @@ import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.validation.beanvalidation.BeanValidationPostProcessor; import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.multipart.MultipartException; import org.springframework.web.multipart.MultipartHttpServletRequest; -import org.springframework.web.multipart.commons.CommonsMultipartResolver; +import org.springframework.web.multipart.MultipartResolver; import org.springframework.web.multipart.support.MultipartFilter; +import org.springframework.web.multipart.support.StandardMultipartHttpServletRequest; +import org.springframework.web.multipart.support.StandardServletMultipartResolver; import org.springframework.web.servlet.DispatcherServlet; import org.springframework.web.servlet.HandlerExceptionResolver; import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer; @@ -77,7 +81,7 @@ public class MvcConfig implements WebMvcConfigurer { private List> converters; private static final String[] CLASSPATH_RESOURCE_LOCATIONS = - { "classpath:/public/", "classpath:/META-INF/resources/", "classpath:/resources/" }; + {"classpath:/public/", "classpath:/META-INF/resources/", "classpath:/resources/"}; @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { @@ -202,13 +206,12 @@ public MultipartFilter multipartFilter() { @Profile("!unittest") @Bean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME) - public CommonsMultipartResolver multipartResolver(MultipartConfig multipartConfig) { - CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver() { + public StandardServletMultipartResolver multipartResolver(MultipartConfig multipartConfig) { + StandardServletMultipartResolver resolver = new StandardServletMultipartResolver() { @Override - protected DiskFileItemFactory newFileItemFactory() { - DiskFileItemFactory diskFileItemFactory = super.newFileItemFactory(); - diskFileItemFactory.setFileCleaningTracker(null); - return diskFileItemFactory; + public MultipartHttpServletRequest resolveMultipart(HttpServletRequest request) + throws MultipartException { + return new StandardMultipartHttpServletRequest(request, true); } @Override @@ -219,11 +222,11 @@ public void cleanupMultipart(MultipartHttpServletRequest request) { //Lazy resolving gives a way to process file limits inside a controller //level and handle exceptions in proper way. Fixes reportportal/reportportal#19 - commonsMultipartResolver.setResolveLazily(true); + resolver.setResolveLazily(true); - commonsMultipartResolver.setMaxUploadSize(multipartConfig.maxUploadSize); - commonsMultipartResolver.setMaxUploadSizePerFile(multipartConfig.maxFileSize); - return commonsMultipartResolver; +/* commonsMultipartResolver.setMaxUploadSize(multipartConfig.maxUploadSize); + commonsMultipartResolver.setMaxUploadSizePerFile(multipartConfig.maxFileSize);*/ + return resolver; } @ConfigurationProperties("rp.upload") diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/PluginConfiguration.java b/src/main/java/com/epam/ta/reportportal/core/configs/PluginConfiguration.java index 3f60ab5ec4..2f3402904d 100644 --- a/src/main/java/com/epam/ta/reportportal/core/configs/PluginConfiguration.java +++ b/src/main/java/com/epam/ta/reportportal/core/configs/PluginConfiguration.java @@ -28,7 +28,7 @@ import java.nio.file.Paths; import java.util.Collections; import java.util.Set; -import javax.activation.FileTypeMap; +import jakarta.activation.FileTypeMap; import org.pf4j.DefaultExtensionFinder; import org.pf4j.DefaultPluginManager; diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/SchedulerConfiguration.java b/src/main/java/com/epam/ta/reportportal/core/configs/SchedulerConfiguration.java index a994945398..0f34d51cd3 100644 --- a/src/main/java/com/epam/ta/reportportal/core/configs/SchedulerConfiguration.java +++ b/src/main/java/com/epam/ta/reportportal/core/configs/SchedulerConfiguration.java @@ -22,7 +22,7 @@ import java.time.Duration; import java.util.List; import java.util.Properties; -import javax.inject.Named; +import jakarta.inject.Named; import javax.sql.DataSource; import org.quartz.Job; import org.quartz.JobDetail; diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/SecurityConfiguration.java b/src/main/java/com/epam/ta/reportportal/core/configs/SecurityConfiguration.java index a118981afe..51887e5f0f 100644 --- a/src/main/java/com/epam/ta/reportportal/core/configs/SecurityConfiguration.java +++ b/src/main/java/com/epam/ta/reportportal/core/configs/SecurityConfiguration.java @@ -41,6 +41,7 @@ import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; @@ -182,7 +183,7 @@ private AccessDecisionManager webAccessDecisionManager() { public void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .accessDecisionManager(webAccessDecisionManager()) - .antMatchers("/**/user**/registration/info*", + .requestMatchers("/**/user**/registration/info*", "/**/user**/registration**", "/**/user**/password/reset/*", "/**/user**/password/reset**", @@ -194,9 +195,9 @@ public void configure(HttpSecurity http) throws Exception { ) .permitAll() /* set of special endpoints for another microservices from RP ecosystem */ - .antMatchers("/api-internal/**") + .requestMatchers("/api-internal/**") .hasRole("COMPONENT") - .antMatchers("/v2/**", "/swagger-resources", "/certificate/**", "/api/**", "/**") + .requestMatchers("/v2/**", "/swagger-resources", "/certificate/**", "/api/**", "/**") .hasRole("USER") .anyRequest() .authenticated() diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/SpringDocConfiguration.java b/src/main/java/com/epam/ta/reportportal/core/configs/SpringDocConfiguration.java index c4dce9b7f7..5f436a22d4 100644 --- a/src/main/java/com/epam/ta/reportportal/core/configs/SpringDocConfiguration.java +++ b/src/main/java/com/epam/ta/reportportal/core/configs/SpringDocConfiguration.java @@ -62,11 +62,11 @@ import java.util.Map; import java.util.Set; import java.util.stream.Collectors; -import javax.servlet.ServletContext; +import jakarta.servlet.ServletContext; import org.apache.commons.lang3.StringUtils; -import org.springdoc.core.SpringDocUtils; -import org.springdoc.core.customizers.OpenApiCustomiser; +import org.springdoc.core.customizers.OpenApiCustomizer; import org.springdoc.core.customizers.OperationCustomizer; +import org.springdoc.core.utils.SpringDocUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; @@ -168,7 +168,7 @@ public Schema resolve(AnnotatedType annotatedType, ModelConverterContext context } @Bean - public OpenApiCustomiser sortTagsAlphabetically() { + public OpenApiCustomizer sortTagsAlphabetically() { return openApi -> { List sortedTags = openApi.getTags().stream() .sorted(Comparator.comparing(Tag::getName)) diff --git a/src/main/java/com/epam/ta/reportportal/core/dashboard/impl/DeleteDashboardHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/dashboard/impl/DeleteDashboardHandlerImpl.java index fbca7cc47f..1c0ad6cb7d 100644 --- a/src/main/java/com/epam/ta/reportportal/core/dashboard/impl/DeleteDashboardHandlerImpl.java +++ b/src/main/java/com/epam/ta/reportportal/core/dashboard/impl/DeleteDashboardHandlerImpl.java @@ -70,7 +70,7 @@ public OperationCompletionRS deleteDashboard(Long dashboardId, ReportPortalUser. projectDetails.getProjectName() )); - Set dashboardWidgets = dashboard.getDashboardWidgets(); + Set dashboardWidgets = dashboard.getWidgets(); List widgets = dashboardWidgets.stream() .filter(DashboardWidget::isCreatedOn) .map(DashboardWidget::getWidget) diff --git a/src/main/java/com/epam/ta/reportportal/core/dashboard/impl/UpdateDashboardHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/dashboard/impl/UpdateDashboardHandlerImpl.java index 32ffbee46f..03be37d358 100644 --- a/src/main/java/com/epam/ta/reportportal/core/dashboard/impl/UpdateDashboardHandlerImpl.java +++ b/src/main/java/com/epam/ta/reportportal/core/dashboard/impl/UpdateDashboardHandlerImpl.java @@ -110,7 +110,7 @@ public OperationCompletionRS addWidget(Long dashboardId, ReportPortalUser.Projec dashboardId, projectDetails.getProjectName() )); - Set dashboardWidgets = dashboard.getDashboardWidgets(); + Set dashboardWidgets = dashboard.getWidgets(); validateWidgetBeforeAddingToDashboard(rq, dashboard, dashboardWidgets); @@ -171,7 +171,7 @@ public OperationCompletionRS removeWidget(Long widgetId, Long dashboardId, Repor return result; } - DashboardWidget toRemove = dashboard.getDashboardWidgets() + DashboardWidget toRemove = dashboard.getWidgets() .stream() .filter(dashboardWidget -> widget.getId().equals(dashboardWidget.getId().getWidgetId())) .findFirst() diff --git a/src/main/java/com/epam/ta/reportportal/core/events/annotations/WidgetLimitRange.java b/src/main/java/com/epam/ta/reportportal/core/events/annotations/WidgetLimitRange.java index d547f45436..9fe985d320 100644 --- a/src/main/java/com/epam/ta/reportportal/core/events/annotations/WidgetLimitRange.java +++ b/src/main/java/com/epam/ta/reportportal/core/events/annotations/WidgetLimitRange.java @@ -1,6 +1,6 @@ package com.epam.ta.reportportal.core.events.annotations; -import javax.validation.Constraint; +import jakarta.validation.Constraint; import java.lang.annotation.*; /** diff --git a/src/main/java/com/epam/ta/reportportal/core/events/annotations/WidgetLimitRangeValidator.java b/src/main/java/com/epam/ta/reportportal/core/events/annotations/WidgetLimitRangeValidator.java index 57067935a7..92a1395aea 100644 --- a/src/main/java/com/epam/ta/reportportal/core/events/annotations/WidgetLimitRangeValidator.java +++ b/src/main/java/com/epam/ta/reportportal/core/events/annotations/WidgetLimitRangeValidator.java @@ -7,8 +7,8 @@ import com.epam.ta.reportportal.model.widget.MaterializedWidgetType; import com.epam.ta.reportportal.model.widget.WidgetRQ; import java.util.Arrays; -import javax.validation.ConstraintValidator; -import javax.validation.ConstraintValidatorContext; +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; /** * @author Pavel Bortnik @@ -18,8 +18,7 @@ public class WidgetLimitRangeValidator @Override public boolean isValid(BaseEntityRQ value, ConstraintValidatorContext context) { - if (value instanceof WidgetRQ) { - WidgetRQ widgetRQ = (WidgetRQ) value; + if (value instanceof WidgetRQ widgetRQ) { int limit = widgetRQ.getContentParameters().getItemsCount(); if (Arrays.stream(MaterializedWidgetType.values()) .anyMatch(it -> it.getType().equalsIgnoreCase(widgetRQ.getWidgetType()))) { diff --git a/src/main/java/com/epam/ta/reportportal/core/integration/plugin/binary/PluginFilesProvider.java b/src/main/java/com/epam/ta/reportportal/core/integration/plugin/binary/PluginFilesProvider.java index 7f2deb45c9..be1708372c 100644 --- a/src/main/java/com/epam/ta/reportportal/core/integration/plugin/binary/PluginFilesProvider.java +++ b/src/main/java/com/epam/ta/reportportal/core/integration/plugin/binary/PluginFilesProvider.java @@ -25,7 +25,7 @@ import java.io.IOException; import java.io.InputStream; import java.nio.file.Paths; -import javax.activation.FileTypeMap; +import jakarta.activation.FileTypeMap; import org.apache.commons.io.FileUtils; /** diff --git a/src/main/java/com/epam/ta/reportportal/core/integration/plugin/impl/PluginLoaderImpl.java b/src/main/java/com/epam/ta/reportportal/core/integration/plugin/impl/PluginLoaderImpl.java index 559c4c600b..834c681ce1 100644 --- a/src/main/java/com/epam/ta/reportportal/core/integration/plugin/impl/PluginLoaderImpl.java +++ b/src/main/java/com/epam/ta/reportportal/core/integration/plugin/impl/PluginLoaderImpl.java @@ -43,7 +43,7 @@ import java.util.Optional; import java.util.jar.JarEntry; import java.util.jar.JarFile; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.StringUtils; import org.pf4j.PluginDescriptor; diff --git a/src/main/java/com/epam/ta/reportportal/core/integration/util/EmailServerIntegrationService.java b/src/main/java/com/epam/ta/reportportal/core/integration/util/EmailServerIntegrationService.java index 4078810022..2f18488005 100644 --- a/src/main/java/com/epam/ta/reportportal/core/integration/util/EmailServerIntegrationService.java +++ b/src/main/java/com/epam/ta/reportportal/core/integration/util/EmailServerIntegrationService.java @@ -33,7 +33,7 @@ import com.mchange.lang.IntegerUtils; import java.util.Map; import java.util.Optional; -import javax.mail.MessagingException; +import jakarta.mail.MessagingException; import org.apache.commons.collections.MapUtils; import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.validator.routines.UrlValidator; diff --git a/src/main/java/com/epam/ta/reportportal/core/item/impl/StartTestItemHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/item/impl/StartTestItemHandlerImpl.java index 396c6f3671..c5cdd16a51 100644 --- a/src/main/java/com/epam/ta/reportportal/core/item/impl/StartTestItemHandlerImpl.java +++ b/src/main/java/com/epam/ta/reportportal/core/item/impl/StartTestItemHandlerImpl.java @@ -134,7 +134,7 @@ public ItemCreatedRS startChildItem(ReportPortalUser user, ReportPortalUser.ProjectDetails projectDetails, StartTestItemRQ rq, String parentId) { boolean isRetry = - BooleanUtils.toBoolean(rq.isRetry()) || StringUtils.isNotBlank(rq.getRetryOf()); + BooleanUtils.toBoolean(rq.getRetry()) || StringUtils.isNotBlank(rq.getRetryOf()); Launch launch = launchRepository.findByUuid(rq.getLaunchUuid()) .orElseThrow(() -> new ReportPortalException(LAUNCH_NOT_FOUND, rq.getLaunchUuid())); @@ -233,7 +233,7 @@ private void validate(ReportPortalUser user, ReportPortalUser.ProjectDetails pro launch.getStartTime(), launch.getId() ); - expect(isTrue(BooleanUtils.toBoolean(rq.isRetry())), equalTo(false)).verify(BAD_REQUEST_ERROR, + expect(isTrue(BooleanUtils.toBoolean(rq.getRetry())), equalTo(false)).verify(BAD_REQUEST_ERROR, "Root test item can't be a retry."); } diff --git a/src/main/java/com/epam/ta/reportportal/core/item/impl/history/TestItemsHistoryHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/item/impl/history/TestItemsHistoryHandlerImpl.java index 9b5863342d..fb9b6cb859 100644 --- a/src/main/java/com/epam/ta/reportportal/core/item/impl/history/TestItemsHistoryHandlerImpl.java +++ b/src/main/java/com/epam/ta/reportportal/core/item/impl/history/TestItemsHistoryHandlerImpl.java @@ -60,7 +60,7 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; -import org.springframework.data.repository.support.PageableExecutionUtils; +import org.springframework.data.support.PageableExecutionUtils; import org.springframework.stereotype.Service; /** diff --git a/src/main/java/com/epam/ta/reportportal/core/launch/GetLaunchHandler.java b/src/main/java/com/epam/ta/reportportal/core/launch/GetLaunchHandler.java index 761e9c82b0..2ba7b3d32a 100644 --- a/src/main/java/com/epam/ta/reportportal/core/launch/GetLaunchHandler.java +++ b/src/main/java/com/epam/ta/reportportal/core/launch/GetLaunchHandler.java @@ -26,7 +26,7 @@ import java.io.OutputStream; import java.util.List; import java.util.Map; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.data.domain.Pageable; //import com.epam.ta.reportportal.entity.widget.content.ComparisonStatisticsContent; @@ -178,4 +178,4 @@ Iterable getClusters(String launchId, ReportPortalUser.ProjectDetails projectDetails, Pageable pageable); boolean hasItemsWithIssues(Launch launch); -} \ No newline at end of file +} diff --git a/src/main/java/com/epam/ta/reportportal/core/launch/util/LinkGenerator.java b/src/main/java/com/epam/ta/reportportal/core/launch/util/LinkGenerator.java index 828dc436e9..a7ed1715b5 100644 --- a/src/main/java/com/epam/ta/reportportal/core/launch/util/LinkGenerator.java +++ b/src/main/java/com/epam/ta/reportportal/core/launch/util/LinkGenerator.java @@ -16,13 +16,16 @@ package com.epam.ta.reportportal.core.launch.util; -import javax.annotation.PostConstruct; -import javax.servlet.http.HttpServletRequest; +import jakarta.annotation.PostConstruct; +import jakarta.servlet.http.HttpServletRequest; +import java.net.URI; +import java.util.Collections; +import lombok.SneakyThrows; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Value; -import org.springframework.http.server.ServletServerHttpRequest; +import org.springframework.http.HttpHeaders; import org.springframework.stereotype.Component; -import org.springframework.web.util.UriComponentsBuilder; +import org.springframework.web.util.ForwardedHeaderUtils; /** * @author Ihar Kahadouski @@ -51,13 +54,21 @@ public static String generateLaunchLink(String baseUrl, String projectName, Stri return StringUtils.isEmpty(baseUrl) ? null : baseUrl + UI_PREFIX + projectName + LAUNCHES + id; } + @SneakyThrows public static String composeBaseUrl(HttpServletRequest request) { String processedPath = "/".equals(path) ? null : path.replace("/api", ""); /* * Use Uri components since they are aware of x-forwarded-host headers */ - return UriComponentsBuilder.fromHttpRequest(new ServletServerHttpRequest(request)) + + HttpHeaders httpHeaders = new HttpHeaders(); + Collections.list(request.getHeaderNames()) + .forEach(headerName-> httpHeaders.add(headerName, request.getHeader(headerName))); + + URI uri = new URI(request.getRequestURI()); + + return ForwardedHeaderUtils.adaptFromForwardedHeaders(uri, httpHeaders) .replacePath(processedPath) .replaceQuery(null) .build() diff --git a/src/main/java/com/epam/ta/reportportal/core/log/impl/GetLogHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/log/impl/GetLogHandlerImpl.java index 065c6688b6..5a70af1cea 100644 --- a/src/main/java/com/epam/ta/reportportal/core/log/impl/GetLogHandlerImpl.java +++ b/src/main/java/com/epam/ta/reportportal/core/log/impl/GetLogHandlerImpl.java @@ -73,7 +73,7 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; -import org.springframework.data.repository.support.PageableExecutionUtils; +import org.springframework.data.support.PageableExecutionUtils; import org.springframework.lang.Nullable; import org.springframework.stereotype.Service; diff --git a/src/main/java/com/epam/ta/reportportal/core/logging/HttpLoggingAspect.java b/src/main/java/com/epam/ta/reportportal/core/logging/HttpLoggingAspect.java index 9aca8d05cc..790e7b05ef 100644 --- a/src/main/java/com/epam/ta/reportportal/core/logging/HttpLoggingAspect.java +++ b/src/main/java/com/epam/ta/reportportal/core/logging/HttpLoggingAspect.java @@ -25,7 +25,7 @@ import java.nio.charset.StandardCharsets; import java.util.Enumeration; import java.util.concurrent.atomic.AtomicLong; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; @@ -103,14 +103,14 @@ protected Object getBody(ProceedingJoinPoint joinPoint, Method method) { Object arg = args[i]; if (arg != null) { - if (arg instanceof MultipartHttpServletRequest) { + if (arg instanceof MultipartHttpServletRequest request) { body = BODY_BINARY_MARK; break; } else if (parameters[i].isAnnotationPresent(RequestBody.class)) { body = arg; break; - } else if (arg instanceof HttpEntity) { - body = ((HttpEntity) arg).getBody(); + } else if (arg instanceof HttpEntity httpEntity) { + body = httpEntity.getBody(); break; } } @@ -171,13 +171,13 @@ protected String formatResponseRecord(long count, String prefix, Object response record.append(" (").append(executionTime).append(" ms)"); } - if (response instanceof ResponseEntity) { - HttpStatus status = ((ResponseEntity) response).getStatusCode(); + if (response instanceof ResponseEntity responseEntity) { + HttpStatus status = HttpStatus.resolve(responseEntity.getStatusCode().value()); record.append(NEWLINE).append(' ').append(status).append(" - ") .append(status.getReasonPhrase()); if (annotation.logHeaders()) { - HttpHeaders headers = ((ResponseEntity) response).getHeaders(); + HttpHeaders headers = responseEntity.getHeaders(); for (String name : headers.keySet()) { record.append(NEWLINE).append(' ').append(name).append(':'); boolean comma = false; diff --git a/src/main/java/com/epam/ta/reportportal/core/logging/RabbitMessageLoggingAspect.java b/src/main/java/com/epam/ta/reportportal/core/logging/RabbitMessageLoggingAspect.java index 1c3fb13f1c..a6d23c8ffd 100644 --- a/src/main/java/com/epam/ta/reportportal/core/logging/RabbitMessageLoggingAspect.java +++ b/src/main/java/com/epam/ta/reportportal/core/logging/RabbitMessageLoggingAspect.java @@ -78,8 +78,7 @@ protected Object getHeadersAndBody(ProceedingJoinPoint joinPoint, Method method, Object arg = args[i]; if (arg != null) { - if (arg instanceof Message) { - Message message = (Message) arg; + if (arg instanceof Message message) { body = messageConverter.fromMessage(message); headers.putAll(message.getMessageProperties().getHeaders()); break; diff --git a/src/main/java/com/epam/ta/reportportal/core/project/GetProjectHandler.java b/src/main/java/com/epam/ta/reportportal/core/project/GetProjectHandler.java index ce078885f9..ecf8563e48 100644 --- a/src/main/java/com/epam/ta/reportportal/core/project/GetProjectHandler.java +++ b/src/main/java/com/epam/ta/reportportal/core/project/GetProjectHandler.java @@ -28,7 +28,7 @@ import java.io.OutputStream; import java.util.List; import java.util.Map; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.data.domain.Pageable; /** @@ -117,4 +117,4 @@ Iterable getUserNames(String value, void exportProjects(ReportFormat reportFormat, Queryable filter, OutputStream outputStream); Map getAnalyzerIndexingStatus(); -} \ No newline at end of file +} diff --git a/src/main/java/com/epam/ta/reportportal/core/user/GetUserHandler.java b/src/main/java/com/epam/ta/reportportal/core/user/GetUserHandler.java index 9f2605452c..ed297e866e 100644 --- a/src/main/java/com/epam/ta/reportportal/core/user/GetUserHandler.java +++ b/src/main/java/com/epam/ta/reportportal/core/user/GetUserHandler.java @@ -25,7 +25,7 @@ import com.epam.ta.reportportal.model.user.UserResource; import java.io.OutputStream; import java.util.Map; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.data.domain.Pageable; /** diff --git a/src/main/java/com/epam/ta/reportportal/core/user/impl/ApiKeyHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/user/impl/ApiKeyHandlerImpl.java index 72c0a29dc7..a59fc033da 100644 --- a/src/main/java/com/epam/ta/reportportal/core/user/impl/ApiKeyHandlerImpl.java +++ b/src/main/java/com/epam/ta/reportportal/core/user/impl/ApiKeyHandlerImpl.java @@ -37,7 +37,7 @@ import java.util.Base64; import java.util.List; import java.util.UUID; -import javax.xml.bind.DatatypeConverter; +import jakarta.xml.bind.DatatypeConverter; import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.lang3.ArrayUtils; import org.springframework.beans.factory.annotation.Autowired; diff --git a/src/main/java/com/epam/ta/reportportal/core/user/impl/CreateUserHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/user/impl/CreateUserHandlerImpl.java index be03e51575..50b974b731 100644 --- a/src/main/java/com/epam/ta/reportportal/core/user/impl/CreateUserHandlerImpl.java +++ b/src/main/java/com/epam/ta/reportportal/core/user/impl/CreateUserHandlerImpl.java @@ -79,11 +79,10 @@ import com.epam.ta.reportportal.ws.converter.converters.UserCreationBidConverter; import com.epam.ta.reportportal.ws.reporting.OperationCompletionRS; import com.google.common.collect.Maps; -import java.util.List; import java.util.Map; import java.util.Optional; import java.util.function.Predicate; -import javax.persistence.PersistenceException; +import jakarta.persistence.PersistenceException; import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.tuple.Pair; import org.hibernate.exception.ConstraintViolationException; @@ -225,9 +224,8 @@ private Pair saveUser(CreateUserRQFull reque creator.getId(), creator.getLogin(), isSystemEvent); eventPublisher.publishEvent(userCreatedEvent); } catch (PersistenceException pe) { - if (pe.getCause() instanceof ConstraintViolationException) { - fail().withError(RESOURCE_ALREADY_EXISTS, - ((ConstraintViolationException) pe.getCause()).getConstraintName()); + if (pe.getCause() instanceof ConstraintViolationException cve) { + fail().withError(RESOURCE_ALREADY_EXISTS, cve.getConstraintName()); } throw new ReportPortalException("Error while User creating: " + pe.getMessage(), pe); } catch (Exception exp) { diff --git a/src/main/java/com/epam/ta/reportportal/job/CleanOutdatedPluginsJob.java b/src/main/java/com/epam/ta/reportportal/job/CleanOutdatedPluginsJob.java index ada8bde7b5..4b0f3e16ae 100644 --- a/src/main/java/com/epam/ta/reportportal/job/CleanOutdatedPluginsJob.java +++ b/src/main/java/com/epam/ta/reportportal/job/CleanOutdatedPluginsJob.java @@ -32,7 +32,7 @@ import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import org.pf4j.PluginWrapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/com/epam/ta/reportportal/job/SelfCancelableJob.java b/src/main/java/com/epam/ta/reportportal/job/SelfCancelableJob.java index 863c852f52..4ff9d3cd8b 100644 --- a/src/main/java/com/epam/ta/reportportal/job/SelfCancelableJob.java +++ b/src/main/java/com/epam/ta/reportportal/job/SelfCancelableJob.java @@ -16,6 +16,7 @@ package com.epam.ta.reportportal.job; +import java.time.Instant; import java.util.Date; import org.springframework.scheduling.Trigger; import org.springframework.scheduling.TriggerContext; @@ -52,4 +53,4 @@ protected void oneMoreTime(boolean oneMoreTime) { this.oneMoreTime = oneMoreTime; } -} \ No newline at end of file +} diff --git a/src/main/java/com/epam/ta/reportportal/model/ActivityEventResource.java b/src/main/java/com/epam/ta/reportportal/model/ActivityEventResource.java index 9ef458af0e..62150720a1 100644 --- a/src/main/java/com/epam/ta/reportportal/model/ActivityEventResource.java +++ b/src/main/java/com/epam/ta/reportportal/model/ActivityEventResource.java @@ -22,7 +22,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; import java.time.Instant; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import lombok.Builder; import lombok.Getter; import lombok.Setter; diff --git a/src/main/java/com/epam/ta/reportportal/model/ApiKeyRQ.java b/src/main/java/com/epam/ta/reportportal/model/ApiKeyRQ.java index f7ed6fa678..6b27260514 100644 --- a/src/main/java/com/epam/ta/reportportal/model/ApiKeyRQ.java +++ b/src/main/java/com/epam/ta/reportportal/model/ApiKeyRQ.java @@ -19,7 +19,7 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; /** * Api key representation for request diff --git a/src/main/java/com/epam/ta/reportportal/model/ApiKeyRS.java b/src/main/java/com/epam/ta/reportportal/model/ApiKeyRS.java index 6e92766052..11081395bb 100644 --- a/src/main/java/com/epam/ta/reportportal/model/ApiKeyRS.java +++ b/src/main/java/com/epam/ta/reportportal/model/ApiKeyRS.java @@ -20,7 +20,7 @@ import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; import java.time.Instant; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import lombok.Getter; import lombok.Setter; import lombok.ToString; diff --git a/src/main/java/com/epam/ta/reportportal/model/ApiKeysRS.java b/src/main/java/com/epam/ta/reportportal/model/ApiKeysRS.java index ac9108aec8..ce308ba641 100644 --- a/src/main/java/com/epam/ta/reportportal/model/ApiKeysRS.java +++ b/src/main/java/com/epam/ta/reportportal/model/ApiKeysRS.java @@ -20,7 +20,7 @@ import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; import java.util.List; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; /** * Container for ApiKeysRS diff --git a/src/main/java/com/epam/ta/reportportal/model/BaseEntityRQ.java b/src/main/java/com/epam/ta/reportportal/model/BaseEntityRQ.java index f776a915eb..8e5f8e66e8 100644 --- a/src/main/java/com/epam/ta/reportportal/model/BaseEntityRQ.java +++ b/src/main/java/com/epam/ta/reportportal/model/BaseEntityRQ.java @@ -21,7 +21,7 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.Size; +import jakarta.validation.constraints.Size; /** * Base entity for manipulating sharable resources @@ -43,4 +43,4 @@ public void setDescription(String description) { this.description = description; } -} \ No newline at end of file +} diff --git a/src/main/java/com/epam/ta/reportportal/model/BulkRQ.java b/src/main/java/com/epam/ta/reportportal/model/BulkRQ.java index a22f6c9fdc..9683944b14 100644 --- a/src/main/java/com/epam/ta/reportportal/model/BulkRQ.java +++ b/src/main/java/com/epam/ta/reportportal/model/BulkRQ.java @@ -18,8 +18,8 @@ import com.fasterxml.jackson.annotation.JsonProperty; import java.util.Map; -import javax.validation.Valid; -import javax.validation.constraints.NotNull; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; /** * @param Type of Key diff --git a/src/main/java/com/epam/ta/reportportal/model/CollectionsRQ.java b/src/main/java/com/epam/ta/reportportal/model/CollectionsRQ.java index 718d526f3e..01322300e2 100644 --- a/src/main/java/com/epam/ta/reportportal/model/CollectionsRQ.java +++ b/src/main/java/com/epam/ta/reportportal/model/CollectionsRQ.java @@ -18,8 +18,8 @@ import com.fasterxml.jackson.annotation.JsonProperty; import java.util.List; -import javax.validation.Valid; -import javax.validation.constraints.NotNull; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; /** * @deprecated use {@link BulkRQ} instead @@ -47,4 +47,4 @@ public String toString() { sb.append('}'); return sb.toString(); } -} \ No newline at end of file +} diff --git a/src/main/java/com/epam/ta/reportportal/model/DeleteBulkRQ.java b/src/main/java/com/epam/ta/reportportal/model/DeleteBulkRQ.java index a64eed9377..c73de9f212 100644 --- a/src/main/java/com/epam/ta/reportportal/model/DeleteBulkRQ.java +++ b/src/main/java/com/epam/ta/reportportal/model/DeleteBulkRQ.java @@ -18,7 +18,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import java.util.List; -import javax.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotEmpty; /** * @author Ivan Budayeu diff --git a/src/main/java/com/epam/ta/reportportal/model/PagedResponse.java b/src/main/java/com/epam/ta/reportportal/model/PagedResponse.java index a97497dfd0..4766d0bb46 100644 --- a/src/main/java/com/epam/ta/reportportal/model/PagedResponse.java +++ b/src/main/java/com/epam/ta/reportportal/model/PagedResponse.java @@ -20,7 +20,7 @@ import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; import java.util.List; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; /** * Paged representation. @@ -115,4 +115,4 @@ public void setItems(List items) { this.items = items; } -} \ No newline at end of file +} diff --git a/src/main/java/com/epam/ta/reportportal/model/SearchCriteria.java b/src/main/java/com/epam/ta/reportportal/model/SearchCriteria.java index f0be5091ea..072dcfc6d8 100644 --- a/src/main/java/com/epam/ta/reportportal/model/SearchCriteria.java +++ b/src/main/java/com/epam/ta/reportportal/model/SearchCriteria.java @@ -22,7 +22,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; import java.util.Objects; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; /** * Search Criteria used for a compound query and subsequent conversion to a filter. @@ -95,4 +95,4 @@ public boolean equals(Object o) { public int hashCode() { return Objects.hash(filterKey); } -} \ No newline at end of file +} diff --git a/src/main/java/com/epam/ta/reportportal/model/SearchCriteriaRQ.java b/src/main/java/com/epam/ta/reportportal/model/SearchCriteriaRQ.java index 58e0cde7ec..73d835a75f 100644 --- a/src/main/java/com/epam/ta/reportportal/model/SearchCriteriaRQ.java +++ b/src/main/java/com/epam/ta/reportportal/model/SearchCriteriaRQ.java @@ -20,7 +20,7 @@ import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; import java.util.Set; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; /** * Keep all search criteria for request. @@ -49,4 +49,4 @@ public void setCriteriaList(Set criteriaList) { this.criteriaList = criteriaList; } -} \ No newline at end of file +} diff --git a/src/main/java/com/epam/ta/reportportal/model/dashboard/AddWidgetRq.java b/src/main/java/com/epam/ta/reportportal/model/dashboard/AddWidgetRq.java index 8e563ae71b..b4e4f3d928 100644 --- a/src/main/java/com/epam/ta/reportportal/model/dashboard/AddWidgetRq.java +++ b/src/main/java/com/epam/ta/reportportal/model/dashboard/AddWidgetRq.java @@ -18,8 +18,8 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.Valid; -import javax.validation.constraints.NotNull; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; /** * @author Pavel Bortnik diff --git a/src/main/java/com/epam/ta/reportportal/model/dashboard/CreateDashboardRQ.java b/src/main/java/com/epam/ta/reportportal/model/dashboard/CreateDashboardRQ.java index 8a6d16a344..958fdfda9b 100644 --- a/src/main/java/com/epam/ta/reportportal/model/dashboard/CreateDashboardRQ.java +++ b/src/main/java/com/epam/ta/reportportal/model/dashboard/CreateDashboardRQ.java @@ -17,8 +17,8 @@ package com.epam.ta.reportportal.model.dashboard; import com.epam.ta.reportportal.model.BaseEntityRQ; -import com.epam.reportportal.annotations.NotBlankWithSize; import com.epam.reportportal.model.ValidationConstraints; +import com.epam.ta.reportportal.ws.annotations.NotBlankWithSize; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; @@ -54,4 +54,4 @@ public String toString() { sb.append('}'); return sb.toString(); } -} \ No newline at end of file +} diff --git a/src/main/java/com/epam/ta/reportportal/model/dashboard/DashboardResource.java b/src/main/java/com/epam/ta/reportportal/model/dashboard/DashboardResource.java index 2dc312ac94..819814bffe 100644 --- a/src/main/java/com/epam/ta/reportportal/model/dashboard/DashboardResource.java +++ b/src/main/java/com/epam/ta/reportportal/model/dashboard/DashboardResource.java @@ -26,9 +26,9 @@ import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; import java.util.List; import java.util.Map; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; /** * Domain model DashBoard resource object. JSON Representation of Report Portal diff --git a/src/main/java/com/epam/ta/reportportal/model/dashboard/UpdateDashboardRQ.java b/src/main/java/com/epam/ta/reportportal/model/dashboard/UpdateDashboardRQ.java index 483a7fdc24..0ca18b72f7 100644 --- a/src/main/java/com/epam/ta/reportportal/model/dashboard/UpdateDashboardRQ.java +++ b/src/main/java/com/epam/ta/reportportal/model/dashboard/UpdateDashboardRQ.java @@ -17,7 +17,7 @@ package com.epam.ta.reportportal.model.dashboard; import com.epam.ta.reportportal.model.BaseEntityRQ; -import com.epam.reportportal.annotations.NotBlankWithSize; +import com.epam.ta.reportportal.ws.annotations.NotBlankWithSize; import com.epam.reportportal.model.ValidationConstraints; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; @@ -25,7 +25,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; import java.util.List; -import javax.validation.Valid; +import jakarta.validation.Valid; /** * Domain object for updating widget positions. @@ -64,4 +64,4 @@ public List getWidgets() { public String toString() { return "UpdateDashboardRQ{" + "name='" + name + '\'' + ", widgets=" + widgets + '}'; } -} \ No newline at end of file +} diff --git a/src/main/java/com/epam/ta/reportportal/model/externalsystem/BtsConnectionTestRQ.java b/src/main/java/com/epam/ta/reportportal/model/externalsystem/BtsConnectionTestRQ.java index 8432bb86cd..a17c1a11f8 100644 --- a/src/main/java/com/epam/ta/reportportal/model/externalsystem/BtsConnectionTestRQ.java +++ b/src/main/java/com/epam/ta/reportportal/model/externalsystem/BtsConnectionTestRQ.java @@ -17,7 +17,7 @@ package com.epam.ta.reportportal.model.externalsystem; import com.fasterxml.jackson.annotation.JsonInclude; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; /** * @author Ivan Budayeu diff --git a/src/main/java/com/epam/ta/reportportal/model/filter/BulkUpdateFilterRQ.java b/src/main/java/com/epam/ta/reportportal/model/filter/BulkUpdateFilterRQ.java index 8e7df6bf70..3844688e94 100644 --- a/src/main/java/com/epam/ta/reportportal/model/filter/BulkUpdateFilterRQ.java +++ b/src/main/java/com/epam/ta/reportportal/model/filter/BulkUpdateFilterRQ.java @@ -18,7 +18,7 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; /** * @deprecated use {@link UpdateUserFilterRQ} in conjunction with @@ -44,4 +44,4 @@ public void setId(String id) { public String toString() { return "BulkUpdateFilterRQ{" + "id='" + id + '\'' + '}'; } -} \ No newline at end of file +} diff --git a/src/main/java/com/epam/ta/reportportal/model/filter/Order.java b/src/main/java/com/epam/ta/reportportal/model/filter/Order.java index e18ca361d8..dc0c39bc25 100644 --- a/src/main/java/com/epam/ta/reportportal/model/filter/Order.java +++ b/src/main/java/com/epam/ta/reportportal/model/filter/Order.java @@ -18,7 +18,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; /** * @author Pavel Bortnik diff --git a/src/main/java/com/epam/ta/reportportal/model/filter/UpdateUserFilterRQ.java b/src/main/java/com/epam/ta/reportportal/model/filter/UpdateUserFilterRQ.java index dd6d1a74d2..7c6af249f3 100644 --- a/src/main/java/com/epam/ta/reportportal/model/filter/UpdateUserFilterRQ.java +++ b/src/main/java/com/epam/ta/reportportal/model/filter/UpdateUserFilterRQ.java @@ -22,8 +22,8 @@ import static com.epam.reportportal.model.ValidationConstraints.MIN_NAME_LENGTH; import com.epam.ta.reportportal.model.BaseEntityRQ; -import com.epam.reportportal.annotations.In; -import com.epam.reportportal.annotations.NotBlankWithSize; +import com.epam.ta.reportportal.ws.annotations.In; +import com.epam.ta.reportportal.ws.annotations.NotBlankWithSize; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; @@ -33,10 +33,10 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Set; -import javax.validation.Valid; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; /** * Domain object for filter actions @@ -110,4 +110,4 @@ public String toString() { return "UpdateUserFilterRQ{" + "name='" + name + '\'' + ", objectType='" + objectType + '\'' + ", conditions=" + conditions + ", orders=" + orders + '}'; } -} \ No newline at end of file +} diff --git a/src/main/java/com/epam/ta/reportportal/model/filter/UserFilterCondition.java b/src/main/java/com/epam/ta/reportportal/model/filter/UserFilterCondition.java index 187915929d..7cf13e08ff 100644 --- a/src/main/java/com/epam/ta/reportportal/model/filter/UserFilterCondition.java +++ b/src/main/java/com/epam/ta/reportportal/model/filter/UserFilterCondition.java @@ -20,7 +20,7 @@ import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; /** * Filter entity domain model object. @@ -131,4 +131,4 @@ public String toString() { sb.append('}'); return sb.toString(); } -} \ No newline at end of file +} diff --git a/src/main/java/com/epam/ta/reportportal/model/filter/UserFilterResource.java b/src/main/java/com/epam/ta/reportportal/model/filter/UserFilterResource.java index 940dfb55d6..c2171f8a15 100644 --- a/src/main/java/com/epam/ta/reportportal/model/filter/UserFilterResource.java +++ b/src/main/java/com/epam/ta/reportportal/model/filter/UserFilterResource.java @@ -20,17 +20,17 @@ import static com.epam.reportportal.model.ValidationConstraints.MIN_COLLECTION_SIZE; import static com.epam.reportportal.model.ValidationConstraints.MIN_NAME_LENGTH; -import com.epam.reportportal.annotations.In; +import com.epam.ta.reportportal.ws.annotations.In; import com.epam.ta.reportportal.ws.reporting.OwnedResource; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; import java.util.List; import java.util.Set; -import javax.validation.Valid; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; /** * JSON Representation of ReportPortal's UserFilter domain object diff --git a/src/main/java/com/epam/ta/reportportal/model/integration/UpdatePluginStateRQ.java b/src/main/java/com/epam/ta/reportportal/model/integration/UpdatePluginStateRQ.java index 3b81382bba..7f5a7266e7 100644 --- a/src/main/java/com/epam/ta/reportportal/model/integration/UpdatePluginStateRQ.java +++ b/src/main/java/com/epam/ta/reportportal/model/integration/UpdatePluginStateRQ.java @@ -18,7 +18,7 @@ import com.fasterxml.jackson.annotation.JsonInclude; import java.io.Serializable; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; /** * @author Ivan Budayeu diff --git a/src/main/java/com/epam/ta/reportportal/model/issue/DefineIssueRQ.java b/src/main/java/com/epam/ta/reportportal/model/issue/DefineIssueRQ.java index 6fa0266ffd..a4196cfe49 100644 --- a/src/main/java/com/epam/ta/reportportal/model/issue/DefineIssueRQ.java +++ b/src/main/java/com/epam/ta/reportportal/model/issue/DefineIssueRQ.java @@ -20,9 +20,9 @@ import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; import java.util.List; -import javax.validation.Valid; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; /** * Request for test items issue types definition (defect block) @@ -53,4 +53,4 @@ public String toString() { sb.append('}'); return sb.toString(); } -} \ No newline at end of file +} diff --git a/src/main/java/com/epam/ta/reportportal/model/issue/IssueDefinition.java b/src/main/java/com/epam/ta/reportportal/model/issue/IssueDefinition.java index cad1f46d81..ef3b5457ef 100644 --- a/src/main/java/com/epam/ta/reportportal/model/issue/IssueDefinition.java +++ b/src/main/java/com/epam/ta/reportportal/model/issue/IssueDefinition.java @@ -22,8 +22,8 @@ import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; -import javax.validation.Valid; -import javax.validation.constraints.NotNull; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; /** * Test item issue with provided it @@ -64,4 +64,4 @@ public void setIssue(Issue issue) { public String toString() { return "IssueDefinition{" + "id=" + id + ", issue=" + issue + '}'; } -} \ No newline at end of file +} diff --git a/src/main/java/com/epam/ta/reportportal/model/item/ExternalIssueRQ.java b/src/main/java/com/epam/ta/reportportal/model/item/ExternalIssueRQ.java index 6672a2ca49..f496be6129 100644 --- a/src/main/java/com/epam/ta/reportportal/model/item/ExternalIssueRQ.java +++ b/src/main/java/com/epam/ta/reportportal/model/item/ExternalIssueRQ.java @@ -19,8 +19,8 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import java.util.List; -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.Size; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.Size; /** * @author Ihar Kahadouski diff --git a/src/main/java/com/epam/ta/reportportal/model/item/LinkExternalIssueRQ.java b/src/main/java/com/epam/ta/reportportal/model/item/LinkExternalIssueRQ.java index 3663be9c81..795029cc10 100644 --- a/src/main/java/com/epam/ta/reportportal/model/item/LinkExternalIssueRQ.java +++ b/src/main/java/com/epam/ta/reportportal/model/item/LinkExternalIssueRQ.java @@ -21,9 +21,9 @@ import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.v3.oas.annotations.media.Schema; import java.util.List; -import javax.validation.Valid; -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.Size; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.Size; /** * Request model for add link to external system issue @@ -53,4 +53,4 @@ public List getIssues() { public String toString() { return "LinkExternalIssueRQ{" + "issues=" + issues + '}'; } -} \ No newline at end of file +} diff --git a/src/main/java/com/epam/ta/reportportal/model/item/UnlinkExternalIssueRQ.java b/src/main/java/com/epam/ta/reportportal/model/item/UnlinkExternalIssueRQ.java index b6037ab9b7..f3424d66e6 100644 --- a/src/main/java/com/epam/ta/reportportal/model/item/UnlinkExternalIssueRQ.java +++ b/src/main/java/com/epam/ta/reportportal/model/item/UnlinkExternalIssueRQ.java @@ -20,9 +20,9 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import java.util.List; -import javax.validation.Valid; -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.Size; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.Size; /** * @author Pavel Bortnik diff --git a/src/main/java/com/epam/ta/reportportal/model/item/UpdateTestItemRQ.java b/src/main/java/com/epam/ta/reportportal/model/item/UpdateTestItemRQ.java index 61cf4adc1e..56bc8548d9 100644 --- a/src/main/java/com/epam/ta/reportportal/model/item/UpdateTestItemRQ.java +++ b/src/main/java/com/epam/ta/reportportal/model/item/UpdateTestItemRQ.java @@ -22,8 +22,8 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import java.util.Set; -import javax.validation.Valid; -import javax.validation.constraints.Size; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Size; /** * @author Dzmitry_Kavalets @@ -65,4 +65,4 @@ public String getStatus() { public void setStatus(String status) { this.status = status; } -} \ No newline at end of file +} diff --git a/src/main/java/com/epam/ta/reportportal/model/launch/AnalyzeLaunchRQ.java b/src/main/java/com/epam/ta/reportportal/model/launch/AnalyzeLaunchRQ.java index 4aa4634cae..f2c72f7827 100644 --- a/src/main/java/com/epam/ta/reportportal/model/launch/AnalyzeLaunchRQ.java +++ b/src/main/java/com/epam/ta/reportportal/model/launch/AnalyzeLaunchRQ.java @@ -16,12 +16,12 @@ package com.epam.ta.reportportal.model.launch; -import com.epam.reportportal.annotations.In; +import com.epam.ta.reportportal.ws.annotations.In; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.v3.oas.annotations.media.Schema; import java.util.List; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; /** * @author Pavel Bortnik diff --git a/src/main/java/com/epam/ta/reportportal/model/launch/LaunchImportRQ.java b/src/main/java/com/epam/ta/reportportal/model/launch/LaunchImportRQ.java index 51acf8e28c..d089fdc0dc 100644 --- a/src/main/java/com/epam/ta/reportportal/model/launch/LaunchImportRQ.java +++ b/src/main/java/com/epam/ta/reportportal/model/launch/LaunchImportRQ.java @@ -27,8 +27,8 @@ import io.swagger.v3.oas.annotations.media.Schema; import java.time.Instant; import java.util.Set; -import javax.validation.Valid; -import javax.validation.constraints.Size; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Size; import lombok.Data; import lombok.NoArgsConstructor; diff --git a/src/main/java/com/epam/ta/reportportal/model/launch/UpdateLaunchRQ.java b/src/main/java/com/epam/ta/reportportal/model/launch/UpdateLaunchRQ.java index a69cadaca9..e66e7521b7 100644 --- a/src/main/java/com/epam/ta/reportportal/model/launch/UpdateLaunchRQ.java +++ b/src/main/java/com/epam/ta/reportportal/model/launch/UpdateLaunchRQ.java @@ -25,8 +25,8 @@ import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.v3.oas.annotations.media.Schema; import java.util.Set; -import javax.validation.Valid; -import javax.validation.constraints.Size; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Size; /** * Domain object for updating launch object. @@ -79,4 +79,4 @@ public String toString() { sb.append('}'); return sb.toString(); } -} \ No newline at end of file +} diff --git a/src/main/java/com/epam/ta/reportportal/model/launch/cluster/CreateClustersRQ.java b/src/main/java/com/epam/ta/reportportal/model/launch/cluster/CreateClustersRQ.java index 3e9a5db893..a9d5e984a4 100644 --- a/src/main/java/com/epam/ta/reportportal/model/launch/cluster/CreateClustersRQ.java +++ b/src/main/java/com/epam/ta/reportportal/model/launch/cluster/CreateClustersRQ.java @@ -18,7 +18,7 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; /** * @author Ivan Budayeu diff --git a/src/main/java/com/epam/ta/reportportal/model/log/GetLogsUnderRq.java b/src/main/java/com/epam/ta/reportportal/model/log/GetLogsUnderRq.java index 8f99ebdcb9..4ac247b0e3 100644 --- a/src/main/java/com/epam/ta/reportportal/model/log/GetLogsUnderRq.java +++ b/src/main/java/com/epam/ta/reportportal/model/log/GetLogsUnderRq.java @@ -3,7 +3,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.v3.oas.annotations.media.Schema; import java.util.List; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; public class GetLogsUnderRq { diff --git a/src/main/java/com/epam/ta/reportportal/model/log/LogResource.java b/src/main/java/com/epam/ta/reportportal/model/log/LogResource.java index 75fe6cf816..42e6516053 100644 --- a/src/main/java/com/epam/ta/reportportal/model/log/LogResource.java +++ b/src/main/java/com/epam/ta/reportportal/model/log/LogResource.java @@ -21,7 +21,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.v3.oas.annotations.media.Schema; import java.time.Instant; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import lombok.Getter; import lombok.Setter; import lombok.ToString; diff --git a/src/main/java/com/epam/ta/reportportal/model/log/SearchLogRq.java b/src/main/java/com/epam/ta/reportportal/model/log/SearchLogRq.java index f043358b10..36fc316f1f 100644 --- a/src/main/java/com/epam/ta/reportportal/model/log/SearchLogRq.java +++ b/src/main/java/com/epam/ta/reportportal/model/log/SearchLogRq.java @@ -16,11 +16,11 @@ package com.epam.ta.reportportal.model.log; -import com.epam.reportportal.annotations.In; +import com.epam.ta.reportportal.ws.annotations.In; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.v3.oas.annotations.media.Schema; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; /** * @author Ihar Kahadouski diff --git a/src/main/java/com/epam/ta/reportportal/model/notification/EmailNotificationRQ.java b/src/main/java/com/epam/ta/reportportal/model/notification/EmailNotificationRQ.java index 3c7944ff84..cff001c6df 100644 --- a/src/main/java/com/epam/ta/reportportal/model/notification/EmailNotificationRQ.java +++ b/src/main/java/com/epam/ta/reportportal/model/notification/EmailNotificationRQ.java @@ -18,7 +18,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import java.util.Map; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; /** * @author Andrei Piankouski diff --git a/src/main/java/com/epam/ta/reportportal/model/project/AssignUsersRQ.java b/src/main/java/com/epam/ta/reportportal/model/project/AssignUsersRQ.java index 7bcad4688e..21fbf4f07e 100644 --- a/src/main/java/com/epam/ta/reportportal/model/project/AssignUsersRQ.java +++ b/src/main/java/com/epam/ta/reportportal/model/project/AssignUsersRQ.java @@ -20,7 +20,7 @@ import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; import java.util.Map; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; /** * Assign users from project request model @@ -49,4 +49,4 @@ public String toString() { sb.append('}'); return sb.toString(); } -} \ No newline at end of file +} diff --git a/src/main/java/com/epam/ta/reportportal/model/project/CreateProjectRQ.java b/src/main/java/com/epam/ta/reportportal/model/project/CreateProjectRQ.java index 963d23e538..f77116a3e8 100644 --- a/src/main/java/com/epam/ta/reportportal/model/project/CreateProjectRQ.java +++ b/src/main/java/com/epam/ta/reportportal/model/project/CreateProjectRQ.java @@ -18,16 +18,16 @@ import static com.epam.reportportal.model.ValidationConstraints.PROJECT_NAME_REGEXP; -import com.epam.reportportal.annotations.In; +import com.epam.ta.reportportal.ws.annotations.In; import com.epam.reportportal.model.ValidationConstraints; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.Pattern; -import javax.validation.constraints.Size; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.Size; /** * Create project request initial model diff --git a/src/main/java/com/epam/ta/reportportal/model/project/DeleteProjectRQ.java b/src/main/java/com/epam/ta/reportportal/model/project/DeleteProjectRQ.java index 082df481ca..abbc5605f0 100644 --- a/src/main/java/com/epam/ta/reportportal/model/project/DeleteProjectRQ.java +++ b/src/main/java/com/epam/ta/reportportal/model/project/DeleteProjectRQ.java @@ -23,9 +23,9 @@ import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.Pattern; -import javax.validation.constraints.Size; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.Size; /** * @author Ivan Budayeu diff --git a/src/main/java/com/epam/ta/reportportal/model/project/ProjectInfoResource.java b/src/main/java/com/epam/ta/reportportal/model/project/ProjectInfoResource.java index f372b045c2..f5bf863652 100644 --- a/src/main/java/com/epam/ta/reportportal/model/project/ProjectInfoResource.java +++ b/src/main/java/com/epam/ta/reportportal/model/project/ProjectInfoResource.java @@ -21,8 +21,8 @@ import com.fasterxml.jackson.annotation.JsonView; import java.time.Instant; import java.util.List; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; diff --git a/src/main/java/com/epam/ta/reportportal/model/project/ProjectResource.java b/src/main/java/com/epam/ta/reportportal/model/project/ProjectResource.java index af1cb3dafa..4967140e19 100644 --- a/src/main/java/com/epam/ta/reportportal/model/project/ProjectResource.java +++ b/src/main/java/com/epam/ta/reportportal/model/project/ProjectResource.java @@ -21,7 +21,7 @@ import java.time.Instant; import java.util.List; import java.util.UUID; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; diff --git a/src/main/java/com/epam/ta/reportportal/model/project/UnassignUsersRQ.java b/src/main/java/com/epam/ta/reportportal/model/project/UnassignUsersRQ.java index c15bc1c33f..d6e56f7637 100644 --- a/src/main/java/com/epam/ta/reportportal/model/project/UnassignUsersRQ.java +++ b/src/main/java/com/epam/ta/reportportal/model/project/UnassignUsersRQ.java @@ -22,7 +22,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; import java.util.List; -import javax.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotEmpty; /** * Un-assign users request template @@ -52,4 +52,4 @@ public String toString() { sb.append('}'); return sb.toString(); } -} \ No newline at end of file +} diff --git a/src/main/java/com/epam/ta/reportportal/model/project/UpdateProjectRQ.java b/src/main/java/com/epam/ta/reportportal/model/project/UpdateProjectRQ.java index 2bc9dc8974..4d0b3312ab 100644 --- a/src/main/java/com/epam/ta/reportportal/model/project/UpdateProjectRQ.java +++ b/src/main/java/com/epam/ta/reportportal/model/project/UpdateProjectRQ.java @@ -21,7 +21,7 @@ import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; import java.util.Map; -import javax.validation.Valid; +import jakarta.validation.Valid; /** * Update project request model @@ -68,4 +68,4 @@ public String toString() { sb.append('}'); return sb.toString(); } -} \ No newline at end of file +} diff --git a/src/main/java/com/epam/ta/reportportal/model/project/config/CreateIssueSubTypeRQ.java b/src/main/java/com/epam/ta/reportportal/model/project/config/CreateIssueSubTypeRQ.java index ee02fb9a77..bbefe7e359 100644 --- a/src/main/java/com/epam/ta/reportportal/model/project/config/CreateIssueSubTypeRQ.java +++ b/src/main/java/com/epam/ta/reportportal/model/project/config/CreateIssueSubTypeRQ.java @@ -24,9 +24,9 @@ import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.Pattern; -import javax.validation.constraints.Size; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.Size; /** * Request model for new issue sub type for specified project.
diff --git a/src/main/java/com/epam/ta/reportportal/model/project/config/ProjectConfigurationUpdate.java b/src/main/java/com/epam/ta/reportportal/model/project/config/ProjectConfigurationUpdate.java index 7a688f4694..06898fb489 100644 --- a/src/main/java/com/epam/ta/reportportal/model/project/config/ProjectConfigurationUpdate.java +++ b/src/main/java/com/epam/ta/reportportal/model/project/config/ProjectConfigurationUpdate.java @@ -21,7 +21,7 @@ import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; import java.util.Map; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; /** * Project configuration model diff --git a/src/main/java/com/epam/ta/reportportal/model/project/config/UpdateIssueSubTypeRQ.java b/src/main/java/com/epam/ta/reportportal/model/project/config/UpdateIssueSubTypeRQ.java index 7e5b0f01f2..0818ce6b36 100644 --- a/src/main/java/com/epam/ta/reportportal/model/project/config/UpdateIssueSubTypeRQ.java +++ b/src/main/java/com/epam/ta/reportportal/model/project/config/UpdateIssueSubTypeRQ.java @@ -38,8 +38,8 @@ import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; import java.util.List; -import javax.validation.Valid; -import javax.validation.constraints.NotEmpty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotEmpty; /** * Request model for existing issue sub type update for specified project.
diff --git a/src/main/java/com/epam/ta/reportportal/model/project/config/UpdateOneIssueSubTypeRQ.java b/src/main/java/com/epam/ta/reportportal/model/project/config/UpdateOneIssueSubTypeRQ.java index 86cb8e0045..d5f25b89e6 100644 --- a/src/main/java/com/epam/ta/reportportal/model/project/config/UpdateOneIssueSubTypeRQ.java +++ b/src/main/java/com/epam/ta/reportportal/model/project/config/UpdateOneIssueSubTypeRQ.java @@ -23,9 +23,9 @@ import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.Pattern; -import javax.validation.constraints.Size; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.Size; /** * One settings sub-type update request representation @@ -105,4 +105,4 @@ public void setColor(String color) { public String getColor() { return color; } -} \ No newline at end of file +} diff --git a/src/main/java/com/epam/ta/reportportal/model/project/config/pattern/CreatePatternTemplateRQ.java b/src/main/java/com/epam/ta/reportportal/model/project/config/pattern/CreatePatternTemplateRQ.java index 6df9e92064..110b166aca 100644 --- a/src/main/java/com/epam/ta/reportportal/model/project/config/pattern/CreatePatternTemplateRQ.java +++ b/src/main/java/com/epam/ta/reportportal/model/project/config/pattern/CreatePatternTemplateRQ.java @@ -21,9 +21,9 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; /** * @author Ivan Budayeu diff --git a/src/main/java/com/epam/ta/reportportal/model/project/config/pattern/UpdatePatternTemplateRQ.java b/src/main/java/com/epam/ta/reportportal/model/project/config/pattern/UpdatePatternTemplateRQ.java index b99f54894e..2c25ee5087 100644 --- a/src/main/java/com/epam/ta/reportportal/model/project/config/pattern/UpdatePatternTemplateRQ.java +++ b/src/main/java/com/epam/ta/reportportal/model/project/config/pattern/UpdatePatternTemplateRQ.java @@ -21,9 +21,9 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; /** * @author Ivan Budayeu diff --git a/src/main/java/com/epam/ta/reportportal/model/project/email/ProjectNotificationConfigDTO.java b/src/main/java/com/epam/ta/reportportal/model/project/email/ProjectNotificationConfigDTO.java index c7dec9d606..1abe314b1e 100644 --- a/src/main/java/com/epam/ta/reportportal/model/project/email/ProjectNotificationConfigDTO.java +++ b/src/main/java/com/epam/ta/reportportal/model/project/email/ProjectNotificationConfigDTO.java @@ -21,7 +21,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import java.io.Serializable; import java.util.List; -import javax.validation.Valid; +import jakarta.validation.Valid; /** * Project notifications configuration object @@ -71,4 +71,4 @@ public String toString() { return "ProjectNotificationConfigDTO{" + "enabled=" + enabled + ", senderCases=" + senderCases + '}'; } -} \ No newline at end of file +} diff --git a/src/main/java/com/epam/ta/reportportal/model/project/email/SenderCaseDTO.java b/src/main/java/com/epam/ta/reportportal/model/project/email/SenderCaseDTO.java index e20a533f22..c888b57caa 100644 --- a/src/main/java/com/epam/ta/reportportal/model/project/email/SenderCaseDTO.java +++ b/src/main/java/com/epam/ta/reportportal/model/project/email/SenderCaseDTO.java @@ -16,7 +16,7 @@ package com.epam.ta.reportportal.model.project.email; -import com.epam.reportportal.annotations.In; +import com.epam.ta.reportportal.ws.annotations.In; import com.epam.reportportal.annotations.NotBlankStringCollection; import com.epam.ta.reportportal.ws.reporting.ItemAttributeResource; import com.fasterxml.jackson.annotation.JsonInclude; @@ -28,9 +28,9 @@ import java.util.Map; import java.util.Objects; import java.util.Set; -import javax.validation.Valid; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotEmpty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotEmpty; /** * Cases object for notifications sending declarations diff --git a/src/main/java/com/epam/ta/reportportal/model/role/SaveRoleRQ.java b/src/main/java/com/epam/ta/reportportal/model/role/SaveRoleRQ.java index 6d8b297771..9b531a635a 100644 --- a/src/main/java/com/epam/ta/reportportal/model/role/SaveRoleRQ.java +++ b/src/main/java/com/epam/ta/reportportal/model/role/SaveRoleRQ.java @@ -19,7 +19,7 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; /** * @@ -62,4 +62,4 @@ public String toString() { return sb.toString(); } -} \ No newline at end of file +} diff --git a/src/main/java/com/epam/ta/reportportal/model/settings/AnalyticsResource.java b/src/main/java/com/epam/ta/reportportal/model/settings/AnalyticsResource.java index 27877551b2..dead86fa57 100644 --- a/src/main/java/com/epam/ta/reportportal/model/settings/AnalyticsResource.java +++ b/src/main/java/com/epam/ta/reportportal/model/settings/AnalyticsResource.java @@ -19,7 +19,7 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import java.io.Serializable; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; @JsonInclude(Include.NON_NULL) public class AnalyticsResource implements Serializable { diff --git a/src/main/java/com/epam/ta/reportportal/model/settings/ServerEmailResource.java b/src/main/java/com/epam/ta/reportportal/model/settings/ServerEmailResource.java index d3a557dce5..97613a9f8b 100644 --- a/src/main/java/com/epam/ta/reportportal/model/settings/ServerEmailResource.java +++ b/src/main/java/com/epam/ta/reportportal/model/settings/ServerEmailResource.java @@ -19,7 +19,7 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import java.io.Serializable; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; /** * Configurable email setting for project object diff --git a/src/main/java/com/epam/ta/reportportal/model/user/ChangePasswordRQ.java b/src/main/java/com/epam/ta/reportportal/model/user/ChangePasswordRQ.java index fd0dc8f32d..47dd4f8743 100644 --- a/src/main/java/com/epam/ta/reportportal/model/user/ChangePasswordRQ.java +++ b/src/main/java/com/epam/ta/reportportal/model/user/ChangePasswordRQ.java @@ -18,8 +18,8 @@ import com.epam.reportportal.model.ValidationConstraints; import com.fasterxml.jackson.annotation.JsonInclude; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.Size; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; /** * @author Dzmitry_Kavalets @@ -85,4 +85,4 @@ public String toString() { sb.append('}'); return sb.toString(); } -} \ No newline at end of file +} diff --git a/src/main/java/com/epam/ta/reportportal/model/user/CreateUserRQ.java b/src/main/java/com/epam/ta/reportportal/model/user/CreateUserRQ.java index f32f39deef..9a2cedb1da 100644 --- a/src/main/java/com/epam/ta/reportportal/model/user/CreateUserRQ.java +++ b/src/main/java/com/epam/ta/reportportal/model/user/CreateUserRQ.java @@ -16,13 +16,13 @@ package com.epam.ta.reportportal.model.user; -import com.epam.reportportal.annotations.In; +import com.epam.ta.reportportal.ws.annotations.In; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; import lombok.Data; /** @@ -50,4 +50,4 @@ public class CreateUserRQ { @Schema(requiredMode = RequiredMode.REQUIRED) private String defaultProject; -} \ No newline at end of file +} diff --git a/src/main/java/com/epam/ta/reportportal/model/user/CreateUserRQConfirm.java b/src/main/java/com/epam/ta/reportportal/model/user/CreateUserRQConfirm.java index f96c5c7aea..466fb1076d 100644 --- a/src/main/java/com/epam/ta/reportportal/model/user/CreateUserRQConfirm.java +++ b/src/main/java/com/epam/ta/reportportal/model/user/CreateUserRQConfirm.java @@ -22,9 +22,9 @@ import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.Pattern; -import javax.validation.constraints.Size; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.Size; import lombok.Data; /** @@ -60,4 +60,4 @@ public class CreateUserRQConfirm { @JsonProperty(value = "email", required = true) @Schema(requiredMode = RequiredMode.REQUIRED) private String email; -} \ No newline at end of file +} diff --git a/src/main/java/com/epam/ta/reportportal/model/user/CreateUserRQFull.java b/src/main/java/com/epam/ta/reportportal/model/user/CreateUserRQFull.java index a71a9c9afc..c6154f7062 100644 --- a/src/main/java/com/epam/ta/reportportal/model/user/CreateUserRQFull.java +++ b/src/main/java/com/epam/ta/reportportal/model/user/CreateUserRQFull.java @@ -16,18 +16,17 @@ package com.epam.ta.reportportal.model.user; -import com.epam.reportportal.annotations.In; import com.epam.reportportal.model.ValidationConstraints; -import com.epam.ta.reportportal.entity.user.UserType; +import com.epam.ta.reportportal.ws.annotations.In; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Pattern; -import javax.validation.constraints.Size; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.Size; import lombok.Data; /** @@ -90,4 +89,4 @@ public class CreateUserRQFull { @JsonProperty(value = "defaultProject") @Schema(requiredMode = RequiredMode.NOT_REQUIRED) private String defaultProject; -} \ No newline at end of file +} diff --git a/src/main/java/com/epam/ta/reportportal/model/user/EditUserRQ.java b/src/main/java/com/epam/ta/reportportal/model/user/EditUserRQ.java index 88235c10dc..66f557cf9c 100644 --- a/src/main/java/com/epam/ta/reportportal/model/user/EditUserRQ.java +++ b/src/main/java/com/epam/ta/reportportal/model/user/EditUserRQ.java @@ -16,17 +16,16 @@ package com.epam.ta.reportportal.model.user; -import com.epam.reportportal.annotations.In; import com.epam.reportportal.annotations.NotBlankString; import com.epam.reportportal.model.ValidationConstraints; -import com.epam.ta.reportportal.entity.user.UserType; +import com.epam.ta.reportportal.ws.annotations.In; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; -import javax.validation.constraints.Pattern; -import javax.validation.constraints.Size; +import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.Size; import lombok.Data; /** @@ -65,4 +64,4 @@ public class EditUserRQ { @Schema(requiredMode = RequiredMode.REQUIRED, example = "string") private String fullName; -} \ No newline at end of file +} diff --git a/src/main/java/com/epam/ta/reportportal/model/user/ResetPasswordRQ.java b/src/main/java/com/epam/ta/reportportal/model/user/ResetPasswordRQ.java index 8e5c97b50d..2fce2fc02d 100644 --- a/src/main/java/com/epam/ta/reportportal/model/user/ResetPasswordRQ.java +++ b/src/main/java/com/epam/ta/reportportal/model/user/ResetPasswordRQ.java @@ -21,8 +21,8 @@ import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.Size; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; /** * @author Dzmitry_Kavalets @@ -90,4 +90,4 @@ public String toString() { sb.append('}'); return sb.toString(); } -} \ No newline at end of file +} diff --git a/src/main/java/com/epam/ta/reportportal/model/user/RestorePasswordRQ.java b/src/main/java/com/epam/ta/reportportal/model/user/RestorePasswordRQ.java index 1b6dca8689..eefdc43c5e 100644 --- a/src/main/java/com/epam/ta/reportportal/model/user/RestorePasswordRQ.java +++ b/src/main/java/com/epam/ta/reportportal/model/user/RestorePasswordRQ.java @@ -20,11 +20,15 @@ import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; +import lombok.Getter; +import lombok.Setter; /** * @author Dzmitry_Kavalets */ +@Setter +@Getter @JsonInclude(JsonInclude.Include.NON_NULL) public class RestorePasswordRQ { @@ -33,15 +37,7 @@ public class RestorePasswordRQ { @Schema(requiredMode = RequiredMode.REQUIRED) private String email; - public String getEmail() { - return email; - } - - public void setEmail(String email) { - this.email = email; - } - - @Override + @Override public boolean equals(Object o) { if (this == o) { return true; @@ -68,4 +64,4 @@ public String toString() { sb.append('}'); return sb.toString(); } -} \ No newline at end of file +} diff --git a/src/main/java/com/epam/ta/reportportal/model/user/UserResource.java b/src/main/java/com/epam/ta/reportportal/model/user/UserResource.java index a9a054b2ed..7aedfcf303 100644 --- a/src/main/java/com/epam/ta/reportportal/model/user/UserResource.java +++ b/src/main/java/com/epam/ta/reportportal/model/user/UserResource.java @@ -21,7 +21,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import java.util.Map; import java.util.UUID; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import lombok.Data; /** diff --git a/src/main/java/com/epam/ta/reportportal/model/validation/NotBlankWithSizeValidator.java b/src/main/java/com/epam/ta/reportportal/model/validation/NotBlankWithSizeValidator.java index e1ee85f9eb..cc0df899ea 100644 --- a/src/main/java/com/epam/ta/reportportal/model/validation/NotBlankWithSizeValidator.java +++ b/src/main/java/com/epam/ta/reportportal/model/validation/NotBlankWithSizeValidator.java @@ -16,9 +16,9 @@ package com.epam.ta.reportportal.model.validation; -import com.epam.reportportal.annotations.NotBlankWithSize; -import javax.validation.ConstraintValidator; -import javax.validation.ConstraintValidatorContext; +import com.epam.ta.reportportal.ws.annotations.NotBlankWithSize; +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; import org.apache.commons.lang3.StringUtils; /** diff --git a/src/main/java/com/epam/ta/reportportal/model/widget/ContentParameters.java b/src/main/java/com/epam/ta/reportportal/model/widget/ContentParameters.java index 7bc16856c5..f0e3d37be1 100644 --- a/src/main/java/com/epam/ta/reportportal/model/widget/ContentParameters.java +++ b/src/main/java/com/epam/ta/reportportal/model/widget/ContentParameters.java @@ -19,16 +19,10 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; - -import javax.validation.constraints.Max; -import javax.validation.constraints.Min; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import java.util.List; import java.util.Map; -import static com.epam.reportportal.model.ValidationConstraints.MAX_WIDGET_LIMIT; -import static com.epam.reportportal.model.ValidationConstraints.MIN_WIDGET_LIMIT; - /** * Part of widget domain object. Describe chart parameters * @@ -71,4 +65,4 @@ public Map getWidgetOptions() { public void setWidgetOptions(Map widgetOptions) { this.widgetOptions = widgetOptions; } -} \ No newline at end of file +} diff --git a/src/main/java/com/epam/ta/reportportal/model/widget/WidgetPreviewRQ.java b/src/main/java/com/epam/ta/reportportal/model/widget/WidgetPreviewRQ.java index 6b85a153c8..8a756e87ad 100644 --- a/src/main/java/com/epam/ta/reportportal/model/widget/WidgetPreviewRQ.java +++ b/src/main/java/com/epam/ta/reportportal/model/widget/WidgetPreviewRQ.java @@ -16,14 +16,14 @@ package com.epam.ta.reportportal.model.widget; -import com.epam.reportportal.annotations.In; +import com.epam.ta.reportportal.ws.annotations.In; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.v3.oas.annotations.media.Schema; import java.util.List; -import javax.validation.Valid; -import javax.validation.constraints.NotNull; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; /** * Model object for getting widget preview content diff --git a/src/main/java/com/epam/ta/reportportal/model/widget/WidgetRQ.java b/src/main/java/com/epam/ta/reportportal/model/widget/WidgetRQ.java index 1df206b95d..7269771cf0 100644 --- a/src/main/java/com/epam/ta/reportportal/model/widget/WidgetRQ.java +++ b/src/main/java/com/epam/ta/reportportal/model/widget/WidgetRQ.java @@ -18,16 +18,18 @@ import com.epam.ta.reportportal.model.BaseEntityRQ; import com.epam.ta.reportportal.core.events.annotations.WidgetLimitRange; -import com.epam.reportportal.annotations.In; -import com.epam.reportportal.annotations.NotBlankWithSize; +import com.epam.ta.reportportal.ws.annotations.In; +import com.epam.ta.reportportal.ws.annotations.NotBlankWithSize; import com.epam.reportportal.model.ValidationConstraints; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.v3.oas.annotations.media.Schema; import java.util.List; -import javax.validation.Valid; -import javax.validation.constraints.NotNull; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import lombok.Getter; +import lombok.Setter; /** * Domain model object for creating and updating widget @@ -39,6 +41,8 @@ @JsonInclude(Include.NON_NULL) public class WidgetRQ extends BaseEntityRQ { + @Setter + @Getter @NotBlankWithSize(min = ValidationConstraints.MIN_NAME_LENGTH, max = ValidationConstraints.MAX_WIDGET_NAME_LENGTH) @JsonProperty(value = "name", required = true) private String name; @@ -58,21 +62,17 @@ public class WidgetRQ extends BaseEntityRQ { + " productStatus, mostTimeConsuming, cumulative, topPatternTemplates, componentHealthCheck, componentHealthCheckTable") private String widgetType; + @Setter + @Getter @Valid @JsonProperty(value = "contentParameters") private ContentParameters contentParameters; + @Setter + @Getter @JsonProperty(value = "filterIds") private List filterIds; - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - @NotNull public String getWidgetType() { return widgetType; @@ -82,25 +82,9 @@ public void setWidgetType(@NotNull String widgetType) { this.widgetType = widgetType; } - public ContentParameters getContentParameters() { - return contentParameters; - } - - public void setContentParameters(ContentParameters contentParameters) { - this.contentParameters = contentParameters; - } - - public List getFilterIds() { - return filterIds; - } - - public void setFilterIds(List filterIds) { - this.filterIds = filterIds; - } - @Override public String toString() { return "WidgetRQ{" + "name='" + name + '\'' + ", widgetType='" + widgetType + '\'' + ", contentParameters=" + contentParameters + ", filterIds=" + filterIds + '}'; } -} \ No newline at end of file +} diff --git a/src/main/java/com/epam/ta/reportportal/model/widget/WidgetResource.java b/src/main/java/com/epam/ta/reportportal/model/widget/WidgetResource.java index a0a826af19..b229ec70bd 100644 --- a/src/main/java/com/epam/ta/reportportal/model/widget/WidgetResource.java +++ b/src/main/java/com/epam/ta/reportportal/model/widget/WidgetResource.java @@ -23,10 +23,10 @@ import io.swagger.v3.oas.annotations.media.Schema; import java.util.List; import java.util.Map; -import javax.validation.Valid; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; /** * @author Dzmitry_Kavalets @@ -117,4 +117,4 @@ public String toString() { + widgetType + '\'' + ", contentParameters=" + contentParameters + ", appliedFilters=" + appliedFilters + ", content=" + content + '}'; } -} \ No newline at end of file +} diff --git a/src/main/java/com/epam/ta/reportportal/plugin/PluginStartUpService.java b/src/main/java/com/epam/ta/reportportal/plugin/PluginStartUpService.java index 38dad5ffc2..dadb88266d 100644 --- a/src/main/java/com/epam/ta/reportportal/plugin/PluginStartUpService.java +++ b/src/main/java/com/epam/ta/reportportal/plugin/PluginStartUpService.java @@ -23,7 +23,7 @@ import java.nio.file.Path; import java.util.Collections; import java.util.List; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.pf4j.PluginManager; @@ -79,4 +79,4 @@ private List getDefaultPluginRepositories() { } return Collections.emptyList(); } -} \ No newline at end of file +} diff --git a/src/main/java/com/epam/ta/reportportal/reporting/async/controller/LaunchAsyncController.java b/src/main/java/com/epam/ta/reportportal/reporting/async/controller/LaunchAsyncController.java index edd3eea871..8309c6b35a 100644 --- a/src/main/java/com/epam/ta/reportportal/reporting/async/controller/LaunchAsyncController.java +++ b/src/main/java/com/epam/ta/reportportal/reporting/async/controller/LaunchAsyncController.java @@ -37,7 +37,7 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.security.access.prepost.PreAuthorize; diff --git a/src/main/java/com/epam/ta/reportportal/reporting/async/controller/LogAsyncController.java b/src/main/java/com/epam/ta/reportportal/reporting/async/controller/LogAsyncController.java index d398028b59..6c1b3bccbe 100644 --- a/src/main/java/com/epam/ta/reportportal/reporting/async/controller/LogAsyncController.java +++ b/src/main/java/com/epam/ta/reportportal/reporting/async/controller/LogAsyncController.java @@ -39,8 +39,8 @@ import io.swagger.v3.oas.annotations.Hidden; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; -import javax.servlet.http.HttpServletRequest; -import javax.validation.Validator; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.validation.Validator; import org.apache.commons.collections4.MultiValuedMap; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.exception.ExceptionUtils; diff --git a/src/main/java/com/epam/ta/reportportal/reporting/async/handler/LogMessageHandler.java b/src/main/java/com/epam/ta/reportportal/reporting/async/handler/LogMessageHandler.java index 032aaece95..53caffbc72 100644 --- a/src/main/java/com/epam/ta/reportportal/reporting/async/handler/LogMessageHandler.java +++ b/src/main/java/com/epam/ta/reportportal/reporting/async/handler/LogMessageHandler.java @@ -46,8 +46,8 @@ import java.util.Objects; import java.util.Optional; import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.springframework.amqp.core.Message; import org.springframework.stereotype.Service; @@ -57,8 +57,7 @@ @Service public class LogMessageHandler implements ReportingMessageHandler { - private static final Logger LOGGER = LoggerFactory.getLogger( - MessageRetriever.class); + private static final Logger LOGGER = LogManager.getLogger(LogMessageHandler.class); private final LaunchRepository launchRepository; private final TestItemRepository testItemRepository; private final LogRepository logRepository; diff --git a/src/main/java/com/epam/ta/reportportal/reporting/async/message/MessageRetriever.java b/src/main/java/com/epam/ta/reportportal/reporting/async/message/MessageRetriever.java index e5b1a1887e..7dccf0042e 100644 --- a/src/main/java/com/epam/ta/reportportal/reporting/async/message/MessageRetriever.java +++ b/src/main/java/com/epam/ta/reportportal/reporting/async/message/MessageRetriever.java @@ -21,9 +21,9 @@ import java.nio.charset.StandardCharsets; import java.util.Optional; import java.util.Set; -import javax.validation.ConstraintViolation; -import javax.validation.ConstraintViolationException; -import javax.validation.Validator; +import jakarta.validation.ConstraintViolation; +import jakarta.validation.ConstraintViolationException; +import jakarta.validation.Validator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.amqp.core.Message; diff --git a/src/main/java/com/epam/ta/reportportal/reporting/async/producer/LogProducer.java b/src/main/java/com/epam/ta/reportportal/reporting/async/producer/LogProducer.java index 823dc6a873..7bbf5c9afe 100644 --- a/src/main/java/com/epam/ta/reportportal/reporting/async/producer/LogProducer.java +++ b/src/main/java/com/epam/ta/reportportal/reporting/async/producer/LogProducer.java @@ -34,9 +34,9 @@ import java.util.Map; import java.util.UUID; import java.util.concurrent.CompletableFuture; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import javax.inject.Provider; +import jakarta.annotation.Nonnull; +import jakarta.annotation.Nullable; +import jakarta.inject.Provider; import org.springframework.amqp.core.AmqpTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; diff --git a/src/main/java/com/epam/ta/reportportal/reporting/event/EventBasedReporting.java b/src/main/java/com/epam/ta/reportportal/reporting/event/EventBasedReporting.java index 94a405161b..6e5a205256 100644 --- a/src/main/java/com/epam/ta/reportportal/reporting/event/EventBasedReporting.java +++ b/src/main/java/com/epam/ta/reportportal/reporting/event/EventBasedReporting.java @@ -31,7 +31,7 @@ import com.epam.ta.reportportal.core.log.CreateLogHandler; import com.epam.ta.reportportal.util.ProjectExtractor; import java.util.Optional; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.context.event.EventListener; @@ -117,8 +117,8 @@ public void handleLogCreation(SaveLogRqEvent saveLogRqEvent) { private Optional extractCurrentHttpRequest() { RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); - if (requestAttributes instanceof ServletRequestAttributes) { - return Optional.of(((ServletRequestAttributes) requestAttributes).getRequest()); + if (requestAttributes instanceof ServletRequestAttributes servletRequestAttributes) { + return Optional.of(servletRequestAttributes.getRequest()); } log.debug("Not called in the context of an HTTP request"); return Optional.empty(); diff --git a/src/main/java/com/epam/ta/reportportal/util/BinaryDataResponseWriter.java b/src/main/java/com/epam/ta/reportportal/util/BinaryDataResponseWriter.java index 296106cefd..93db090626 100644 --- a/src/main/java/com/epam/ta/reportportal/util/BinaryDataResponseWriter.java +++ b/src/main/java/com/epam/ta/reportportal/util/BinaryDataResponseWriter.java @@ -21,7 +21,7 @@ import com.epam.reportportal.rules.exception.ErrorType; import java.io.IOException; import java.io.InputStream; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletResponse; import org.apache.commons.io.IOUtils; /** diff --git a/src/main/java/com/epam/ta/reportportal/util/ControllerUtils.java b/src/main/java/com/epam/ta/reportportal/util/ControllerUtils.java index ceb967b73d..2aabf8bc0a 100644 --- a/src/main/java/com/epam/ta/reportportal/util/ControllerUtils.java +++ b/src/main/java/com/epam/ta/reportportal/util/ControllerUtils.java @@ -22,10 +22,10 @@ import java.util.Iterator; import java.util.List; import java.util.Set; -import javax.servlet.http.HttpServletRequest; -import javax.validation.ConstraintViolation; -import javax.validation.Path; -import javax.validation.Validator; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.validation.ConstraintViolation; +import jakarta.validation.Path; +import jakarta.validation.Validator; import org.apache.commons.collections4.MultiValuedMap; import org.apache.commons.collections4.multimap.ArrayListValuedHashMap; import org.springframework.util.MultiValueMap; @@ -99,8 +99,8 @@ public static void validateSaveRQ(Validator validator, SaveLogRQ saveLogRQ) { public static MultiValuedMap getUploadedFiles(HttpServletRequest request) { MultiValuedMap uploadedFiles = new ArrayListValuedHashMap<>(); - if (request instanceof MultipartHttpServletRequest) { - MultiValueMap multiFileMap = (((MultipartHttpServletRequest) request)).getMultiFileMap(); + if (request instanceof MultipartHttpServletRequest multipartRequest) { + MultiValueMap multiFileMap = multipartRequest.getMultiFileMap(); for (List multipartFiles : multiFileMap.values()) { for (MultipartFile file : multipartFiles) { uploadedFiles.put(file.getOriginalFilename(), file); diff --git a/src/main/java/com/epam/ta/reportportal/util/MultipartFileUtils.java b/src/main/java/com/epam/ta/reportportal/util/MultipartFileUtils.java index 7ae233d631..5c030cd0ad 100644 --- a/src/main/java/com/epam/ta/reportportal/util/MultipartFileUtils.java +++ b/src/main/java/com/epam/ta/reportportal/util/MultipartFileUtils.java @@ -16,13 +16,14 @@ package com.epam.ta.reportportal.util; +import java.io.FileInputStream; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.disk.DiskFileItem; import org.apache.commons.io.IOUtils; import org.apache.tika.Tika; import org.springframework.core.io.ClassPathResource; -import org.springframework.web.multipart.commons.CommonsMultipartFile; - +import org.springframework.mock.web.MockMultipartFile; +import org.springframework.web.multipart.MultipartFile; import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; @@ -37,8 +38,7 @@ public class MultipartFileUtils { private MultipartFileUtils() { //static only } - - public static CommonsMultipartFile getMultipartFile(String path) throws IOException { + public static MultipartFile getMultipartFile(String path) throws IOException { ClassPathResource resource = new ClassPathResource(path); //TODO investigate stream closing requirement try (InputStream bufferedInputStream = new BufferedInputStream(resource.getInputStream())) { @@ -50,7 +50,7 @@ public static CommonsMultipartFile getMultipartFile(String path) throws IOExcept null ); IOUtils.copy(bufferedInputStream, fileItem.getOutputStream()); - return new CommonsMultipartFile(fileItem); + return new MockMultipartFile(resource.getFilename(), resource.getFilename(), tika.detect(bufferedInputStream), resource.getInputStream().readAllBytes()); } } } diff --git a/src/main/java/com/epam/ta/reportportal/util/email/EmailService.java b/src/main/java/com/epam/ta/reportportal/util/email/EmailService.java index c2a194c399..1944c3300e 100644 --- a/src/main/java/com/epam/ta/reportportal/util/email/EmailService.java +++ b/src/main/java/com/epam/ta/reportportal/util/email/EmailService.java @@ -51,9 +51,9 @@ import java.util.Set; import java.util.regex.Pattern; import java.util.stream.Collectors; -import javax.mail.MessagingException; -import javax.mail.internet.AddressException; -import javax.mail.internet.InternetAddress; +import jakarta.mail.MessagingException; +import jakarta.mail.internet.AddressException; +import jakarta.mail.internet.InternetAddress; import lombok.Setter; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; diff --git a/src/main/java/com/epam/ta/reportportal/ws/controller/ActivityEventController.java b/src/main/java/com/epam/ta/reportportal/ws/controller/ActivityEventController.java index 276bb655fd..4b7d3424a5 100644 --- a/src/main/java/com/epam/ta/reportportal/ws/controller/ActivityEventController.java +++ b/src/main/java/com/epam/ta/reportportal/ws/controller/ActivityEventController.java @@ -33,8 +33,8 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import java.util.List; -import javax.validation.constraints.Max; -import javax.validation.constraints.Min; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; diff --git a/src/main/java/com/epam/ta/reportportal/ws/controller/FileStorageController.java b/src/main/java/com/epam/ta/reportportal/ws/controller/FileStorageController.java index 66c27697ed..788af1f401 100644 --- a/src/main/java/com/epam/ta/reportportal/ws/controller/FileStorageController.java +++ b/src/main/java/com/epam/ta/reportportal/ws/controller/FileStorageController.java @@ -34,7 +34,7 @@ import io.swagger.v3.oas.annotations.tags.Tag; import java.io.IOException; import java.io.InputStream; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletResponse; import org.apache.commons.io.IOUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; diff --git a/src/main/java/com/epam/ta/reportportal/ws/controller/IntegrationController.java b/src/main/java/com/epam/ta/reportportal/ws/controller/IntegrationController.java index b88fa0c4ed..c4bd590481 100644 --- a/src/main/java/com/epam/ta/reportportal/ws/controller/IntegrationController.java +++ b/src/main/java/com/epam/ta/reportportal/ws/controller/IntegrationController.java @@ -36,7 +36,7 @@ import io.swagger.v3.oas.annotations.tags.Tag; import java.util.List; import java.util.Map; -import javax.validation.Valid; +import jakarta.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.security.access.prepost.PreAuthorize; diff --git a/src/main/java/com/epam/ta/reportportal/ws/controller/LaunchController.java b/src/main/java/com/epam/ta/reportportal/ws/controller/LaunchController.java index 448e9fdfd1..be6d23c0d6 100644 --- a/src/main/java/com/epam/ta/reportportal/ws/controller/LaunchController.java +++ b/src/main/java/com/epam/ta/reportportal/ws/controller/LaunchController.java @@ -65,9 +65,9 @@ import java.io.OutputStream; import java.util.List; import java.util.Map; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.validation.Valid; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.data.domain.Pageable; diff --git a/src/main/java/com/epam/ta/reportportal/ws/controller/LogController.java b/src/main/java/com/epam/ta/reportportal/ws/controller/LogController.java index 583df097eb..69fb3f4aaa 100644 --- a/src/main/java/com/epam/ta/reportportal/ws/controller/LogController.java +++ b/src/main/java/com/epam/ta/reportportal/ws/controller/LogController.java @@ -60,8 +60,8 @@ import java.io.Serializable; import java.util.List; import java.util.Map; -import javax.servlet.http.HttpServletRequest; -import javax.validation.Validator; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.validation.Validator; import org.apache.commons.collections4.MultiValuedMap; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.exception.ExceptionUtils; diff --git a/src/main/java/com/epam/ta/reportportal/ws/controller/PluginController.java b/src/main/java/com/epam/ta/reportportal/ws/controller/PluginController.java index 43b4b7dbd6..19d292f105 100644 --- a/src/main/java/com/epam/ta/reportportal/ws/controller/PluginController.java +++ b/src/main/java/com/epam/ta/reportportal/ws/controller/PluginController.java @@ -43,8 +43,8 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import javax.validation.Valid; -import javax.validation.constraints.NotNull; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; diff --git a/src/main/java/com/epam/ta/reportportal/ws/controller/PluginPublicController.java b/src/main/java/com/epam/ta/reportportal/ws/controller/PluginPublicController.java index 3e5fec00fe..6d95cf8a98 100644 --- a/src/main/java/com/epam/ta/reportportal/ws/controller/PluginPublicController.java +++ b/src/main/java/com/epam/ta/reportportal/ws/controller/PluginPublicController.java @@ -28,7 +28,7 @@ import io.swagger.v3.oas.annotations.tags.Tag; import java.util.List; import java.util.Map; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; diff --git a/src/main/java/com/epam/ta/reportportal/ws/controller/ProjectController.java b/src/main/java/com/epam/ta/reportportal/ws/controller/ProjectController.java index a03568226d..41cef2fd99 100644 --- a/src/main/java/com/epam/ta/reportportal/ws/controller/ProjectController.java +++ b/src/main/java/com/epam/ta/reportportal/ws/controller/ProjectController.java @@ -72,7 +72,7 @@ import java.security.Principal; import java.util.List; import java.util.Map; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletResponse; import org.jooq.Operator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; diff --git a/src/main/java/com/epam/ta/reportportal/ws/controller/UserController.java b/src/main/java/com/epam/ta/reportportal/ws/controller/UserController.java index cb7a5bd481..144e5c5b8c 100644 --- a/src/main/java/com/epam/ta/reportportal/ws/controller/UserController.java +++ b/src/main/java/com/epam/ta/reportportal/ws/controller/UserController.java @@ -68,8 +68,8 @@ import java.io.OutputStream; import java.util.List; import java.util.Map; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.jooq.Operator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/builders/DashboardBuilder.java b/src/main/java/com/epam/ta/reportportal/ws/converter/builders/DashboardBuilder.java index 06afe99aaa..b9f3ad7d4b 100644 --- a/src/main/java/com/epam/ta/reportportal/ws/converter/builders/DashboardBuilder.java +++ b/src/main/java/com/epam/ta/reportportal/ws/converter/builders/DashboardBuilder.java @@ -60,7 +60,7 @@ public DashboardBuilder addUpdateRq(UpdateDashboardRQ rq) { Optional.ofNullable(rq.getDescription()) .ifPresent(description -> dashboard.setDescription(description)); Optional.ofNullable(rq.getWidgets()).ifPresent(widgets -> { - for (DashboardWidget dashboardWidget : dashboard.getDashboardWidgets()) { + for (DashboardWidget dashboardWidget : dashboard.getWidgets()) { widgets.stream().filter(updWidget -> Objects.equals(dashboardWidget.getId().getWidgetId(), updWidget.getWidgetId() )).forEach(updWidget -> { diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/builders/IntegrationTypeBuilder.java b/src/main/java/com/epam/ta/reportportal/ws/converter/builders/IntegrationTypeBuilder.java index 1c0faf45ee..d764f7cb6c 100644 --- a/src/main/java/com/epam/ta/reportportal/ws/converter/builders/IntegrationTypeBuilder.java +++ b/src/main/java/com/epam/ta/reportportal/ws/converter/builders/IntegrationTypeBuilder.java @@ -22,7 +22,7 @@ import com.google.common.collect.Maps; import java.time.Instant; import java.util.function.Supplier; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; /** * @author Ivan Budayeu diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/DashboardConverter.java b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/DashboardConverter.java index 26f6924520..983142379f 100644 --- a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/DashboardConverter.java +++ b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/DashboardConverter.java @@ -37,7 +37,7 @@ private DashboardConverter() { resource.setName(dashboard.getName()); resource.setDescription(dashboard.getDescription()); resource.setWidgets( - dashboard.getDashboardWidgets().stream().map(WidgetConverter.TO_OBJECT_MODEL) + dashboard.getWidgets().stream().map(WidgetConverter.TO_OBJECT_MODEL) .collect(Collectors.toList())); resource.setOwner(dashboard.getOwner()); return resource; diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/ItemAttributeConverter.java b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/ItemAttributeConverter.java index 1a17d6142f..534458ecea 100644 --- a/src/main/java/com/epam/ta/reportportal/ws/converter/converters/ItemAttributeConverter.java +++ b/src/main/java/com/epam/ta/reportportal/ws/converter/converters/ItemAttributeConverter.java @@ -49,8 +49,8 @@ private ItemAttributeConverter() { itemAttribute.setKey(key); itemAttribute.setValue(value); - if (it instanceof ItemAttributesRQ) { - itemAttribute.setSystem(((ItemAttributesRQ) it).isSystem()); + if (it instanceof ItemAttributesRQ itemAttributesRQ) { + itemAttribute.setSystem(itemAttributesRQ.isSystem()); } else { itemAttribute.setSystem(false); } @@ -68,4 +68,4 @@ private ItemAttributeConverter() { itemAttribute.setTestItem(item); return itemAttribute; }; -} \ No newline at end of file +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 7f9bbe1df0..ba526a6d8d 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -98,6 +98,9 @@ server.tomcat.connection-timeout=30s server.port=8585 server.servlet.context-path=/ +spring.servlet.multipart.max-file-size=128MB +spring.servlet.multipart.max-request-size=128MB + logging.level.org.hibernate=info logging.level.org.hibernate.stat=info logging.level.org.springframework.security=info diff --git a/src/test/java/com/epam/ta/reportportal/core/integration/util/EmailServerIntegrationServiceTest.java b/src/test/java/com/epam/ta/reportportal/core/integration/util/EmailServerIntegrationServiceTest.java index a205b7c531..cffcef67f5 100644 --- a/src/test/java/com/epam/ta/reportportal/core/integration/util/EmailServerIntegrationServiceTest.java +++ b/src/test/java/com/epam/ta/reportportal/core/integration/util/EmailServerIntegrationServiceTest.java @@ -34,7 +34,7 @@ import java.util.HashMap; import java.util.Map; import java.util.Optional; -import javax.mail.MessagingException; +import jakarta.mail.MessagingException; import org.jasypt.util.text.BasicTextEncryptor; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -124,4 +124,4 @@ private Map getParams() { return params; } -} \ No newline at end of file +} diff --git a/src/test/java/com/epam/ta/reportportal/core/log/impl/CreateLogHandlerAsyncImplTest.java b/src/test/java/com/epam/ta/reportportal/core/log/impl/CreateLogHandlerAsyncImplTest.java index 2889adffdb..7ca80d0297 100644 --- a/src/test/java/com/epam/ta/reportportal/core/log/impl/CreateLogHandlerAsyncImplTest.java +++ b/src/test/java/com/epam/ta/reportportal/core/log/impl/CreateLogHandlerAsyncImplTest.java @@ -31,7 +31,7 @@ import com.epam.ta.reportportal.reporting.async.producer.LogProducer; import com.epam.ta.reportportal.ws.reporting.SaveLogRQ; import java.util.UUID; -import javax.inject.Provider; +import jakarta.inject.Provider; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; @@ -114,4 +114,4 @@ void sendMessageWithoutLaunchUuid() { ); } -} \ No newline at end of file +} diff --git a/src/test/java/com/epam/ta/reportportal/core/logging/HttpLoggingAspectTest.java b/src/test/java/com/epam/ta/reportportal/core/logging/HttpLoggingAspectTest.java index 3556c67911..d34d7c6e26 100644 --- a/src/test/java/com/epam/ta/reportportal/core/logging/HttpLoggingAspectTest.java +++ b/src/test/java/com/epam/ta/reportportal/core/logging/HttpLoggingAspectTest.java @@ -27,7 +27,7 @@ import java.util.HashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicLong; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -156,4 +156,4 @@ private void formatRequestResponseAndPrint(long count, String prefix, HttpServle System.out.println(responseLog); } -} \ No newline at end of file +} diff --git a/src/test/java/com/epam/ta/reportportal/job/SelfCancalableJobTest.java b/src/test/java/com/epam/ta/reportportal/job/SelfCancalableJobTest.java index 0e9ebbef99..3208733c2a 100644 --- a/src/test/java/com/epam/ta/reportportal/job/SelfCancalableJobTest.java +++ b/src/test/java/com/epam/ta/reportportal/job/SelfCancalableJobTest.java @@ -18,6 +18,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; +import java.time.Instant; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; @@ -41,6 +42,11 @@ class SelfCancelableJobTest { @Test void selfCancelableJobTest() { SelfCancelableJob selfCancelableJob = new SelfCancelableJob(triggerDelegate) { + @Override + public Instant nextExecution(TriggerContext triggerContext) { + return null; + } + @Override public void run() { } @@ -57,4 +63,4 @@ public void run() { assertEquals(false, ReflectionTestUtils.getField(selfCancelableJob, "oneMoreTime")); } -} \ No newline at end of file +} diff --git a/src/test/java/com/epam/ta/reportportal/util/MultipartFileUtilsTest.java b/src/test/java/com/epam/ta/reportportal/util/MultipartFileUtilsTest.java index db5bf17ea9..44acb82b01 100644 --- a/src/test/java/com/epam/ta/reportportal/util/MultipartFileUtilsTest.java +++ b/src/test/java/com/epam/ta/reportportal/util/MultipartFileUtilsTest.java @@ -25,7 +25,7 @@ import org.apache.commons.io.IOUtils; import org.junit.jupiter.api.Test; import org.springframework.core.io.ClassPathResource; -import org.springframework.web.multipart.commons.CommonsMultipartFile; +import org.springframework.mock.web.MockMultipartFile; /** * @author Pavel Bortnik @@ -36,12 +36,12 @@ class MultipartFileUtilsTest { void getMultipartFile() throws IOException { String path = "image/image.png"; File expected = new ClassPathResource(path).getFile(); - CommonsMultipartFile file = MultipartFileUtils.getMultipartFile(path); + MockMultipartFile file = (MockMultipartFile)MultipartFileUtils.getMultipartFile(path); assertEquals(expected.length(), file.getSize()); - assertEquals(expected.getName(), file.getFileItem().getName()); + assertEquals(expected.getName(), file.getName()); assertEquals("image/png", file.getContentType()); try (FileInputStream expectedStream = new FileInputStream(expected)) { assertTrue(IOUtils.contentEquals(expectedStream, file.getInputStream())); } } -} \ No newline at end of file +} diff --git a/src/test/java/com/epam/ta/reportportal/util/email/MailServiceFactoryTest.java b/src/test/java/com/epam/ta/reportportal/util/email/MailServiceFactoryTest.java index bf2b19941f..50462a8a97 100644 --- a/src/test/java/com/epam/ta/reportportal/util/email/MailServiceFactoryTest.java +++ b/src/test/java/com/epam/ta/reportportal/util/email/MailServiceFactoryTest.java @@ -38,7 +38,7 @@ import java.util.Map; import java.util.Optional; import java.util.Properties; -import javax.mail.MessagingException; +import jakarta.mail.MessagingException; import org.jasypt.util.text.BasicTextEncryptor; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; @@ -257,4 +257,4 @@ void testConnectionNegative() throws MessagingException { ); } -} \ No newline at end of file +} diff --git a/src/test/java/com/epam/ta/reportportal/ws/controller/BugTrackingSystemControllerTest.java b/src/test/java/com/epam/ta/reportportal/ws/controller/BugTrackingSystemControllerTest.java index 2ba60514de..a85acd4f60 100644 --- a/src/test/java/com/epam/ta/reportportal/ws/controller/BugTrackingSystemControllerTest.java +++ b/src/test/java/com/epam/ta/reportportal/ws/controller/BugTrackingSystemControllerTest.java @@ -214,8 +214,8 @@ private PostTicketRQ getPostTicketRQ() { PostTicketRQ postTicketRQ = new PostTicketRQ(); postTicketRQ.setFields(getPostFormFields()); postTicketRQ.setNumberOfLogs(10); - postTicketRQ.setIsIncludeScreenshots(false); - postTicketRQ.setIsIncludeComments(false); + postTicketRQ.setIncludeScreenshots(false); + postTicketRQ.setIncludeScreenshots(false); postTicketRQ.setTestItemId(1L); return postTicketRQ; @@ -227,4 +227,4 @@ private List getPostFormFields() { .value(List.of("value")).definedValues(List.of(new AllowedValue("id", "name"))).build(); return Lists.newArrayList(field); } -} \ No newline at end of file +} diff --git a/src/test/java/com/epam/ta/reportportal/ws/controller/LaunchAsyncControllerTest.java b/src/test/java/com/epam/ta/reportportal/ws/controller/LaunchAsyncControllerTest.java index 30466c862b..ffcf34f796 100644 --- a/src/test/java/com/epam/ta/reportportal/ws/controller/LaunchAsyncControllerTest.java +++ b/src/test/java/com/epam/ta/reportportal/ws/controller/LaunchAsyncControllerTest.java @@ -36,7 +36,7 @@ import com.epam.ta.reportportal.ws.reporting.StartLaunchRQ; import com.google.common.collect.Lists; import java.util.UUID; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.ArgumentCaptor; @@ -164,4 +164,4 @@ void mergeLaunch() { ); assertEquals(mergeLaunchesRQ, requestArgumentCaptor.getValue()); } -} \ No newline at end of file +} diff --git a/src/test/java/com/epam/ta/reportportal/ws/controller/LogAsyncControllerTest.java b/src/test/java/com/epam/ta/reportportal/ws/controller/LogAsyncControllerTest.java index 33cdcc32e7..55b5f22e3b 100644 --- a/src/test/java/com/epam/ta/reportportal/ws/controller/LogAsyncControllerTest.java +++ b/src/test/java/com/epam/ta/reportportal/ws/controller/LogAsyncControllerTest.java @@ -31,8 +31,8 @@ import com.epam.ta.reportportal.reporting.async.controller.LogAsyncController; import com.epam.ta.reportportal.util.ProjectExtractor; import com.epam.ta.reportportal.ws.reporting.SaveLogRQ; -import javax.servlet.http.HttpServletRequest; -import javax.validation.Validator; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.validation.Validator; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.ArgumentCaptor; @@ -147,4 +147,4 @@ void createLogs() { projectDetailsArgumentCaptor.getAllValues() .forEach(arg -> assertEquals(user.getProjectDetails().get("test_project"), arg)); } -} \ No newline at end of file +} diff --git a/src/test/java/com/epam/ta/reportportal/ws/controller/PluginPublicControllerTest.java b/src/test/java/com/epam/ta/reportportal/ws/controller/PluginPublicControllerTest.java index b2e0c1a4a9..ffed7603b5 100644 --- a/src/test/java/com/epam/ta/reportportal/ws/controller/PluginPublicControllerTest.java +++ b/src/test/java/com/epam/ta/reportportal/ws/controller/PluginPublicControllerTest.java @@ -31,8 +31,8 @@ import java.io.ByteArrayInputStream; import java.util.Collections; import java.util.Map; -import javax.activation.MimetypesFileTypeMap; -import javax.servlet.http.HttpServletResponse; +import jakarta.activation.MimetypesFileTypeMap; +import jakarta.servlet.http.HttpServletResponse; import org.hamcrest.Matchers; import org.junit.jupiter.api.Test; import org.springframework.http.MediaType; diff --git a/src/test/java/com/epam/ta/reportportal/ws/converter/converters/DashboardConverterTest.java b/src/test/java/com/epam/ta/reportportal/ws/converter/converters/DashboardConverterTest.java index 73972ee144..0b0e13861b 100644 --- a/src/test/java/com/epam/ta/reportportal/ws/converter/converters/DashboardConverterTest.java +++ b/src/test/java/com/epam/ta/reportportal/ws/converter/converters/DashboardConverterTest.java @@ -66,7 +66,7 @@ void toResource() { assertEquals(resource.getName(), dashboard.getName()); assertEquals(resource.getDescription(), dashboard.getDescription()); assertEquals(resource.getOwner(), dashboard.getOwner()); - assertEquals(resource.getWidgets().size(), dashboard.getDashboardWidgets().size()); + assertEquals(resource.getWidgets().size(), dashboard.getWidgets().size()); } private static Dashboard getDashboard() { diff --git a/src/test/java/com/epam/ta/reportportal/ws/validation/TicketsValidationTest.java b/src/test/java/com/epam/ta/reportportal/ws/validation/TicketsValidationTest.java index ab7e6788ef..c4459d4c92 100644 --- a/src/test/java/com/epam/ta/reportportal/ws/validation/TicketsValidationTest.java +++ b/src/test/java/com/epam/ta/reportportal/ws/validation/TicketsValidationTest.java @@ -12,9 +12,9 @@ import java.util.HashSet; import java.util.Locale; import java.util.Set; -import javax.validation.ConstraintViolation; -import javax.validation.Validation; -import javax.validation.Validator; +import jakarta.validation.ConstraintViolation; +import jakarta.validation.Validation; +import jakarta.validation.Validator; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/epam/ta/reportportal/ws/validation/WidgetRqValidatorTest.java b/src/test/java/com/epam/ta/reportportal/ws/validation/WidgetRqValidatorTest.java index b682496dd4..c499493624 100644 --- a/src/test/java/com/epam/ta/reportportal/ws/validation/WidgetRqValidatorTest.java +++ b/src/test/java/com/epam/ta/reportportal/ws/validation/WidgetRqValidatorTest.java @@ -9,9 +9,9 @@ import com.epam.reportportal.model.ValidationConstraints; import java.util.Collections; import java.util.Set; -import javax.validation.ConstraintViolation; -import javax.validation.Validation; -import javax.validation.Validator; +import jakarta.validation.ConstraintViolation; +import jakarta.validation.Validation; +import jakarta.validation.Validator; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; From 7555ec8a60dd8ea2cf9d0a021172abb04cdfc6e1 Mon Sep 17 00:00:00 2001 From: siarhei_hrabko Date: Wed, 20 Nov 2024 23:13:59 +0300 Subject: [PATCH 2/7] SB3 --- build.gradle | 6 + .../reportportal/auth/CombinedTokenStore.java | 18 +- .../AssignedToProjectPermission.java | 5 +- .../permissions/BaseProjectPermission.java | 5 +- .../core/configs/SecurityConfiguration.java | 221 +++++++++--------- .../handler/DefectTypeDeletedHandler.java | 5 +- src/main/resources/application.properties | 9 +- 7 files changed, 141 insertions(+), 128 deletions(-) diff --git a/build.gradle b/build.gradle index 9c52db3594..0ff1997a6a 100644 --- a/build.gradle +++ b/build.gradle @@ -78,8 +78,14 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-batch' implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' + implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework:spring-context-support' implementation 'org.springframework.security:spring-security-jwt:1.1.1.RELEASE' + implementation 'org.springframework.security:spring-security-core' + implementation 'org.springframework.security:spring-security-oauth2-core' + implementation 'org.springframework.security:spring-security-oauth2-client' + implementation 'org.springframework.security:spring-security-oauth2-resource-server' + implementation 'org.springframework.security:spring-security-web' implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0' implementation 'com.opencsv:opencsv:5.9' diff --git a/src/main/java/com/epam/ta/reportportal/auth/CombinedTokenStore.java b/src/main/java/com/epam/ta/reportportal/auth/CombinedTokenStore.java index 9c81637335..36e91af957 100644 --- a/src/main/java/com/epam/ta/reportportal/auth/CombinedTokenStore.java +++ b/src/main/java/com/epam/ta/reportportal/auth/CombinedTokenStore.java @@ -21,6 +21,7 @@ import com.epam.ta.reportportal.dao.ApiKeyRepository; import com.epam.ta.reportportal.dao.UserRepository; import com.epam.ta.reportportal.entity.user.ApiKey; +import com.google.auth.oauth2.TokenStore; import com.google.common.collect.Maps; import java.time.LocalDate; import java.util.Collections; @@ -34,16 +35,13 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.support.MessageSourceAccessor; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.config.web.server.ServerHttpSecurity.OAuth2ResourceServerSpec.JwtSpec; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.SpringSecurityMessageSource; import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.oauth2.core.DefaultOAuth2AccessToken; -import org.springframework.security.oauth2.common.OAuth2AccessToken; -import org.springframework.security.oauth2.common.exceptions.InvalidTokenException; -import org.springframework.security.oauth2.provider.OAuth2Authentication; -import org.springframework.security.oauth2.provider.OAuth2Request; -import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter; -import org.springframework.security.oauth2.provider.token.store.JwtTokenStore; + +import org.springframework.security.oauth2.core.OAuth2AccessToken; +import org.springframework.security.oauth2.jwt.Jwt; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; @@ -52,7 +50,7 @@ */ @Component(value = "combinedTokenStore") @Transactional(readOnly = true) -public class CombinedTokenStore extends JwtTokenStore { +public class CombinedTokenStore { @Autowired private ApiKeyRepository apiKeyRepository; @@ -60,7 +58,7 @@ public class CombinedTokenStore extends JwtTokenStore { @Autowired private UserRepository userRepository; - @Autowired +/* @Autowired public CombinedTokenStore(JwtAccessTokenConverter jwtTokenEnhancer) { super(jwtTokenEnhancer); } @@ -151,5 +149,5 @@ private ReportPortalUser getUserWithAuthorities(ReportPortalUser user) { .withAuthorities(AuthUtils.AS_AUTHORITIES.apply(user.getUserRole())) .withUserId(user.getUserId()).withUserRole(user.getUserRole()) .withProjectDetails(Maps.newHashMapWithExpectedSize(1)).withEmail(user.getEmail()).build(); - } + }*/ } diff --git a/src/main/java/com/epam/ta/reportportal/auth/permissions/AssignedToProjectPermission.java b/src/main/java/com/epam/ta/reportportal/auth/permissions/AssignedToProjectPermission.java index 4a623eb14c..210c94fb99 100644 --- a/src/main/java/com/epam/ta/reportportal/auth/permissions/AssignedToProjectPermission.java +++ b/src/main/java/com/epam/ta/reportportal/auth/permissions/AssignedToProjectPermission.java @@ -26,6 +26,7 @@ import java.util.Optional; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.Authentication; +import org.springframework.security.oauth2.client.authentication.OAuth2LoginAuthenticationToken; import org.springframework.stereotype.Component; /** @@ -58,8 +59,8 @@ public boolean isAllowed(Authentication authentication, Object targetDomainObjec return false; } - OAuth2Authentication oauth = (OAuth2Authentication) authentication; - ReportPortalUser rpUser = (ReportPortalUser) oauth.getUserAuthentication().getPrincipal(); + OAuth2LoginAuthenticationToken oauth = (OAuth2LoginAuthenticationToken) authentication; + ReportPortalUser rpUser = (ReportPortalUser) oauth.getPrincipal(); BusinessRule.expect(rpUser, Objects::nonNull).verify(ErrorType.ACCESS_DENIED); final String resolvedProjectName = String.valueOf(targetDomainObject); diff --git a/src/main/java/com/epam/ta/reportportal/auth/permissions/BaseProjectPermission.java b/src/main/java/com/epam/ta/reportportal/auth/permissions/BaseProjectPermission.java index 76c303a3d1..3b1528d102 100644 --- a/src/main/java/com/epam/ta/reportportal/auth/permissions/BaseProjectPermission.java +++ b/src/main/java/com/epam/ta/reportportal/auth/permissions/BaseProjectPermission.java @@ -26,6 +26,7 @@ import java.util.Map; import java.util.Objects; import org.springframework.security.core.Authentication; +import org.springframework.security.oauth2.client.authentication.OAuth2LoginAuthenticationToken; /** * Base logic for project-related permissions. Validates project exists and there is provided in @@ -51,8 +52,8 @@ public boolean isAllowed(Authentication authentication, Object projectName) { return false; } - OAuth2Authentication oauth = (OAuth2Authentication) authentication; - ReportPortalUser rpUser = (ReportPortalUser) oauth.getUserAuthentication().getPrincipal(); + OAuth2LoginAuthenticationToken oauth = (OAuth2LoginAuthenticationToken) authentication; + ReportPortalUser rpUser = (ReportPortalUser) oauth.getPrincipal(); BusinessRule.expect(rpUser, Objects::nonNull).verify(ErrorType.ACCESS_DENIED); final String resolvedProjectName = String.valueOf(projectName); diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/SecurityConfiguration.java b/src/main/java/com/epam/ta/reportportal/core/configs/SecurityConfiguration.java index 51887e5f0f..5bba116d35 100644 --- a/src/main/java/com/epam/ta/reportportal/core/configs/SecurityConfiguration.java +++ b/src/main/java/com/epam/ta/reportportal/core/configs/SecurityConfiguration.java @@ -15,46 +15,36 @@ */ package com.epam.ta.reportportal.core.configs; -import com.epam.ta.reportportal.auth.CombinedTokenStore; import com.epam.ta.reportportal.auth.UserRoleHierarchy; import com.epam.ta.reportportal.auth.basic.DatabaseUserDetailsService; import com.epam.ta.reportportal.auth.permissions.PermissionEvaluatorFactoryBean; import com.epam.ta.reportportal.dao.ServerSettingsRepository; import com.epam.ta.reportportal.entity.ServerSettings; -import com.google.common.collect.Lists; -import java.util.List; +import java.nio.charset.StandardCharsets; import java.util.Optional; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Primary; import org.springframework.context.annotation.Profile; -import org.springframework.security.access.AccessDecisionManager; -import org.springframework.security.access.AccessDecisionVoter; import org.springframework.security.access.PermissionEvaluator; import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler; import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler; import org.springframework.security.access.hierarchicalroles.RoleHierarchy; -import org.springframework.security.access.vote.AffirmativeBased; -import org.springframework.security.access.vote.AuthenticatedVoter; -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; 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.configurers.AbstractHttpConfigurer; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; -import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; -import org.springframework.security.oauth2.provider.expression.OAuth2WebSecurityExpressionHandler; -import org.springframework.security.oauth2.provider.token.DefaultAccessTokenConverter; -import org.springframework.security.oauth2.provider.token.DefaultTokenServices; -import org.springframework.security.oauth2.provider.token.DefaultUserAuthenticationConverter; -import org.springframework.security.oauth2.provider.token.TokenStore; -import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter; -import org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler; -import org.springframework.security.web.access.expression.WebExpressionVoter; -import org.springframework.util.StringUtils; +import org.springframework.security.oauth2.jwt.JwtDecoder; +import org.springframework.security.oauth2.jwt.NimbusJwtDecoder; +import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter; +import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter; +import org.springframework.security.web.SecurityFilterChain; /** * Spring's Security Configuration @@ -62,8 +52,83 @@ * @author Andrei Varabyeu */ @Configuration +@EnableWebSecurity +@EnableMethodSecurity(proxyTargetClass = true) class SecurityConfiguration { + @Value("${rp.jwt.signing-key}") + private String signingKey; + + @Autowired + private PermissionEvaluator permissionEvaluator; + + @Autowired + private DatabaseUserDetailsService userDetailsService; + + @Autowired + private ServerSettingsRepository serverSettingsRepository; + + @Autowired + private RoleHierarchy roleHierarchy; + + private static final String SECRET_KEY = "secret.key"; + + @Bean + @Profile("!unittest") + public JwtAuthenticationConverter accessTokenConverter() { + + JwtAuthenticationConverter jwtConverter = new JwtAuthenticationConverter(); + jwtConverter.setJwtGrantedAuthoritiesConverter(new JwtGrantedAuthoritiesConverter()); + jwtConverter.setPrincipalClaimName("sub"); +/* + JwtBearerTokenAuthenticationConverter jwtConverter = new JwtBearerTokenAuthenticationConverter(); + jwtConverter.setJwtGrantedAuthoritiesConverter(new JwtGrantedAuthoritiesConverter()); + + DefaultAccessTokenConverter accessTokenConverter = new DefaultAccessTokenConverter(); + DefaultUserAuthenticationConverter defaultUserAuthenticationConverter = new DefaultUserAuthenticationConverter(); + defaultUserAuthenticationConverter.setUserDetailsService(userDetailsService); + accessTokenConverter.setUserTokenConverter(defaultUserAuthenticationConverter); + + jwtConverter.setAccessTokenConverter(accessTokenConverter);*/ + + return jwtConverter; + } + + @Bean + public SecurityFilterChain web(HttpSecurity http) throws Exception { + http.authorizeHttpRequests(authorize -> authorize + .requestMatchers("/**/user**/registration/info*", + "/**/user**/registration**", + "/**/user**/password/reset/*", + "/**/user**/password/reset**", + "/**/user**/password/restore**", + "/**/plugin/public/**", + "/documentation.html", + "/health", + "/info" + ) + .permitAll() + /* set of special endpoints for another microservices from RP ecosystem */ + .requestMatchers("/api-internal/**") + .hasRole("COMPONENT") + .requestMatchers("/v2/**", "/swagger-resources", "/certificate/**", "/api/**", "/**") + .hasRole("USER") + .anyRequest() + .authenticated()) + .oauth2ResourceServer(resourceServer -> + resourceServer.jwt( + jwt -> jwt.jwtAuthenticationConverter(accessTokenConverter()))) + .userDetailsService(userDetailsService) + .csrf(AbstractHttpConfigurer::disable); + + return http.build(); + } + +/* @Bean + public TokenStore tokenStore() { + return new CombinedTokenStore(accessTokenConverter()); + }*/ + @Bean public PermissionEvaluatorFactoryBean permissionEvaluator() { return new PermissionEvaluatorFactoryBean(); @@ -74,43 +139,28 @@ public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } - @Configuration - @EnableGlobalMethodSecurity(proxyTargetClass = true, prePostEnabled = true) - public static class MethodSecurityConfig extends GlobalMethodSecurityConfiguration { - - @Autowired - private RoleHierarchy roleHierarchy; - - @Autowired - private PermissionEvaluator permissionEvaluator; + @Bean + public static RoleHierarchy userRoleHierarchy() { + return new UserRoleHierarchy(); + } - @Override - protected MethodSecurityExpressionHandler createExpressionHandler() { - DefaultMethodSecurityExpressionHandler handler = new DefaultMethodSecurityExpressionHandler(); - handler.setRoleHierarchy(roleHierarchy); - handler.setPermissionEvaluator(permissionEvaluator); - return handler; - } + @Bean + JwtDecoder jwtDecoder() { + return NimbusJwtDecoder.withSecretKey(this.getSecret()).build(); + } + @Bean + public MethodSecurityExpressionHandler createExpressionHandler() { + DefaultMethodSecurityExpressionHandler handler = new DefaultMethodSecurityExpressionHandler(); + handler.setRoleHierarchy(roleHierarchy); + handler.setPermissionEvaluator(permissionEvaluator); + return handler; } - @Configuration +/* @Configuration @EnableResourceServer public static class SecurityServerConfiguration extends ResourceServerConfigurerAdapter { - private static final String SECRET_KEY = "secret.key"; - - @Value("${rp.jwt.signing-key}") - private String signingKey; - - @Autowired - private PermissionEvaluator permissionEvaluator; - - @Autowired - private DatabaseUserDetailsService userDetailsService; - - @Autowired - private ServerSettingsRepository serverSettingsRepository; @Bean public static PermissionEvaluatorFactoryBean permissionEvaluatorFactoryBean() { @@ -120,39 +170,10 @@ public static PermissionEvaluatorFactoryBean permissionEvaluatorFactoryBean() { @Bean public static RoleHierarchy userRoleHierarchy() { return new UserRoleHierarchy(); - } + }*/ - @Bean - public TokenStore tokenStore() { - return new CombinedTokenStore(accessTokenConverter()); - } - @Bean - @Profile("!unittest") - public JwtAccessTokenConverter accessTokenConverter() { - JwtAccessTokenConverter jwtConverter = new JwtAccessTokenConverter(); - jwtConverter.setSigningKey(getSecret()); - - DefaultAccessTokenConverter accessTokenConverter = new DefaultAccessTokenConverter(); - DefaultUserAuthenticationConverter defaultUserAuthenticationConverter = new DefaultUserAuthenticationConverter(); - defaultUserAuthenticationConverter.setUserDetailsService(userDetailsService); - accessTokenConverter.setUserTokenConverter(defaultUserAuthenticationConverter); - - jwtConverter.setAccessTokenConverter(accessTokenConverter); - - return jwtConverter; - } - - private String getSecret() { - if (!StringUtils.isEmpty(signingKey)) { - return signingKey; - } - Optional secretKey = serverSettingsRepository.findByKey(SECRET_KEY); - return secretKey.isPresent() ? secretKey.get().getValue() - : serverSettingsRepository.generateSecret(); - } - - @Bean +/* @Bean @Primary public DefaultTokenServices tokenServices() { DefaultTokenServices defaultTokenServices = new DefaultTokenServices(); @@ -177,35 +198,17 @@ private AccessDecisionManager webAccessDecisionManager() { accessDecisionVoters.add(webVoter); return new AffirmativeBased(accessDecisionVoters); - } + }*/ - @Override - public void configure(HttpSecurity http) throws Exception { - http.authorizeRequests() - .accessDecisionManager(webAccessDecisionManager()) - .requestMatchers("/**/user**/registration/info*", - "/**/user**/registration**", - "/**/user**/password/reset/*", - "/**/user**/password/reset**", - "/**/user**/password/restore**", - "/**/plugin/public/**", - "/documentation.html", - "/health", - "/info" - ) - .permitAll() - /* set of special endpoints for another microservices from RP ecosystem */ - .requestMatchers("/api-internal/**") - .hasRole("COMPONENT") - .requestMatchers("/v2/**", "/swagger-resources", "/certificate/**", "/api/**", "/**") - .hasRole("USER") - .anyRequest() - .authenticated() - .and() - .csrf() - .disable(); - } + private SecretKey getSecret() { + String secret = Optional.ofNullable(signingKey) + .filter(StringUtils::isNotEmpty) + .orElseGet(() -> serverSettingsRepository.findByKey(SECRET_KEY) + .map(ServerSettings::getValue) + .orElseGet(() -> serverSettingsRepository.generateSecret())); + + return new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), 0, secret.length(), "HmacSha256"); } } diff --git a/src/main/java/com/epam/ta/reportportal/core/events/handler/DefectTypeDeletedHandler.java b/src/main/java/com/epam/ta/reportportal/core/events/handler/DefectTypeDeletedHandler.java index e77629d434..91ea029e91 100644 --- a/src/main/java/com/epam/ta/reportportal/core/events/handler/DefectTypeDeletedHandler.java +++ b/src/main/java/com/epam/ta/reportportal/core/events/handler/DefectTypeDeletedHandler.java @@ -35,6 +35,7 @@ import org.springframework.retry.annotation.Backoff; import org.springframework.retry.annotation.Retryable; import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.event.TransactionalEventListener; @@ -67,8 +68,8 @@ public DefectTypeDeletedHandler(AnalyzerStatusCache analyzerStatusCache, this.projectRepository = projectRepository; } - @Transactional - @Retryable(value = ReportPortalException.class, maxAttempts = 5, backoff = @Backoff(value = 5000L)) + @Transactional(propagation = Propagation.REQUIRES_NEW) + @Retryable(retryFor = ReportPortalException.class, maxAttempts = 5, backoff = @Backoff(value = 5000L)) @TransactionalEventListener public void handleDefectTypeDeleted(DefectTypeDeletedEvent event) { Project project = projectRepository.findById(event.getProjectId()) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index ba526a6d8d..6873e0dffd 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -14,6 +14,10 @@ # limitations under the License. # spring.main.allow-bean-definition-overriding=true +#TODO: fix circular references +spring.main.allow-circular-references=true +#TODO: switch to PATH_PATTERN_PARSER +spring.mvc.pathmatch.matching-strategy=ANT_PATH_MATCHER spring.batch.jdbc.initialize-schema=always info.build.name=API Service info.build.description=ReportPortal API Service @@ -34,14 +38,13 @@ com.ta.reportportal.job.clean.bids.cron=PT1H spring.jooq.sql-dialect=POSTGRES -datastore.path=\${rp.binarystore.path:/data/storage} +datastore.path=\${rp.binarystore.path:/home/siarhei_hrabko/IdeaProjects/service-api/data} datastore.thumbnail.attachment.width=\${rp.binarystore.thumbnail.attachment.width:80} datastore.thumbnail.attachment.height=\${rp.binarystore.thumbnail.attachment.height:60} datastore.thumbnail.avatar.width=\${rp.binarystore.thumbnail.avatar.width:40} datastore.thumbnail.avatar.height=\${rp.binarystore.thumbnail.avatar.height:60} ## Datastore properties from application.yml -#datastore.path=/data/storage -datastore.type=minio +datastore.type=filesystem datastore.endpoint=http://play.min.io datastore.accessKey= datastore.secretKey= From 7ec46b71834c8011c7d50e25c6a3bee226765937 Mon Sep 17 00:00:00 2001 From: siarhei_hrabko Date: Mon, 9 Dec 2024 10:30:25 +0300 Subject: [PATCH 3/7] EPMRPP-96317 jwt token --- build.gradle | 15 ++-- gradle.properties | 4 +- .../epam/ta/reportportal/auth/JwtService.java | 11 +++ .../auth/acl/ReportPortalAclService.java | 0 .../auth/acl/ShareableObjectsHandler.java | 0 .../ta/reportportal/auth/util/AuthUtils.java | 15 +--- .../core/configs/AttachmentSizeConfig.java | 16 ++-- .../core/configs/BatchJobConfiguration.java | 7 +- .../core/configs/SecurityConfiguration.java | 16 +++- .../core/configs/filter/ApiKeyFilter.java | 78 +++++++++++++++++++ .../core/configs/filter/JwtFilter.java | 59 ++++++++++++++ .../model/settings/UpdateSettingsRq.java | 2 +- .../com/epam/ta/reportportal/TestConfig.java | 5 +- .../ta/reportportal/auth/OAuthHelper.java | 16 +++- 14 files changed, 207 insertions(+), 37 deletions(-) create mode 100644 src/main/java/com/epam/ta/reportportal/auth/JwtService.java delete mode 100644 src/main/java/com/epam/ta/reportportal/auth/acl/ReportPortalAclService.java delete mode 100644 src/main/java/com/epam/ta/reportportal/auth/acl/ShareableObjectsHandler.java create mode 100644 src/main/java/com/epam/ta/reportportal/core/configs/filter/ApiKeyFilter.java create mode 100644 src/main/java/com/epam/ta/reportportal/core/configs/filter/JwtFilter.java diff --git a/build.gradle b/build.gradle index 359fbe5e52..0bad13e6f7 100644 --- a/build.gradle +++ b/build.gradle @@ -18,7 +18,7 @@ plugins { id 'io.spring.dependency-management' version '1.1.6' id 'java' id 'java-library' - id 'org.owasp.dependencycheck' version '10.0.4' + id 'org.owasp.dependencycheck' version '11.1.1' id 'org.springframework.boot' version "${springBootVersion}" id "com.epam.drill.integration.cicd" version "0.1.6" } @@ -68,9 +68,9 @@ dependencies { implementation 'com.epam.reportportal:commons' implementation 'com.epam.reportportal:plugin-api' } else { - implementation 'com.github.reportportal:commons-dao:74bd07c' - implementation 'com.github.reportportal:commons:bbb9a1a' - implementation 'com.github.reportportal:plugin-api:0b9bdb3' + implementation 'com.github.reportportal:commons-dao:1fb643b' + implementation 'com.github.reportportal:commons:56e9608' + implementation 'com.github.reportportal:plugin-api:f7d2e68' } implementation 'org.springframework.boot:spring-boot-starter-aop' @@ -83,7 +83,6 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' implementation 'org.springframework.boot:spring-boot-starter-security' - implementation 'org.springframework:spring-context-support' implementation 'org.springframework.security:spring-security-jwt:1.1.1.RELEASE' implementation 'org.springframework.security:spring-security-core' implementation 'org.springframework.security:spring-security-oauth2-core' @@ -91,6 +90,9 @@ dependencies { implementation 'org.springframework.security:spring-security-oauth2-resource-server' implementation 'org.springframework.security:spring-security-web' implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0' + implementation "org.springdoc:springdoc-openapi-starter-common:2.6.0" // TODO: go down to 2.6.0 in case of problems + implementation 'org.springframework:spring-context-support' + implementation 'com.opencsv:opencsv:5.9' implementation "org.jooq:jooq:${jooqVersion}" @@ -106,7 +108,7 @@ dependencies { implementation 'com.sun.mail:jakarta.mail:2.0.1' implementation 'xerces:xercesImpl:2.12.2' - implementation 'com.lowagie:itext:4.2.2' + //implementation 'com.lowagie:itext:4.2.2' // JasperReport's export to XLS uses Apache POI implementation 'org.apache.poi:poi:4.1.2' implementation 'com.google.api-client:google-api-client:2.6.0' @@ -137,7 +139,6 @@ dependencies { testImplementation 'org.springframework.boot:spring-boot-starter-test' implementation 'org.springframework:spring-web' implementation 'org.springframework:spring-test' - testImplementation 'net.bytebuddy:byte-buddy:1.14.17' testImplementation 'org.flywaydb.flyway-test-extensions:flyway-spring-test:10.0.0' } diff --git a/gradle.properties b/gradle.properties index 5ed5d4182f..a3b305d325 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,8 +12,8 @@ dockerJavaOptsDev=-DLOG_FILE=app.log \ -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 dockerServerUrl=unix:///var/run/docker.sock org.gradle.jvmargs=-Xmx2048m -lombokVersion=1.18.34 -springBootVersion=3.3.5 +lombokVersion=1.18.36 +springBootVersion=3.4.0 jooqVersion=3.19.13 hibernateValidatorVersion=8.0.1.Final jcloudsVersion=2.6.0 diff --git a/src/main/java/com/epam/ta/reportportal/auth/JwtService.java b/src/main/java/com/epam/ta/reportportal/auth/JwtService.java new file mode 100644 index 0000000000..666fe71c4b --- /dev/null +++ b/src/main/java/com/epam/ta/reportportal/auth/JwtService.java @@ -0,0 +1,11 @@ +package com.epam.ta.reportportal.auth; + +import org.springframework.stereotype.Service; + +@Service +public class JwtService { + + public String extractUserName(String token){ + return ""; + } +} diff --git a/src/main/java/com/epam/ta/reportportal/auth/acl/ReportPortalAclService.java b/src/main/java/com/epam/ta/reportportal/auth/acl/ReportPortalAclService.java deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/main/java/com/epam/ta/reportportal/auth/acl/ShareableObjectsHandler.java b/src/main/java/com/epam/ta/reportportal/auth/acl/ShareableObjectsHandler.java deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/main/java/com/epam/ta/reportportal/auth/util/AuthUtils.java b/src/main/java/com/epam/ta/reportportal/auth/util/AuthUtils.java index 2cc9ecde1e..b32e5c8f79 100644 --- a/src/main/java/com/epam/ta/reportportal/auth/util/AuthUtils.java +++ b/src/main/java/com/epam/ta/reportportal/auth/util/AuthUtils.java @@ -16,19 +16,9 @@ package com.epam.ta.reportportal.auth.util; import com.epam.ta.reportportal.entity.user.UserRole; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InvalidClassException; -import java.io.ObjectInputStream; -import java.io.ObjectStreamClass; import java.util.Collections; import java.util.List; -import java.util.function.Consumer; import java.util.function.Function; -import javax.annotation.Nullable; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; @@ -43,8 +33,7 @@ private AuthUtils() { //statics only } - public static final Function> AS_AUTHORITIES = userRole -> Collections.singletonList( - new SimpleGrantedAuthority( - userRole.getAuthority())); + public static final Function> AS_AUTHORITIES = userRole -> + Collections.singletonList(new SimpleGrantedAuthority(userRole.getAuthority())); } diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/AttachmentSizeConfig.java b/src/main/java/com/epam/ta/reportportal/core/configs/AttachmentSizeConfig.java index 15ee8940e7..3f08fe4c6f 100644 --- a/src/main/java/com/epam/ta/reportportal/core/configs/AttachmentSizeConfig.java +++ b/src/main/java/com/epam/ta/reportportal/core/configs/AttachmentSizeConfig.java @@ -26,7 +26,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.batch.core.Step; -import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; +import org.springframework.batch.core.repository.JobRepository; +import org.springframework.batch.core.step.builder.StepBuilder; import org.springframework.batch.item.ItemProcessor; import org.springframework.batch.item.ItemWriter; import org.springframework.batch.item.database.JdbcCursorItemReader; @@ -36,6 +37,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.transaction.PlatformTransactionManager; import org.springframework.util.StreamUtils; /** @@ -49,9 +51,6 @@ public class AttachmentSizeConfig { private static final int CHUNK_SIZE = 10; - @Autowired - private StepBuilderFactory stepBuilderFactory; - @Autowired private DataSource dataSource; @@ -62,6 +61,12 @@ public class AttachmentSizeConfig { @Autowired private JdbcTemplate jdbcTemplate; + @Autowired + private JobRepository jobRepository; + + private PlatformTransactionManager transactionManager; + + @Bean public JdbcCursorItemReader reader() throws Exception { String query = "SELECT * from attachment order by id"; @@ -108,7 +113,8 @@ public ItemWriter writer() { @Bean public Step attachmentSizeStep() throws Exception { - return stepBuilderFactory.get("attachment").chunk(CHUNK_SIZE) + return new StepBuilder("attachment", jobRepository) + .chunk(CHUNK_SIZE, transactionManager) .reader(reader()) .processor(processor()) .writer(writer()) diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/BatchJobConfiguration.java b/src/main/java/com/epam/ta/reportportal/core/configs/BatchJobConfiguration.java index 9b861329fc..35353e92e9 100644 --- a/src/main/java/com/epam/ta/reportportal/core/configs/BatchJobConfiguration.java +++ b/src/main/java/com/epam/ta/reportportal/core/configs/BatchJobConfiguration.java @@ -21,9 +21,10 @@ import org.springframework.batch.core.JobExecutionListener; import org.springframework.batch.core.Step; import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; -import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; +import org.springframework.batch.core.job.builder.JobBuilder; import org.springframework.batch.core.job.builder.SimpleJobBuilder; import org.springframework.batch.core.launch.support.RunIdIncrementer; +import org.springframework.batch.core.repository.JobRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.context.annotation.Bean; @@ -39,7 +40,7 @@ public class BatchJobConfiguration { @Autowired - private JobBuilderFactory jobBuilderFactory; + private JobRepository jobRepository; @Autowired private Step attachmentSizeStep; @@ -65,7 +66,7 @@ public void afterJob(JobExecution jobExecution) { @Bean public Job job() { - SimpleJobBuilder job = jobBuilderFactory.get("attachmentSize") + SimpleJobBuilder job = new JobBuilder("attachmentSize", jobRepository) .incrementer(new RunIdIncrementer()) .listener(jobExecutionListener()) .start(attachmentSizeStep); diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/SecurityConfiguration.java b/src/main/java/com/epam/ta/reportportal/core/configs/SecurityConfiguration.java index 5bba116d35..1758bddb04 100644 --- a/src/main/java/com/epam/ta/reportportal/core/configs/SecurityConfiguration.java +++ b/src/main/java/com/epam/ta/reportportal/core/configs/SecurityConfiguration.java @@ -18,6 +18,8 @@ import com.epam.ta.reportportal.auth.UserRoleHierarchy; import com.epam.ta.reportportal.auth.basic.DatabaseUserDetailsService; import com.epam.ta.reportportal.auth.permissions.PermissionEvaluatorFactoryBean; +import com.epam.ta.reportportal.core.configs.filter.ApiKeyFilter; +import com.epam.ta.reportportal.core.configs.filter.JwtFilter; import com.epam.ta.reportportal.dao.ServerSettingsRepository; import com.epam.ta.reportportal.entity.ServerSettings; import java.nio.charset.StandardCharsets; @@ -45,6 +47,8 @@ import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter; import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter; import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter; /** * Spring's Security Configuration @@ -71,6 +75,12 @@ class SecurityConfiguration { @Autowired private RoleHierarchy roleHierarchy; + @Autowired + JwtFilter jwtFilter; + + @Autowired + ApiKeyFilter apiKeyFilter; + private static final String SECRET_KEY = "secret.key"; @Bean @@ -115,10 +125,12 @@ public SecurityFilterChain web(HttpSecurity http) throws Exception { .hasRole("USER") .anyRequest() .authenticated()) - .oauth2ResourceServer(resourceServer -> +/* .oauth2ResourceServer(resourceServer -> resourceServer.jwt( - jwt -> jwt.jwtAuthenticationConverter(accessTokenConverter()))) + jwt -> jwt.jwtAuthenticationConverter(accessTokenConverter())))*/ .userDetailsService(userDetailsService) + .addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class) + .addFilterBefore(apiKeyFilter, RememberMeAuthenticationFilter.class) .csrf(AbstractHttpConfigurer::disable); return http.build(); diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/filter/ApiKeyFilter.java b/src/main/java/com/epam/ta/reportportal/core/configs/filter/ApiKeyFilter.java new file mode 100644 index 0000000000..2905544921 --- /dev/null +++ b/src/main/java/com/epam/ta/reportportal/core/configs/filter/ApiKeyFilter.java @@ -0,0 +1,78 @@ +package com.epam.ta.reportportal.core.configs.filter; + +import com.epam.ta.reportportal.auth.ApiKeyUtils; +import com.epam.ta.reportportal.auth.util.AuthUtils; +import com.epam.ta.reportportal.commons.ReportPortalUser; +import com.epam.ta.reportportal.dao.ApiKeyRepository; +import com.epam.ta.reportportal.dao.UserRepository; +import com.epam.ta.reportportal.entity.user.ApiKey; +import com.google.common.collect.Maps; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.xml.bind.DatatypeConverter; +import java.io.IOException; +import java.time.LocalDate; +import org.apache.commons.codec.digest.DigestUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.authentication.RememberMeAuthenticationToken; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken; +import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; +import org.springframework.stereotype.Component; +import org.springframework.web.filter.OncePerRequestFilter; + +@Component +public class ApiKeyFilter extends OncePerRequestFilter { + + @Autowired + private ApiKeyRepository apiKeyRepository; + + @Autowired + private UserRepository userRepository; + + @Autowired + private UserDetailsService userDetailsService; + + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, + FilterChain filterChain) throws ServletException, IOException { + String tokenValue = request.getHeader("apiKey"); + if (tokenValue != null) { + if (ApiKeyUtils.validateToken(tokenValue)) { + RememberMeAuthenticationToken authToken = new RememberMeAuthenticationToken(tokenValue, + userDetailsService, + null + ); + authToken.setDetails( + new WebAuthenticationDetailsSource().buildDetails(request) + ); + SecurityContextHolder.getContext().setAuthentication(authToken); + + String hashedKey = DatatypeConverter.printHexBinary(DigestUtils.sha3_256(tokenValue)); + ApiKey apiKey = apiKeyRepository.findByHash(hashedKey); + if (apiKey != null) { + LocalDate today = LocalDate.now(); + if (apiKey.getLastUsedAt() == null || !apiKey.getLastUsedAt().equals(today)) { + apiKeyRepository.updateLastUsedAt(apiKey.getId(), hashedKey, today); + } + } + } + } + + filterChain.doFilter(request, response); + } + + private ReportPortalUser getUserWithAuthorities(ReportPortalUser user) { + return ReportPortalUser.userBuilder().withUserName(user.getUsername()) + .withPassword(user.getPassword()) + .withAuthorities(AuthUtils.AS_AUTHORITIES.apply(user.getUserRole())) + .withUserId(user.getUserId()).withUserRole(user.getUserRole()) + .withProjectDetails(Maps.newHashMapWithExpectedSize(1)).withEmail(user.getEmail()).build(); + } +} diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/filter/JwtFilter.java b/src/main/java/com/epam/ta/reportportal/core/configs/filter/JwtFilter.java new file mode 100644 index 0000000000..34636844f8 --- /dev/null +++ b/src/main/java/com/epam/ta/reportportal/core/configs/filter/JwtFilter.java @@ -0,0 +1,59 @@ +package com.epam.ta.reportportal.core.configs.filter; + +import static org.apache.http.HttpHeaders.AUTHORIZATION; + +import com.epam.ta.reportportal.auth.JwtService; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import java.io.IOException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.oauth2.jwt.Jwt; +import org.springframework.security.oauth2.jwt.JwtDecoder; +import org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthentication; +import org.springframework.stereotype.Component; +import org.springframework.web.filter.OncePerRequestFilter; + +@Component +public class JwtFilter extends OncePerRequestFilter { + + @Autowired + private JwtService jwtService; + + @Autowired + JwtDecoder jwtDecoder; + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, + FilterChain filterChain) throws ServletException, IOException { + System.out.println("asd"); + String authHeader = request.getHeader(AUTHORIZATION); + String token = null; + String username = null; + if (authHeader != null && authHeader.startsWith("Bearer")) { + token = authHeader.substring(7); + username = jwtService.extractUserName(token); + Jwt jwt = jwtDecoder.decode(token); + } + + if (username != null && SecurityContextHolder.getContext().getAuthentication() != null) { + + // SecurityContextHolder.getContext().setAuthentication(new BearerTokenAuthentication()); + } + +/* + public BearerTokenAuthentication(OAuth2AuthenticatedPrincipal principal, OAuth2AccessToken + credentials, Collection authorities) { + super(credentials, principal, credentials, authorities); + Assert.isTrue(credentials.getTokenType() == TokenType.BEARER, "credentials must be a bearer token"); + this.attributes = Collections.unmodifiableMap(new LinkedHashMap(principal.getAttributes())); + this.setAuthenticated(true); + } +*/ + + //request.getHeader() + filterChain.doFilter(request, response); + } +} diff --git a/src/main/java/com/epam/ta/reportportal/model/settings/UpdateSettingsRq.java b/src/main/java/com/epam/ta/reportportal/model/settings/UpdateSettingsRq.java index 5ec587ed2e..20fd53de3b 100644 --- a/src/main/java/com/epam/ta/reportportal/model/settings/UpdateSettingsRq.java +++ b/src/main/java/com/epam/ta/reportportal/model/settings/UpdateSettingsRq.java @@ -15,7 +15,7 @@ */ package com.epam.ta.reportportal.model.settings; -import javax.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotEmpty; import lombok.Data; /** diff --git a/src/test/java/com/epam/ta/reportportal/TestConfig.java b/src/test/java/com/epam/ta/reportportal/TestConfig.java index 60e35589e7..7d9d76e6df 100644 --- a/src/test/java/com/epam/ta/reportportal/TestConfig.java +++ b/src/test/java/com/epam/ta/reportportal/TestConfig.java @@ -42,6 +42,7 @@ import org.springframework.security.oauth2.provider.token.DefaultAccessTokenConverter; import org.springframework.security.oauth2.provider.token.DefaultUserAuthenticationConverter; import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter; +import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter; /** * @author Ihar Kahadouski @@ -90,7 +91,7 @@ protected RabbitMqManagementClient managementTemplate() { @Bean @Profile("unittest") public JwtAccessTokenConverter accessTokenConverter() { - JwtAccessTokenConverter jwtConverter = new JwtAccessTokenConverter(); + JwtAuthenticationConverter jwtConverter = new JwtAuthenticationConverter(); jwtConverter.setSigningKey("123"); DefaultAccessTokenConverter accessTokenConverter = new DefaultAccessTokenConverter(); @@ -112,4 +113,4 @@ public ObjectMapper testObjectMapper() { return objectMapper; } -} \ No newline at end of file +} diff --git a/src/test/java/com/epam/ta/reportportal/auth/OAuthHelper.java b/src/test/java/com/epam/ta/reportportal/auth/OAuthHelper.java index 407a7f4cdb..ba1141519a 100644 --- a/src/test/java/com/epam/ta/reportportal/auth/OAuthHelper.java +++ b/src/test/java/com/epam/ta/reportportal/auth/OAuthHelper.java @@ -17,9 +17,11 @@ package com.epam.ta.reportportal.auth; import com.epam.ta.reportportal.entity.user.UserRole; +import com.nimbusds.jwt.JWTClaimsSet; import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.Set; @@ -68,7 +70,16 @@ public String getCustomerToken() { customerToken; } - private OAuth2AccessToken createAccessToken(String username, String password, UserRole... roles) { + private AccessToken createAccessToken(String username, String password, UserRole... roles) { + + var claimsSet = new JWTClaimsSet.Builder() + .expirationTime(new Date(new Date().getTime() + 60 * 1000)) + .build(); + var signedJWT = new SignedJWT(new JWSHeader.Builder(JWSAlgorithm.RS256) + .keyID(rsaKey.getKeyID()).build(), claimsSet); + signedJWT.sign(signer); + return signedJWT.serialize(); + Collection authorities = Arrays.stream(roles) .map(it -> new SimpleGrantedAuthority(it.getAuthority())) .collect(Collectors.toList()); @@ -80,6 +91,7 @@ private OAuth2AccessToken createAccessToken(String username, String password, Us requestParameters.put("grand_type", "password"); requestParameters.put("username", username); + OAuth2Request oAuth2Request = new OAuth2Request( requestParameters, "ui", @@ -97,4 +109,4 @@ private OAuth2AccessToken createAccessToken(String username, String password, Us OAuth2Authentication auth = new OAuth2Authentication(oAuth2Request, authenticationToken); return tokenService.createAccessToken(auth); } -} \ No newline at end of file +} From 4c10f4fab666267a0507eb03d7c500f74eb1e1d3 Mon Sep 17 00:00:00 2001 From: siarhei_hrabko Date: Tue, 7 Jan 2025 13:18:49 +0300 Subject: [PATCH 4/7] EPMRPP-96333 migrate to Spring Boot 3 --- build.gradle | 19 ++- gradle.properties | 6 +- gradle/wrapper/gradle-wrapper.properties | 2 +- .../{core/configs => }/ReportPortalApp.java | 2 +- .../reportportal/auth/CombinedTokenStore.java | 153 ------------------ .../auth/JwtReportPortalUserConverter.java | 57 +++++++ .../epam/ta/reportportal/auth/JwtService.java | 20 ++- .../reportportal/auth/UserRoleHierarchy.java | 19 +-- .../AssignedToProjectPermission.java | 5 +- .../permissions/BaseProjectPermission.java | 5 +- .../ReportPortalPermissionEvaluator.java | 4 +- .../core/configs/SecurityConfiguration.java | 120 +++++--------- .../core/configs/filter/ApiKeyFilter.java | 68 +++++--- .../core/configs/filter/JwtFilter.java | 42 ++--- .../ws/controller/IntegrationController.java | 2 +- .../ws/controller/ProjectController.java | 3 +- .../ws/controller/UserController.java | 5 +- src/main/resources/application.properties | 9 +- 18 files changed, 220 insertions(+), 321 deletions(-) rename src/main/java/com/epam/ta/reportportal/{core/configs => }/ReportPortalApp.java (96%) delete mode 100644 src/main/java/com/epam/ta/reportportal/auth/CombinedTokenStore.java create mode 100644 src/main/java/com/epam/ta/reportportal/auth/JwtReportPortalUserConverter.java diff --git a/build.gradle b/build.gradle index 6b77483046..b93ee9358a 100644 --- a/build.gradle +++ b/build.gradle @@ -15,7 +15,7 @@ */ plugins { - id 'io.spring.dependency-management' version '1.1.6' + id 'io.spring.dependency-management' version '1.1.7' id 'java' id 'java-library' id 'org.owasp.dependencycheck' version '11.1.1' @@ -68,9 +68,9 @@ dependencies { implementation 'com.epam.reportportal:commons' implementation 'com.epam.reportportal:plugin-api' } else { - implementation 'com.github.reportportal:commons-dao:1fb643b' - implementation 'com.github.reportportal:commons:56e9608' - implementation 'com.github.reportportal:plugin-api:f7d2e68' + implementation 'com.github.reportportal:commons-dao:b13f8d3' + implementation 'com.github.reportportal:commons:6729eb7' + implementation 'com.github.reportportal:plugin-api:e37b0fd' } implementation 'org.springframework.boot:spring-boot-starter-aop' @@ -83,14 +83,13 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' implementation 'org.springframework.boot:spring-boot-starter-security' - implementation 'org.springframework.security:spring-security-jwt:1.1.1.RELEASE' + implementation 'org.springframework.security:spring-security-core' implementation 'org.springframework.security:spring-security-oauth2-core' implementation 'org.springframework.security:spring-security-oauth2-client' implementation 'org.springframework.security:spring-security-oauth2-resource-server' implementation 'org.springframework.security:spring-security-web' - implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0' - implementation "org.springdoc:springdoc-openapi-starter-common:2.6.0" // TODO: go down to 2.6.0 in case of problems + implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.7.0' implementation 'org.springframework:spring-context-support' @@ -112,7 +111,7 @@ dependencies { // Fix CVE-2021-43113 in com.lowagie:itext:4.2.2 implementation 'com.itextpdf:itextpdf:5.5.13.4' // Fix CVE-2020-15522 in com.lowagie:itext:2.1.7.js7 - implementation 'org.bouncycastle:bcprov-jdk15on:1.70' + implementation 'org.bouncycastle:bcprov-jdk18on:1.78.1' // JasperReport's export to XLS uses Apache POI implementation 'org.apache.poi:poi:4.1.2' implementation 'com.google.api-client:google-api-client:2.6.0' @@ -122,7 +121,7 @@ dependencies { } implementation 'org.springframework.security:spring-security-acl' implementation 'com.github.ben-manes.caffeine:caffeine' - implementation 'commons-fileupload:commons-fileupload:1.5' // TODO to delete + implementation 'commons-fileupload:commons-fileupload:1.5' // TODO: to remove implementation "org.apache.jclouds.api:filesystem:${jcloudsVersion}" @@ -131,7 +130,7 @@ dependencies { implementation "org.hibernate.validator:hibernate-validator:${hibernateValidatorVersion}" // Metrics - implementation 'io.micrometer:micrometer-registry-prometheus:1.13.2' + implementation 'io.micrometer:micrometer-registry-prometheus:1.14.2' // add lombok support compileOnly "org.projectlombok:lombok:${lombokVersion}" diff --git a/gradle.properties b/gradle.properties index a0b02fed72..3dcf5b1692 100644 --- a/gradle.properties +++ b/gradle.properties @@ -13,7 +13,7 @@ dockerJavaOptsDev=-DLOG_FILE=app.log \ dockerServerUrl=unix:///var/run/docker.sock org.gradle.jvmargs=-Xmx2048m lombokVersion=1.18.36 -springBootVersion=3.4.0 -jooqVersion=3.19.13 -hibernateValidatorVersion=8.0.1.Final +springBootVersion=3.4.1 +jooqVersion=3.19.16 +hibernateValidatorVersion=8.0.2.Final jcloudsVersion=2.6.0 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index df97d72b8b..cea7a793a8 100755 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/ReportPortalApp.java b/src/main/java/com/epam/ta/reportportal/ReportPortalApp.java similarity index 96% rename from src/main/java/com/epam/ta/reportportal/core/configs/ReportPortalApp.java rename to src/main/java/com/epam/ta/reportportal/ReportPortalApp.java index 26ba489a01..1e5692e1da 100644 --- a/src/main/java/com/epam/ta/reportportal/core/configs/ReportPortalApp.java +++ b/src/main/java/com/epam/ta/reportportal/ReportPortalApp.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.epam.ta.reportportal.core.configs; +package com.epam.ta.reportportal; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git a/src/main/java/com/epam/ta/reportportal/auth/CombinedTokenStore.java b/src/main/java/com/epam/ta/reportportal/auth/CombinedTokenStore.java deleted file mode 100644 index 36e91af957..0000000000 --- a/src/main/java/com/epam/ta/reportportal/auth/CombinedTokenStore.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright 2019 EPAM Systems - * - * Licensed 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 com.epam.ta.reportportal.auth; - -import com.epam.ta.reportportal.auth.util.AuthUtils; -import com.epam.ta.reportportal.commons.ReportPortalUser; -import com.epam.ta.reportportal.dao.ApiKeyRepository; -import com.epam.ta.reportportal.dao.UserRepository; -import com.epam.ta.reportportal.entity.user.ApiKey; -import com.google.auth.oauth2.TokenStore; -import com.google.common.collect.Maps; -import java.time.LocalDate; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Optional; -import java.util.Set; -import jakarta.xml.bind.DatatypeConverter; -import org.apache.commons.codec.digest.DigestUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.support.MessageSourceAccessor; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.config.web.server.ServerHttpSecurity.OAuth2ResourceServerSpec.JwtSpec; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.SpringSecurityMessageSource; -import org.springframework.security.core.authority.SimpleGrantedAuthority; - -import org.springframework.security.oauth2.core.OAuth2AccessToken; -import org.springframework.security.oauth2.jwt.Jwt; -import org.springframework.stereotype.Component; -import org.springframework.transaction.annotation.Transactional; - -/** - * @author Pavel Bortnik - */ -@Component(value = "combinedTokenStore") -@Transactional(readOnly = true) -public class CombinedTokenStore { - - @Autowired - private ApiKeyRepository apiKeyRepository; - - @Autowired - private UserRepository userRepository; - -/* @Autowired - public CombinedTokenStore(JwtAccessTokenConverter jwtTokenEnhancer) { - super(jwtTokenEnhancer); - } - - @Override - public OAuth2Authentication readAuthentication(OAuth2AccessToken token) { - try { - return super.readAuthentication(token); - } catch (InvalidTokenException e) { - return this.readAuthentication(token.getValue()); - } - } - - @Transactional - @Override - public OAuth2Authentication readAuthentication(String tokenId) { - try { - return super.readAuthentication(tokenId); - } catch (InvalidTokenException e) { - String hashedKey = DatatypeConverter.printHexBinary(DigestUtils.sha3_256(tokenId)); - ApiKey apiKey = apiKeyRepository.findByHash(hashedKey); - if (apiKey != null) { - Optional user = userRepository.findReportPortalUser(apiKey.getUserId()); - if (user.isPresent() && user.get().isEnabled()) { - LocalDate today = LocalDate.now(); - if (apiKey.getLastUsedAt() == null || !apiKey.getLastUsedAt().equals(today)) { - apiKeyRepository.updateLastUsedAt(apiKey.getId(), hashedKey, today); - } - return getAuthentication(getUserWithAuthorities(user.get())); - } - } - return null; - } - } - - @Transactional - @Override - public OAuth2AccessToken readAccessToken(String tokenValue) { - try { - return super.readAccessToken(tokenValue); - } catch (InvalidTokenException e) { - if (ApiKeyUtils.validateToken(tokenValue)) { - DefaultOAuth2AccessToken defaultOAuth2AccessToken = - new DefaultOAuth2AccessToken(tokenValue); - defaultOAuth2AccessToken.setExpiration(new Date(System.currentTimeMillis() + 60 * 1000L)); - String hashedKey = DatatypeConverter.printHexBinary(DigestUtils.sha3_256(tokenValue)); - ApiKey apiKey = apiKeyRepository.findByHash(hashedKey); - if (apiKey != null) { - LocalDate today = LocalDate.now(); - if (apiKey.getLastUsedAt() == null || !apiKey.getLastUsedAt().equals(today)) { - apiKeyRepository.updateLastUsedAt(apiKey.getId(), hashedKey, today); - } - } - return defaultOAuth2AccessToken; - } - return null; //let spring security handle the invalid token - } - } - - private OAuth2Authentication getAuthentication(ReportPortalUser user) { - HashMap requestParameters = new HashMap<>(); - requestParameters.put("username", user.getUsername()); - requestParameters.put("client_id", ReportPortalClient.api.name()); - - Set authorities = new HashSet<>(); - authorities.add(new SimpleGrantedAuthority(user.getUserRole().getAuthority())); - - Set scopes = Collections.singleton(ReportPortalClient.api.name()); - - OAuth2Request authorizationRequest = - new OAuth2Request(requestParameters, ReportPortalClient.api.name(), authorities, true, - scopes, Collections.emptySet(), null, Collections.emptySet(), null - ); - - UsernamePasswordAuthenticationToken authenticationToken = - new UsernamePasswordAuthenticationToken(user, null, authorities); - - OAuth2Authentication authenticationRequest = - new OAuth2Authentication(authorizationRequest, authenticationToken); - authenticationRequest.setAuthenticated(true); - - return authenticationRequest; - } - - private ReportPortalUser getUserWithAuthorities(ReportPortalUser user) { - return ReportPortalUser.userBuilder().withUserName(user.getUsername()) - .withPassword(user.getPassword()) - .withAuthorities(AuthUtils.AS_AUTHORITIES.apply(user.getUserRole())) - .withUserId(user.getUserId()).withUserRole(user.getUserRole()) - .withProjectDetails(Maps.newHashMapWithExpectedSize(1)).withEmail(user.getEmail()).build(); - }*/ -} diff --git a/src/main/java/com/epam/ta/reportportal/auth/JwtReportPortalUserConverter.java b/src/main/java/com/epam/ta/reportportal/auth/JwtReportPortalUserConverter.java new file mode 100644 index 0000000000..b087fed492 --- /dev/null +++ b/src/main/java/com/epam/ta/reportportal/auth/JwtReportPortalUserConverter.java @@ -0,0 +1,57 @@ +/* + * Copyright 2025 EPAM Systems + * + * Licensed 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 com.epam.ta.reportportal.auth; + +import jakarta.validation.constraints.NotNull; +import java.util.Collection; +import org.springframework.core.convert.converter.Converter; +import org.springframework.security.authentication.AbstractAuthenticationToken; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.oauth2.jwt.Jwt; +import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter; + +public class JwtReportPortalUserConverter implements Converter { + + private final UserDetailsService userDetailsService; + + private Converter> jwtGrantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter(); + + private final static String PRINCIPAL_CLAIM_NAME = "user_name"; + + public JwtReportPortalUserConverter(UserDetailsService userDetailsService) { + this.userDetailsService = userDetailsService; + } + + @Override + public final AbstractAuthenticationToken convert(Jwt jwt) { + Collection authorities = this.jwtGrantedAuthoritiesConverter.convert(jwt); + + String username = jwt.getClaimAsString(PRINCIPAL_CLAIM_NAME); + var principal = userDetailsService.loadUserByUsername(username); + + return new UsernamePasswordAuthenticationToken(principal, null, authorities); + } + + + public void setJwtGrantedAuthoritiesConverter(@NotNull + Converter> jwtGrantedAuthoritiesConverter) { + this.jwtGrantedAuthoritiesConverter = jwtGrantedAuthoritiesConverter; + } + +} diff --git a/src/main/java/com/epam/ta/reportportal/auth/JwtService.java b/src/main/java/com/epam/ta/reportportal/auth/JwtService.java index 666fe71c4b..44d280fb12 100644 --- a/src/main/java/com/epam/ta/reportportal/auth/JwtService.java +++ b/src/main/java/com/epam/ta/reportportal/auth/JwtService.java @@ -1,11 +1,27 @@ package com.epam.ta.reportportal.auth; +import static java.util.Objects.requireNonNull; + +import java.time.Instant; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.oauth2.jwt.JwtDecoder; import org.springframework.stereotype.Service; @Service public class JwtService { - public String extractUserName(String token){ - return ""; + @Autowired + private JwtDecoder jwtDecoder; + + public String extractUserName(String token) { + return (String) jwtDecoder.decode(token) + .getClaims() + .get("user_name"); } + + public boolean isValid(String token) { + return Instant.now() + .isBefore(requireNonNull(jwtDecoder.decode(token).getExpiresAt())); + } + } diff --git a/src/main/java/com/epam/ta/reportportal/auth/UserRoleHierarchy.java b/src/main/java/com/epam/ta/reportportal/auth/UserRoleHierarchy.java index 7b3b3f0aa2..d9fe2b7644 100644 --- a/src/main/java/com/epam/ta/reportportal/auth/UserRoleHierarchy.java +++ b/src/main/java/com/epam/ta/reportportal/auth/UserRoleHierarchy.java @@ -25,8 +25,7 @@ import java.util.Map; import java.util.Set; import java.util.stream.Collectors; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import lombok.extern.log4j.Log4j2; import org.springframework.security.access.hierarchicalroles.RoleHierarchy; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.AuthorityUtils; @@ -38,6 +37,7 @@ * * @author Andrei Varabyeu */ +@Log4j2 public class UserRoleHierarchy implements RoleHierarchy { public static final String ROLE_REGISTERED = "ROLE_REGISTERED"; @@ -47,8 +47,6 @@ public class UserRoleHierarchy implements RoleHierarchy { */ public static final String ROLE_COMPONENT = "ROLE_COMPONENT"; - private static final Logger logger = LoggerFactory.getLogger(UserRoleHierarchy.class); - private Map> authoritiesMap; public UserRoleHierarchy() { @@ -74,12 +72,11 @@ public Collection getReachableGrantedAuthorities( .flatMap(authority -> authoritiesMap.get(authority).stream()) .collect(Collectors.toList()); - if (logger.isDebugEnabled()) { - logger.debug( - "getReachableGrantedAuthorities() - From the roles " + authorities + " one can reach " - + reachableRoles - + " in zero or more steps."); - } + + log.debug( + "getReachableGrantedAuthorities() - From the roles {} one can reach {} in zero or more steps.", + authorities, reachableRoles); + return reachableRoles; } @@ -98,4 +95,4 @@ private GrantedAuthority asAuthority(UserRole userRole) { return new SimpleGrantedAuthority(userRole.getAuthority()); } -} \ No newline at end of file +} diff --git a/src/main/java/com/epam/ta/reportportal/auth/permissions/AssignedToProjectPermission.java b/src/main/java/com/epam/ta/reportportal/auth/permissions/AssignedToProjectPermission.java index 210c94fb99..11c1ca9b86 100644 --- a/src/main/java/com/epam/ta/reportportal/auth/permissions/AssignedToProjectPermission.java +++ b/src/main/java/com/epam/ta/reportportal/auth/permissions/AssignedToProjectPermission.java @@ -26,7 +26,6 @@ import java.util.Optional; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.Authentication; -import org.springframework.security.oauth2.client.authentication.OAuth2LoginAuthenticationToken; import org.springframework.stereotype.Component; /** @@ -58,9 +57,7 @@ public boolean isAllowed(Authentication authentication, Object targetDomainObjec if (!authentication.isAuthenticated()) { return false; } - - OAuth2LoginAuthenticationToken oauth = (OAuth2LoginAuthenticationToken) authentication; - ReportPortalUser rpUser = (ReportPortalUser) oauth.getPrincipal(); + ReportPortalUser rpUser = (ReportPortalUser) authentication.getPrincipal(); BusinessRule.expect(rpUser, Objects::nonNull).verify(ErrorType.ACCESS_DENIED); final String resolvedProjectName = String.valueOf(targetDomainObject); diff --git a/src/main/java/com/epam/ta/reportportal/auth/permissions/BaseProjectPermission.java b/src/main/java/com/epam/ta/reportportal/auth/permissions/BaseProjectPermission.java index 3b1528d102..b03772ad1e 100644 --- a/src/main/java/com/epam/ta/reportportal/auth/permissions/BaseProjectPermission.java +++ b/src/main/java/com/epam/ta/reportportal/auth/permissions/BaseProjectPermission.java @@ -26,7 +26,6 @@ import java.util.Map; import java.util.Objects; import org.springframework.security.core.Authentication; -import org.springframework.security.oauth2.client.authentication.OAuth2LoginAuthenticationToken; /** * Base logic for project-related permissions. Validates project exists and there is provided in @@ -51,9 +50,7 @@ public boolean isAllowed(Authentication authentication, Object projectName) { if (!authentication.isAuthenticated()) { return false; } - - OAuth2LoginAuthenticationToken oauth = (OAuth2LoginAuthenticationToken) authentication; - ReportPortalUser rpUser = (ReportPortalUser) oauth.getPrincipal(); + ReportPortalUser rpUser = (ReportPortalUser) authentication.getPrincipal(); BusinessRule.expect(rpUser, Objects::nonNull).verify(ErrorType.ACCESS_DENIED); final String resolvedProjectName = String.valueOf(projectName); diff --git a/src/main/java/com/epam/ta/reportportal/auth/permissions/ReportPortalPermissionEvaluator.java b/src/main/java/com/epam/ta/reportportal/auth/permissions/ReportPortalPermissionEvaluator.java index daaa26b327..1ce9b300e9 100644 --- a/src/main/java/com/epam/ta/reportportal/auth/permissions/ReportPortalPermissionEvaluator.java +++ b/src/main/java/com/epam/ta/reportportal/auth/permissions/ReportPortalPermissionEvaluator.java @@ -94,6 +94,6 @@ private void verifyPermissionIsDefined(String permissionKey) { public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission) { throw new PermissionNotDefinedException( - "Id and Class permissions are not supperted by " + this.getClass().toString()); + "Id and Class permissions are not supported by " + this.getClass()); } -} \ No newline at end of file +} diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/SecurityConfiguration.java b/src/main/java/com/epam/ta/reportportal/core/configs/SecurityConfiguration.java index 1758bddb04..755d5d429a 100644 --- a/src/main/java/com/epam/ta/reportportal/core/configs/SecurityConfiguration.java +++ b/src/main/java/com/epam/ta/reportportal/core/configs/SecurityConfiguration.java @@ -15,14 +15,16 @@ */ package com.epam.ta.reportportal.core.configs; +import com.epam.ta.reportportal.auth.JwtReportPortalUserConverter; import com.epam.ta.reportportal.auth.UserRoleHierarchy; import com.epam.ta.reportportal.auth.basic.DatabaseUserDetailsService; import com.epam.ta.reportportal.auth.permissions.PermissionEvaluatorFactoryBean; -import com.epam.ta.reportportal.core.configs.filter.ApiKeyFilter; import com.epam.ta.reportportal.core.configs.filter.JwtFilter; import com.epam.ta.reportportal.dao.ServerSettingsRepository; import com.epam.ta.reportportal.entity.ServerSettings; import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; import java.util.Optional; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; @@ -32,10 +34,14 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; +import org.springframework.security.access.AccessDecisionManager; +import org.springframework.security.access.AccessDecisionVoter; import org.springframework.security.access.PermissionEvaluator; import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler; import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler; import org.springframework.security.access.hierarchicalroles.RoleHierarchy; +import org.springframework.security.access.vote.AffirmativeBased; +import org.springframework.security.access.vote.AuthenticatedVoter; import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; @@ -44,11 +50,11 @@ import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.oauth2.jwt.JwtDecoder; import org.springframework.security.oauth2.jwt.NimbusJwtDecoder; -import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter; import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter; import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler; +import org.springframework.security.web.access.expression.WebExpressionVoter; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; -import org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter; /** * Spring's Security Configuration @@ -78,28 +84,18 @@ class SecurityConfiguration { @Autowired JwtFilter jwtFilter; - @Autowired - ApiKeyFilter apiKeyFilter; - private static final String SECRET_KEY = "secret.key"; @Bean @Profile("!unittest") - public JwtAuthenticationConverter accessTokenConverter() { - - JwtAuthenticationConverter jwtConverter = new JwtAuthenticationConverter(); - jwtConverter.setJwtGrantedAuthoritiesConverter(new JwtGrantedAuthoritiesConverter()); - jwtConverter.setPrincipalClaimName("sub"); -/* - JwtBearerTokenAuthenticationConverter jwtConverter = new JwtBearerTokenAuthenticationConverter(); - jwtConverter.setJwtGrantedAuthoritiesConverter(new JwtGrantedAuthoritiesConverter()); - - DefaultAccessTokenConverter accessTokenConverter = new DefaultAccessTokenConverter(); - DefaultUserAuthenticationConverter defaultUserAuthenticationConverter = new DefaultUserAuthenticationConverter(); - defaultUserAuthenticationConverter.setUserDetailsService(userDetailsService); - accessTokenConverter.setUserTokenConverter(defaultUserAuthenticationConverter); + public JwtReportPortalUserConverter accessTokenConverter() { + JwtReportPortalUserConverter jwtConverter = new JwtReportPortalUserConverter(userDetailsService); + JwtGrantedAuthoritiesConverter jwtGrantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter(); + jwtGrantedAuthoritiesConverter.setAuthoritiesClaimName("authorities"); + jwtGrantedAuthoritiesConverter.setAuthorityPrefix(""); + //jwtGrantedAuthoritiesConverter.setAuthoritiesClaimDelimiter(" "); - jwtConverter.setAccessTokenConverter(accessTokenConverter);*/ + jwtConverter.setJwtGrantedAuthoritiesConverter(jwtGrantedAuthoritiesConverter); return jwtConverter; } @@ -125,37 +121,31 @@ public SecurityFilterChain web(HttpSecurity http) throws Exception { .hasRole("USER") .anyRequest() .authenticated()) -/* .oauth2ResourceServer(resourceServer -> - resourceServer.jwt( - jwt -> jwt.jwtAuthenticationConverter(accessTokenConverter())))*/ - .userDetailsService(userDetailsService) + .oauth2ResourceServer(resourceServer -> resourceServer + .jwt(jwt -> jwt.jwtAuthenticationConverter(accessTokenConverter()))) .addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class) - .addFilterBefore(apiKeyFilter, RememberMeAuthenticationFilter.class) + .userDetailsService(userDetailsService) .csrf(AbstractHttpConfigurer::disable); return http.build(); } -/* @Bean - public TokenStore tokenStore() { - return new CombinedTokenStore(accessTokenConverter()); - }*/ - @Bean - public PermissionEvaluatorFactoryBean permissionEvaluator() { + public static PermissionEvaluatorFactoryBean permissionEvaluatorFactoryBean() { return new PermissionEvaluatorFactoryBean(); } @Bean - public PasswordEncoder passwordEncoder() { - return new BCryptPasswordEncoder(); + public static RoleHierarchy userRoleHierarchy() { + return new UserRoleHierarchy(); } @Bean - public static RoleHierarchy userRoleHierarchy() { - return new UserRoleHierarchy(); + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); } + @Bean JwtDecoder jwtDecoder() { return NimbusJwtDecoder.withSecretKey(this.getSecret()).build(); @@ -169,48 +159,24 @@ public MethodSecurityExpressionHandler createExpressionHandler() { return handler; } -/* @Configuration - @EnableResourceServer - public static class SecurityServerConfiguration extends ResourceServerConfigurerAdapter { - - - @Bean - public static PermissionEvaluatorFactoryBean permissionEvaluatorFactoryBean() { - return new PermissionEvaluatorFactoryBean(); - } - - @Bean - public static RoleHierarchy userRoleHierarchy() { - return new UserRoleHierarchy(); - }*/ - - -/* @Bean - @Primary - public DefaultTokenServices tokenServices() { - DefaultTokenServices defaultTokenServices = new DefaultTokenServices(); - defaultTokenServices.setTokenStore(tokenStore()); - defaultTokenServices.setSupportRefreshToken(true); - defaultTokenServices.setTokenEnhancer(accessTokenConverter()); - return defaultTokenServices; - } - - private DefaultWebSecurityExpressionHandler webSecurityExpressionHandler() { - OAuth2WebSecurityExpressionHandler handler = new OAuth2WebSecurityExpressionHandler(); - handler.setRoleHierarchy(userRoleHierarchy()); - handler.setPermissionEvaluator(permissionEvaluator); - return handler; - } - - private AccessDecisionManager webAccessDecisionManager() { - List> accessDecisionVoters = Lists.newArrayList(); - accessDecisionVoters.add(new AuthenticatedVoter()); - WebExpressionVoter webVoter = new WebExpressionVoter(); - webVoter.setExpressionHandler(webSecurityExpressionHandler()); - accessDecisionVoters.add(webVoter); - - return new AffirmativeBased(accessDecisionVoters); - }*/ + public DefaultWebSecurityExpressionHandler webSecurityExpressionHandler() { + DefaultWebSecurityExpressionHandler handler = new DefaultWebSecurityExpressionHandler(); + handler.setRoleHierarchy(userRoleHierarchy()); + handler.setPermissionEvaluator(permissionEvaluator); + return handler; + } + + + @Bean + public AccessDecisionManager webAccessDecisionManager() { + List> accessDecisionVoters = new ArrayList<>(); + accessDecisionVoters.add(new AuthenticatedVoter()); + WebExpressionVoter webVoter = new WebExpressionVoter(); + webVoter.setExpressionHandler(webSecurityExpressionHandler()); + accessDecisionVoters.add(webVoter); + + return new AffirmativeBased(accessDecisionVoters); + } private SecretKey getSecret() { diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/filter/ApiKeyFilter.java b/src/main/java/com/epam/ta/reportportal/core/configs/filter/ApiKeyFilter.java index 2905544921..05589281da 100644 --- a/src/main/java/com/epam/ta/reportportal/core/configs/filter/ApiKeyFilter.java +++ b/src/main/java/com/epam/ta/reportportal/core/configs/filter/ApiKeyFilter.java @@ -1,12 +1,14 @@ package com.epam.ta.reportportal.core.configs.filter; import com.epam.ta.reportportal.auth.ApiKeyUtils; +import com.epam.ta.reportportal.auth.ReportPortalClient; import com.epam.ta.reportportal.auth.util.AuthUtils; import com.epam.ta.reportportal.commons.ReportPortalUser; import com.epam.ta.reportportal.dao.ApiKeyRepository; import com.epam.ta.reportportal.dao.UserRepository; import com.epam.ta.reportportal.entity.user.ApiKey; import com.google.common.collect.Maps; +import io.micrometer.common.util.StringUtils; import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; @@ -14,20 +16,19 @@ import jakarta.xml.bind.DatatypeConverter; import java.io.IOException; import java.time.LocalDate; +import java.util.Collections; +import java.util.HashMap; +import java.util.Set; import org.apache.commons.codec.digest.DigestUtils; -import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.authentication.RememberMeAuthenticationToken; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken; import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; import org.springframework.stereotype.Component; import org.springframework.web.filter.OncePerRequestFilter; -@Component -public class ApiKeyFilter extends OncePerRequestFilter { +public class ApiKeyFilter { @Autowired private ApiKeyRepository apiKeyRepository; @@ -39,35 +40,52 @@ public class ApiKeyFilter extends OncePerRequestFilter { private UserDetailsService userDetailsService; - @Override + //@Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { - String tokenValue = request.getHeader("apiKey"); - if (tokenValue != null) { - if (ApiKeyUtils.validateToken(tokenValue)) { - RememberMeAuthenticationToken authToken = new RememberMeAuthenticationToken(tokenValue, - userDetailsService, - null - ); - authToken.setDetails( - new WebAuthenticationDetailsSource().buildDetails(request) - ); - SecurityContextHolder.getContext().setAuthentication(authToken); + String apiToken = request.getHeader("apiKey"); + if (StringUtils.isNotEmpty(apiToken)) { + String hashedKey = DatatypeConverter.printHexBinary(DigestUtils.sha3_256(apiToken)); + ApiKey apiKey = apiKeyRepository.findByHash(hashedKey); + + if (ApiKeyUtils.validateToken(apiToken) && apiKeyRepository.findByHash(hashedKey) != null) { + userRepository.findReportPortalUser(apiKey.getUserId()) + .filter(ReportPortalUser::isEnabled) + .map(user -> { + LocalDate today = LocalDate.now(); + if (apiKey.getLastUsedAt() == null || !apiKey.getLastUsedAt().equals(today)) { + apiKeyRepository.updateLastUsedAt(apiKey.getId(), hashedKey, today); + } + return user; + }) + .map(this::getUserWithAuthorities) + .ifPresent(a -> authenticate(request, a)); - String hashedKey = DatatypeConverter.printHexBinary(DigestUtils.sha3_256(tokenValue)); - ApiKey apiKey = apiKeyRepository.findByHash(hashedKey); - if (apiKey != null) { - LocalDate today = LocalDate.now(); - if (apiKey.getLastUsedAt() == null || !apiKey.getLastUsedAt().equals(today)) { - apiKeyRepository.updateLastUsedAt(apiKey.getId(), hashedKey, today); - } - } } } filterChain.doFilter(request, response); } + private void authenticate(HttpServletRequest request, ReportPortalUser user ) { +/* HashMap requestParameters = new HashMap<>(); + request.put("username", user.getUsername()); + requestParameters.put("client_id", ReportPortalClient.api.name()); + + Set scopes = Collections.singleton(ReportPortalClient.api.name());*/ + + UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken( + userDetailsService, + null, + user.getAuthorities() + ); + authToken.setDetails( + new WebAuthenticationDetailsSource().buildDetails(request) + ); + SecurityContextHolder.getContext().setAuthentication(authToken); + + } + private ReportPortalUser getUserWithAuthorities(ReportPortalUser user) { return ReportPortalUser.userBuilder().withUserName(user.getUsername()) .withPassword(user.getPassword()) diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/filter/JwtFilter.java b/src/main/java/com/epam/ta/reportportal/core/configs/filter/JwtFilter.java index 34636844f8..c49c56348e 100644 --- a/src/main/java/com/epam/ta/reportportal/core/configs/filter/JwtFilter.java +++ b/src/main/java/com/epam/ta/reportportal/core/configs/filter/JwtFilter.java @@ -2,17 +2,21 @@ import static org.apache.http.HttpHeaders.AUTHORIZATION; +import com.epam.reportportal.rules.commons.validation.BusinessRule; +import com.epam.reportportal.rules.exception.ErrorType; import com.epam.ta.reportportal.auth.JwtService; import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; +import org.apache.commons.lang3.BooleanUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.oauth2.jwt.Jwt; -import org.springframework.security.oauth2.jwt.JwtDecoder; -import org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthentication; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; import org.springframework.stereotype.Component; import org.springframework.web.filter.OncePerRequestFilter; @@ -23,37 +27,39 @@ public class JwtFilter extends OncePerRequestFilter { private JwtService jwtService; @Autowired - JwtDecoder jwtDecoder; + private UserDetailsService userDetailsService; + @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { - System.out.println("asd"); + String authHeader = request.getHeader(AUTHORIZATION); String token = null; String username = null; + if (authHeader != null && authHeader.startsWith("Bearer")) { token = authHeader.substring(7); username = jwtService.extractUserName(token); - Jwt jwt = jwtDecoder.decode(token); } - if (username != null && SecurityContextHolder.getContext().getAuthentication() != null) { + if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) { + BusinessRule.expect(jwtService.isValid(token), BooleanUtils::isTrue) + .verify(ErrorType.FORBIDDEN_OPERATION, "User token expired"); - // SecurityContextHolder.getContext().setAuthentication(new BearerTokenAuthentication()); - } + UserDetails userDetails = userDetailsService.loadUserByUsername(username); + UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken( + userDetails, + null, + userDetails.getAuthorities() + ); + authToken.setDetails( + new WebAuthenticationDetailsSource().buildDetails(request) + ); -/* - public BearerTokenAuthentication(OAuth2AuthenticatedPrincipal principal, OAuth2AccessToken - credentials, Collection authorities) { - super(credentials, principal, credentials, authorities); - Assert.isTrue(credentials.getTokenType() == TokenType.BEARER, "credentials must be a bearer token"); - this.attributes = Collections.unmodifiableMap(new LinkedHashMap(principal.getAttributes())); - this.setAuthenticated(true); + SecurityContextHolder.getContext().setAuthentication(authToken); } -*/ - //request.getHeader() filterChain.doFilter(request, response); } } diff --git a/src/main/java/com/epam/ta/reportportal/ws/controller/IntegrationController.java b/src/main/java/com/epam/ta/reportportal/ws/controller/IntegrationController.java index f912050401..f9043dfadc 100644 --- a/src/main/java/com/epam/ta/reportportal/ws/controller/IntegrationController.java +++ b/src/main/java/com/epam/ta/reportportal/ws/controller/IntegrationController.java @@ -80,7 +80,7 @@ public IntegrationController(ProjectExtractor projectExtractor, } @Transactional(readOnly = true) - @GetMapping("/global/all") + @GetMapping({"/global/all", "/global/all/"}) // TODO: fix on UI side and remove the second one @ResponseStatus(HttpStatus.OK) @Operation(summary = "Get available global integrations") public List getGlobalIntegrations( diff --git a/src/main/java/com/epam/ta/reportportal/ws/controller/ProjectController.java b/src/main/java/com/epam/ta/reportportal/ws/controller/ProjectController.java index 427a435475..43ba1f6416 100644 --- a/src/main/java/com/epam/ta/reportportal/ws/controller/ProjectController.java +++ b/src/main/java/com/epam/ta/reportportal/ws/controller/ProjectController.java @@ -17,7 +17,6 @@ package com.epam.ta.reportportal.ws.controller; import static com.epam.ta.reportportal.auth.permissions.Permissions.ADMIN_ONLY; -import static com.epam.ta.reportportal.auth.permissions.Permissions.ALLOWED_TO_EDIT_USER; import static com.epam.ta.reportportal.auth.permissions.Permissions.ASSIGNED_TO_PROJECT; import static com.epam.ta.reportportal.auth.permissions.Permissions.NOT_CUSTOMER; import static com.epam.ta.reportportal.auth.permissions.Permissions.PROJECT_MANAGER; @@ -304,7 +303,7 @@ public OperationCompletionRS removeUserPreference(@PathVariable String projectNa } @Transactional(readOnly = true) - @GetMapping("/{projectName}/preference") + @GetMapping({"/{projectName}/preference", "/{projectName}/preference/"}) @ResponseStatus(HttpStatus.OK) @Operation(summary = "Load logged-in user preferences", description = "Only for logged-in user") public PreferenceResource getUserPreference(@PathVariable String projectName, diff --git a/src/main/java/com/epam/ta/reportportal/ws/controller/UserController.java b/src/main/java/com/epam/ta/reportportal/ws/controller/UserController.java index 014cccd8d1..de16f4bfe5 100644 --- a/src/main/java/com/epam/ta/reportportal/ws/controller/UserController.java +++ b/src/main/java/com/epam/ta/reportportal/ws/controller/UserController.java @@ -76,6 +76,7 @@ import org.springframework.data.domain.Pageable; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.security.core.userdetails.UserDetails; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.DeleteMapping; @@ -194,8 +195,8 @@ public UserResource getUser(@PathVariable String login, @Transactional(readOnly = true) @GetMapping(value = { "", "/" }) @Operation(summary = "Return information about current logged-in user") - public UserResource getMyself(@AuthenticationPrincipal ReportPortalUser currentUser) { - return getUserHandler.getUser(currentUser); + public UserResource getMyself(@AuthenticationPrincipal UserDetails currentUser) { + return getUserHandler.getUser((ReportPortalUser) currentUser); } @Transactional(readOnly = true) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 6873e0dffd..2fc46a1fce 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -38,7 +38,7 @@ com.ta.reportportal.job.clean.bids.cron=PT1H spring.jooq.sql-dialect=POSTGRES -datastore.path=\${rp.binarystore.path:/home/siarhei_hrabko/IdeaProjects/service-api/data} +datastore.path=\${rp.binarystore.path:/data/storage} datastore.thumbnail.attachment.width=\${rp.binarystore.thumbnail.attachment.width:80} datastore.thumbnail.attachment.height=\${rp.binarystore.thumbnail.attachment.height:60} datastore.thumbnail.avatar.width=\${rp.binarystore.thumbnail.avatar.width:40} @@ -55,10 +55,9 @@ datastore.region=us-west-1 # Metrics management.endpoints.web.exposure.include=prometheus, metrics, info, health -management.metrics.web.server.request.autotime.enabled=true -management.metrics.export.prometheus.enabled=true -management.metrics.export.prometheus.step=5s -management.metrics.tags.version=${version} +management.prometheus.metrics.export.enabled=true +management.prometheus.metrics.export.step=5s +management.metrics.tags.version=\${version} management.metrics.tags.application=api # Demo instance From 183b655577858f4dcb01f737d6ad60d9033db847 Mon Sep 17 00:00:00 2001 From: siarhei_hrabko Date: Tue, 7 Jan 2025 19:10:22 +0300 Subject: [PATCH 5/7] EPMRPP-96333 migrate to Spring Boot 3 --- build.gradle | 7 +- .../core/configs/SecurityConfiguration.java | 1 + .../core/configs/filter/JwtFilter.java | 2 +- .../reportportal/util/MultipartFileUtils.java | 1 - .../com/epam/ta/reportportal/TestConfig.java | 35 +++++--- .../ta/reportportal/auth/OAuthHelper.java | 80 +++++-------------- .../epam/ta/reportportal/ws/BaseMvcTest.java | 2 +- .../ws/controller/LaunchControllerTest.java | 2 +- .../ProjectSettingsControllerTest.java | 8 +- src/test/resources/application-unittest.yaml | 5 +- 10 files changed, 60 insertions(+), 83 deletions(-) diff --git a/build.gradle b/build.gradle index b93ee9358a..2178234a85 100644 --- a/build.gradle +++ b/build.gradle @@ -107,10 +107,7 @@ dependencies { implementation 'com.sun.mail:jakarta.mail:2.0.1' implementation 'xerces:xercesImpl:2.12.2' - implementation 'com.lowagie:itext:4.2.2' - // Fix CVE-2021-43113 in com.lowagie:itext:4.2.2 implementation 'com.itextpdf:itextpdf:5.5.13.4' - // Fix CVE-2020-15522 in com.lowagie:itext:2.1.7.js7 implementation 'org.bouncycastle:bcprov-jdk18on:1.78.1' // JasperReport's export to XLS uses Apache POI implementation 'org.apache.poi:poi:4.1.2' @@ -143,6 +140,10 @@ dependencies { implementation 'org.springframework:spring-web' implementation 'org.springframework:spring-test' testImplementation 'org.flywaydb.flyway-test-extensions:flyway-spring-test:10.0.0' + + testImplementation 'io.jsonwebtoken:jjwt-api:0.12.5' + testImplementation 'io.jsonwebtoken:jjwt-impl:0.12.5' + testImplementation 'io.jsonwebtoken:jjwt-jackson:0.12.5' } processResources { diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/SecurityConfiguration.java b/src/main/java/com/epam/ta/reportportal/core/configs/SecurityConfiguration.java index 755d5d429a..416a3f039f 100644 --- a/src/main/java/com/epam/ta/reportportal/core/configs/SecurityConfiguration.java +++ b/src/main/java/com/epam/ta/reportportal/core/configs/SecurityConfiguration.java @@ -147,6 +147,7 @@ public PasswordEncoder passwordEncoder() { @Bean + @Profile("!unittest") JwtDecoder jwtDecoder() { return NimbusJwtDecoder.withSecretKey(this.getSecret()).build(); } diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/filter/JwtFilter.java b/src/main/java/com/epam/ta/reportportal/core/configs/filter/JwtFilter.java index c49c56348e..400365350d 100644 --- a/src/main/java/com/epam/ta/reportportal/core/configs/filter/JwtFilter.java +++ b/src/main/java/com/epam/ta/reportportal/core/configs/filter/JwtFilter.java @@ -38,7 +38,7 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse String token = null; String username = null; - if (authHeader != null && authHeader.startsWith("Bearer")) { + if (authHeader != null && authHeader.toLowerCase().startsWith("bearer")) { token = authHeader.substring(7); username = jwtService.extractUserName(token); } diff --git a/src/main/java/com/epam/ta/reportportal/util/MultipartFileUtils.java b/src/main/java/com/epam/ta/reportportal/util/MultipartFileUtils.java index 5c030cd0ad..d241fa7ddb 100644 --- a/src/main/java/com/epam/ta/reportportal/util/MultipartFileUtils.java +++ b/src/main/java/com/epam/ta/reportportal/util/MultipartFileUtils.java @@ -16,7 +16,6 @@ package com.epam.ta.reportportal.util; -import java.io.FileInputStream; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.disk.DiskFileItem; import org.apache.commons.io.IOUtils; diff --git a/src/test/java/com/epam/ta/reportportal/TestConfig.java b/src/test/java/com/epam/ta/reportportal/TestConfig.java index 7d9d76e6df..e03eef49c3 100644 --- a/src/test/java/com/epam/ta/reportportal/TestConfig.java +++ b/src/test/java/com/epam/ta/reportportal/TestConfig.java @@ -16,6 +16,7 @@ package com.epam.ta.reportportal; +import com.epam.ta.reportportal.auth.JwtReportPortalUserConverter; import com.epam.ta.reportportal.auth.basic.DatabaseUserDetailsService; import com.epam.ta.reportportal.core.analyzer.auto.client.RabbitMqManagementClient; import com.epam.ta.reportportal.core.analyzer.auto.client.impl.RabbitMqManagementClientTemplate; @@ -24,6 +25,8 @@ import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import com.rabbitmq.http.client.Client; +import io.jsonwebtoken.Jwts.SIG; +import javax.crypto.SecretKey; import org.springframework.amqp.core.AmqpAdmin; import org.springframework.amqp.rabbit.connection.ConnectionFactory; import org.springframework.amqp.rabbit.core.RabbitTemplate; @@ -39,10 +42,9 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.FilterType; import org.springframework.context.annotation.Profile; -import org.springframework.security.oauth2.provider.token.DefaultAccessTokenConverter; -import org.springframework.security.oauth2.provider.token.DefaultUserAuthenticationConverter; -import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter; -import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter; +import org.springframework.security.oauth2.jwt.JwtDecoder; +import org.springframework.security.oauth2.jwt.NimbusJwtDecoder; +import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter; /** * @author Ihar Kahadouski @@ -58,6 +60,8 @@ @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = ApplicationContextAwareFactoryBeanTest.TestConfig.class)}) public class TestConfig { + public final static SecretKey TEST_SECRET = SIG.HS256.key().build(); + @MockBean protected Client rabbitClient; @@ -90,20 +94,25 @@ protected RabbitMqManagementClient managementTemplate() { @Bean @Profile("unittest") - public JwtAccessTokenConverter accessTokenConverter() { - JwtAuthenticationConverter jwtConverter = new JwtAuthenticationConverter(); - jwtConverter.setSigningKey("123"); - - DefaultAccessTokenConverter accessTokenConverter = new DefaultAccessTokenConverter(); - DefaultUserAuthenticationConverter defaultUserAuthenticationConverter = new DefaultUserAuthenticationConverter(); - defaultUserAuthenticationConverter.setUserDetailsService(userDetailsService); - accessTokenConverter.setUserTokenConverter(defaultUserAuthenticationConverter); + public JwtReportPortalUserConverter accessTokenConverter() { + JwtReportPortalUserConverter jwtConverter = new JwtReportPortalUserConverter( + userDetailsService); + JwtGrantedAuthoritiesConverter jwtGrantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter(); + jwtGrantedAuthoritiesConverter.setAuthoritiesClaimName("authorities"); + jwtGrantedAuthoritiesConverter.setAuthorityPrefix(""); + //jwtGrantedAuthoritiesConverter.setAuthoritiesClaimDelimiter(" "); - jwtConverter.setAccessTokenConverter(accessTokenConverter); + jwtConverter.setJwtGrantedAuthoritiesConverter(jwtGrantedAuthoritiesConverter); return jwtConverter; } + @Bean + @Profile("unittest") + JwtDecoder jwtDecoder() { + return NimbusJwtDecoder.withSecretKey(TEST_SECRET).build(); + } + @Bean public ObjectMapper testObjectMapper() { ObjectMapper objectMapper = new ObjectMapper(); diff --git a/src/test/java/com/epam/ta/reportportal/auth/OAuthHelper.java b/src/test/java/com/epam/ta/reportportal/auth/OAuthHelper.java index ba1141519a..3c4ee03bb1 100644 --- a/src/test/java/com/epam/ta/reportportal/auth/OAuthHelper.java +++ b/src/test/java/com/epam/ta/reportportal/auth/OAuthHelper.java @@ -16,25 +16,15 @@ package com.epam.ta.reportportal.auth; +import static com.epam.ta.reportportal.TestConfig.TEST_SECRET; + import com.epam.ta.reportportal.entity.user.UserRole; -import com.nimbusds.jwt.JWTClaimsSet; +import io.jsonwebtoken.Jwts; +import java.time.Instant; +import java.time.temporal.ChronoUnit; import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; import java.util.Date; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; import java.util.stream.Collectors; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.core.userdetails.User; -import org.springframework.security.oauth2.common.OAuth2AccessToken; -import org.springframework.security.oauth2.provider.OAuth2Authentication; -import org.springframework.security.oauth2.provider.OAuth2Request; -import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices; import org.springframework.stereotype.Component; /** @@ -43,9 +33,6 @@ @Component public class OAuthHelper { - @Autowired - private AuthorizationServerTokenServices tokenService; - private String defaultToken; private String superadminToken; @@ -54,59 +41,36 @@ public class OAuthHelper { public String getDefaultToken() { return defaultToken == null ? defaultToken = createAccessToken("default", "1q2w3e", - UserRole.USER).getValue() : defaultToken; + UserRole.USER) : defaultToken; } public String getSuperadminToken() { return superadminToken == null ? - superadminToken = createAccessToken("superadmin", "erebus", - UserRole.ADMINISTRATOR).getValue() : - superadminToken; + superadminToken = createAccessToken("superadmin", "erebus", UserRole.ADMINISTRATOR) + : superadminToken; } public String getCustomerToken() { return customerToken == null ? - customerToken = createAccessToken("default_customer", "erebus", UserRole.USER).getValue() : + customerToken = createAccessToken("default_customer", "erebus", UserRole.USER) : customerToken; } - private AccessToken createAccessToken(String username, String password, UserRole... roles) { - - var claimsSet = new JWTClaimsSet.Builder() - .expirationTime(new Date(new Date().getTime() + 60 * 1000)) - .build(); - var signedJWT = new SignedJWT(new JWSHeader.Builder(JWSAlgorithm.RS256) - .keyID(rsaKey.getKeyID()).build(), claimsSet); - signedJWT.sign(signer); - return signedJWT.serialize(); - - Collection authorities = Arrays.stream(roles) - .map(it -> new SimpleGrantedAuthority(it.getAuthority())) + private String createAccessToken(String username, String password, + UserRole... roles) { + var authorities = Arrays.stream(roles) + .map(role -> "ROLE_" + role) .collect(Collectors.toList()); - Set scopes = Collections.singleton("ui"); - - Map requestParameters = new HashMap<>(); - requestParameters.put("password", password); - requestParameters.put("grand_type", "password"); - requestParameters.put("username", username); - + return Jwts.builder() + .subject(username) + .claim("user_name", username) + .claim("scope", "ui") + .claim("authorities", authorities) + .issuedAt(new Date()) + .expiration(new Date(Instant.now().plus(1, ChronoUnit.DAYS).toEpochMilli())) + .signWith(TEST_SECRET) + .compact(); - OAuth2Request oAuth2Request = new OAuth2Request( - requestParameters, - "ui", - authorities, - true, - scopes, - Collections.emptySet(), - null, - Collections.emptySet(), - Collections.emptyMap() - ); - User userPrincipal = new User(username, password, true, true, true, true, authorities); - UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken( - userPrincipal, null, authorities); - OAuth2Authentication auth = new OAuth2Authentication(oAuth2Request, authenticationToken); - return tokenService.createAccessToken(auth); } } diff --git a/src/test/java/com/epam/ta/reportportal/ws/BaseMvcTest.java b/src/test/java/com/epam/ta/reportportal/ws/BaseMvcTest.java index 6f51bab15d..5a417dfd7f 100644 --- a/src/test/java/com/epam/ta/reportportal/ws/BaseMvcTest.java +++ b/src/test/java/com/epam/ta/reportportal/ws/BaseMvcTest.java @@ -92,7 +92,7 @@ public abstract class BaseMvcTest { @Mock protected EmailService emailService; - @FlywayTest + @FlywayTest(invokeCleanDB = false) @BeforeAll public static void before() { } diff --git a/src/test/java/com/epam/ta/reportportal/ws/controller/LaunchControllerTest.java b/src/test/java/com/epam/ta/reportportal/ws/controller/LaunchControllerTest.java index fdc29c235b..6f4448a2a8 100644 --- a/src/test/java/com/epam/ta/reportportal/ws/controller/LaunchControllerTest.java +++ b/src/test/java/com/epam/ta/reportportal/ws/controller/LaunchControllerTest.java @@ -90,7 +90,7 @@ void happyCreateLaunch() throws Exception { startLaunchRQ.setAttributes(Sets.newHashSet(new ItemAttributesRQ("key", "value"))); mockMvc.perform( - post(DEFAULT_PROJECT_BASE_URL + "/launch/").with(token(oAuthHelper.getDefaultToken())) + post(DEFAULT_PROJECT_BASE_URL + "/launch").with(token(oAuthHelper.getDefaultToken())) .content(objectMapper.writeValueAsBytes(startLaunchRQ)).contentType(APPLICATION_JSON)) .andExpect(status().isCreated()); } diff --git a/src/test/java/com/epam/ta/reportportal/ws/controller/ProjectSettingsControllerTest.java b/src/test/java/com/epam/ta/reportportal/ws/controller/ProjectSettingsControllerTest.java index 7f1ab81f57..b76df0891e 100644 --- a/src/test/java/com/epam/ta/reportportal/ws/controller/ProjectSettingsControllerTest.java +++ b/src/test/java/com/epam/ta/reportportal/ws/controller/ProjectSettingsControllerTest.java @@ -66,7 +66,7 @@ class ProjectSettingsControllerTest extends BaseMvcTest { @Autowired private SenderCaseRepository senderCaseRepository; - private static final String NOTIFICATION_URL = "/settings/notification/"; + private static final String NOTIFICATION_URL = "/settings/notification"; @Test void createSubType() throws Exception { @@ -269,12 +269,12 @@ void updateNotification() throws Exception { void deleteNotification() throws Exception { Long id = 1L; - mockMvc.perform(delete(DEFAULT_PROJECT_BASE_URL + NOTIFICATION_URL + id).with( - token(oAuthHelper.getDefaultToken()))).andExpect(status().isOk()); + mockMvc.perform(delete(DEFAULT_PROJECT_BASE_URL + NOTIFICATION_URL + "/" + id) + .with(token(oAuthHelper.getDefaultToken()))).andExpect(status().isOk()); List senderCases = senderCaseRepository.findAll(); assertFalse(senderCases.stream().anyMatch(s -> s.getId().equals(id))); } -} \ No newline at end of file +} diff --git a/src/test/resources/application-unittest.yaml b/src/test/resources/application-unittest.yaml index 2b894b002a..c024391fa8 100644 --- a/src/test/resources/application-unittest.yaml +++ b/src/test/resources/application-unittest.yaml @@ -11,4 +11,7 @@ embedded: datasource: dir: ${java.io.tmpdir}/reportportal/embedded-postgres clean: true - port: 0 \ No newline at end of file + port: 0 +spring: + flyway: + clean-disabled: false From 6edc00c3ae96277720729edc6229492de89ed153 Mon Sep 17 00:00:00 2001 From: siarhei_hrabko Date: Fri, 10 Jan 2025 10:34:29 +0300 Subject: [PATCH 6/7] EPMRPP-96333 migrate to Spring Boot 3 --- build.gradle | 3 +- .../epam/ta/reportportal/auth/JwtService.java | 27 ----- .../reportportal/core/configs/MvcConfig.java | 20 ++-- .../core/configs/filter/ApiKeyFilter.java | 96 ------------------ .../core/configs/filter/JwtFilter.java | 65 ------------ .../ApiKeyAuthenticationProvider.java | 84 ++++++++++++++++ .../ApiKeyReportPortalUserConverter.java | 49 ++++++++++ .../JwtCustomAuthenticationProvider.java | 98 +++++++++++++++++++ .../JwtReportPortalUserConverter.java | 2 +- .../{ => security}/SecurityConfiguration.java | 39 +++++--- .../CustomAuthenticationManagerResolver.java | 83 ++++++++++++++++ .../DeleteProjectSettingsHandlerImpl.java | 4 +- .../reportportal/util/MultipartFileUtils.java | 46 ++++----- .../ws/converter/builders/UserBuilder.java | 2 +- .../com/epam/ta/reportportal/TestConfig.java | 2 +- .../util/MultipartFileUtilsTest.java | 2 +- .../controller/LaunchAsyncControllerTest.java | 21 ++-- .../ws/controller/UserControllerTest.java | 1 + 18 files changed, 394 insertions(+), 250 deletions(-) delete mode 100644 src/main/java/com/epam/ta/reportportal/auth/JwtService.java delete mode 100644 src/main/java/com/epam/ta/reportportal/core/configs/filter/ApiKeyFilter.java delete mode 100644 src/main/java/com/epam/ta/reportportal/core/configs/filter/JwtFilter.java create mode 100644 src/main/java/com/epam/ta/reportportal/core/configs/security/ApiKeyAuthenticationProvider.java create mode 100644 src/main/java/com/epam/ta/reportportal/core/configs/security/ApiKeyReportPortalUserConverter.java create mode 100644 src/main/java/com/epam/ta/reportportal/core/configs/security/JwtCustomAuthenticationProvider.java rename src/main/java/com/epam/ta/reportportal/{auth => core/configs/security}/JwtReportPortalUserConverter.java (97%) rename src/main/java/com/epam/ta/reportportal/core/configs/{ => security}/SecurityConfiguration.java (88%) create mode 100644 src/main/java/com/epam/ta/reportportal/core/configs/utils/CustomAuthenticationManagerResolver.java diff --git a/build.gradle b/build.gradle index 2178234a85..6dcabf15c5 100644 --- a/build.gradle +++ b/build.gradle @@ -68,10 +68,11 @@ dependencies { implementation 'com.epam.reportportal:commons' implementation 'com.epam.reportportal:plugin-api' } else { - implementation 'com.github.reportportal:commons-dao:b13f8d3' + implementation 'com.github.reportportal:commons-dao:184a749' implementation 'com.github.reportportal:commons:6729eb7' implementation 'com.github.reportportal:plugin-api:e37b0fd' } + implementation 'jakarta.servlet:jakarta.servlet-api:6.1.0' implementation 'org.springframework.boot:spring-boot-starter-aop' implementation 'org.springframework.boot:spring-boot-starter-web' diff --git a/src/main/java/com/epam/ta/reportportal/auth/JwtService.java b/src/main/java/com/epam/ta/reportportal/auth/JwtService.java deleted file mode 100644 index 44d280fb12..0000000000 --- a/src/main/java/com/epam/ta/reportportal/auth/JwtService.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.epam.ta.reportportal.auth; - -import static java.util.Objects.requireNonNull; - -import java.time.Instant; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.oauth2.jwt.JwtDecoder; -import org.springframework.stereotype.Service; - -@Service -public class JwtService { - - @Autowired - private JwtDecoder jwtDecoder; - - public String extractUserName(String token) { - return (String) jwtDecoder.decode(token) - .getClaims() - .get("user_name"); - } - - public boolean isValid(String token) { - return Instant.now() - .isBefore(requireNonNull(jwtDecoder.decode(token).getExpiresAt())); - } - -} diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/MvcConfig.java b/src/main/java/com/epam/ta/reportportal/core/configs/MvcConfig.java index be5c19b024..213e166eb2 100644 --- a/src/main/java/com/epam/ta/reportportal/core/configs/MvcConfig.java +++ b/src/main/java/com/epam/ta/reportportal/core/configs/MvcConfig.java @@ -17,6 +17,9 @@ package com.epam.ta.reportportal.core.configs; import static com.google.common.base.Strings.isNullOrEmpty; +import static org.apache.commons.io.FileUtils.ONE_GB; +import static org.apache.commons.io.FileUtils.ONE_KB; +import static org.apache.commons.io.FileUtils.ONE_MB; import com.epam.reportportal.rules.commons.ExceptionMappings; import com.epam.reportportal.rules.commons.exception.forwarding.ClientResponseForwardingExceptionHandler; @@ -35,7 +38,6 @@ import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.List; -import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.http.HttpMessageConverters; import org.springframework.boot.context.properties.ConfigurationProperties; @@ -54,7 +56,6 @@ import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.multipart.MultipartException; import org.springframework.web.multipart.MultipartHttpServletRequest; -import org.springframework.web.multipart.MultipartResolver; import org.springframework.web.multipart.support.MultipartFilter; import org.springframework.web.multipart.support.StandardMultipartHttpServletRequest; import org.springframework.web.multipart.support.StandardServletMultipartResolver; @@ -64,6 +65,7 @@ import org.springframework.web.servlet.config.annotation.PathMatchConfigurer; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; /** * Class-based Spring MVC Configuration @@ -224,16 +226,16 @@ public void cleanupMultipart(MultipartHttpServletRequest request) { //level and handle exceptions in proper way. Fixes reportportal/reportportal#19 resolver.setResolveLazily(true); -/* commonsMultipartResolver.setMaxUploadSize(multipartConfig.maxUploadSize); - commonsMultipartResolver.setMaxUploadSizePerFile(multipartConfig.maxFileSize);*/ + multipartConfig.setMaxUploadSize(String.valueOf(multipartConfig.maxUploadSize)); + //resolver.setMaxUploadSizePerFile(multipartConfig.maxFileSize); return resolver; } @ConfigurationProperties("rp.upload") public static class MultipartConfig { - long maxUploadSize = 128L * 1024L * 1024L; - long maxFileSize = 128L * 1024L * 1024L; + long maxUploadSize = 128 * ONE_MB; + long maxFileSize = 128 * ONE_MB; public void setMaxUploadSize(String maxUploadSize) { this.maxUploadSize = parseSize(maxUploadSize); @@ -247,13 +249,13 @@ private long parseSize(String size) { Preconditions.checkArgument(!isNullOrEmpty(size), "Size must not be empty"); size = size.toUpperCase(); if (size.endsWith("KB")) { - return Long.parseLong(size.substring(0, size.length() - 2)) * 1024; + return Long.parseLong(size.substring(0, size.length() - 2)) * ONE_KB; } if (size.endsWith("MB")) { - return Long.parseLong(size.substring(0, size.length() - 2)) * 1024 * 1024; + return Long.parseLong(size.substring(0, size.length() - 2)) * ONE_MB; } if (size.endsWith("GB")) { - return Long.parseLong(size.substring(0, size.length() - 2)) * 1024 * 1024 * 1024; + return Long.parseLong(size.substring(0, size.length() - 2)) * ONE_GB; } return Long.parseLong(size); } diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/filter/ApiKeyFilter.java b/src/main/java/com/epam/ta/reportportal/core/configs/filter/ApiKeyFilter.java deleted file mode 100644 index 05589281da..0000000000 --- a/src/main/java/com/epam/ta/reportportal/core/configs/filter/ApiKeyFilter.java +++ /dev/null @@ -1,96 +0,0 @@ -package com.epam.ta.reportportal.core.configs.filter; - -import com.epam.ta.reportportal.auth.ApiKeyUtils; -import com.epam.ta.reportportal.auth.ReportPortalClient; -import com.epam.ta.reportportal.auth.util.AuthUtils; -import com.epam.ta.reportportal.commons.ReportPortalUser; -import com.epam.ta.reportportal.dao.ApiKeyRepository; -import com.epam.ta.reportportal.dao.UserRepository; -import com.epam.ta.reportportal.entity.user.ApiKey; -import com.google.common.collect.Maps; -import io.micrometer.common.util.StringUtils; -import jakarta.servlet.FilterChain; -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import jakarta.xml.bind.DatatypeConverter; -import java.io.IOException; -import java.time.LocalDate; -import java.util.Collections; -import java.util.HashMap; -import java.util.Set; -import org.apache.commons.codec.digest.DigestUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; -import org.springframework.stereotype.Component; -import org.springframework.web.filter.OncePerRequestFilter; - -public class ApiKeyFilter { - - @Autowired - private ApiKeyRepository apiKeyRepository; - - @Autowired - private UserRepository userRepository; - - @Autowired - private UserDetailsService userDetailsService; - - - //@Override - protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, - FilterChain filterChain) throws ServletException, IOException { - String apiToken = request.getHeader("apiKey"); - if (StringUtils.isNotEmpty(apiToken)) { - String hashedKey = DatatypeConverter.printHexBinary(DigestUtils.sha3_256(apiToken)); - ApiKey apiKey = apiKeyRepository.findByHash(hashedKey); - - if (ApiKeyUtils.validateToken(apiToken) && apiKeyRepository.findByHash(hashedKey) != null) { - userRepository.findReportPortalUser(apiKey.getUserId()) - .filter(ReportPortalUser::isEnabled) - .map(user -> { - LocalDate today = LocalDate.now(); - if (apiKey.getLastUsedAt() == null || !apiKey.getLastUsedAt().equals(today)) { - apiKeyRepository.updateLastUsedAt(apiKey.getId(), hashedKey, today); - } - return user; - }) - .map(this::getUserWithAuthorities) - .ifPresent(a -> authenticate(request, a)); - - } - } - - filterChain.doFilter(request, response); - } - - private void authenticate(HttpServletRequest request, ReportPortalUser user ) { -/* HashMap requestParameters = new HashMap<>(); - request.put("username", user.getUsername()); - requestParameters.put("client_id", ReportPortalClient.api.name()); - - Set scopes = Collections.singleton(ReportPortalClient.api.name());*/ - - UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken( - userDetailsService, - null, - user.getAuthorities() - ); - authToken.setDetails( - new WebAuthenticationDetailsSource().buildDetails(request) - ); - SecurityContextHolder.getContext().setAuthentication(authToken); - - } - - private ReportPortalUser getUserWithAuthorities(ReportPortalUser user) { - return ReportPortalUser.userBuilder().withUserName(user.getUsername()) - .withPassword(user.getPassword()) - .withAuthorities(AuthUtils.AS_AUTHORITIES.apply(user.getUserRole())) - .withUserId(user.getUserId()).withUserRole(user.getUserRole()) - .withProjectDetails(Maps.newHashMapWithExpectedSize(1)).withEmail(user.getEmail()).build(); - } -} diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/filter/JwtFilter.java b/src/main/java/com/epam/ta/reportportal/core/configs/filter/JwtFilter.java deleted file mode 100644 index 400365350d..0000000000 --- a/src/main/java/com/epam/ta/reportportal/core/configs/filter/JwtFilter.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.epam.ta.reportportal.core.configs.filter; - -import static org.apache.http.HttpHeaders.AUTHORIZATION; - -import com.epam.reportportal.rules.commons.validation.BusinessRule; -import com.epam.reportportal.rules.exception.ErrorType; -import com.epam.ta.reportportal.auth.JwtService; -import jakarta.servlet.FilterChain; -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import java.io.IOException; -import org.apache.commons.lang3.BooleanUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; -import org.springframework.stereotype.Component; -import org.springframework.web.filter.OncePerRequestFilter; - -@Component -public class JwtFilter extends OncePerRequestFilter { - - @Autowired - private JwtService jwtService; - - @Autowired - private UserDetailsService userDetailsService; - - - @Override - protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, - FilterChain filterChain) throws ServletException, IOException { - - String authHeader = request.getHeader(AUTHORIZATION); - String token = null; - String username = null; - - if (authHeader != null && authHeader.toLowerCase().startsWith("bearer")) { - token = authHeader.substring(7); - username = jwtService.extractUserName(token); - } - - if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) { - BusinessRule.expect(jwtService.isValid(token), BooleanUtils::isTrue) - .verify(ErrorType.FORBIDDEN_OPERATION, "User token expired"); - - UserDetails userDetails = userDetailsService.loadUserByUsername(username); - UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken( - userDetails, - null, - userDetails.getAuthorities() - ); - authToken.setDetails( - new WebAuthenticationDetailsSource().buildDetails(request) - ); - - SecurityContextHolder.getContext().setAuthentication(authToken); - } - - filterChain.doFilter(request, response); - } -} diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/security/ApiKeyAuthenticationProvider.java b/src/main/java/com/epam/ta/reportportal/core/configs/security/ApiKeyAuthenticationProvider.java new file mode 100644 index 0000000000..24679bd016 --- /dev/null +++ b/src/main/java/com/epam/ta/reportportal/core/configs/security/ApiKeyAuthenticationProvider.java @@ -0,0 +1,84 @@ +/* + * Copyright 2025 EPAM Systems + * + * Licensed 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 com.epam.ta.reportportal.core.configs.security; + +import com.epam.ta.reportportal.auth.ApiKeyUtils; +import com.epam.ta.reportportal.commons.ReportPortalUser; +import com.epam.ta.reportportal.dao.ApiKeyRepository; +import com.epam.ta.reportportal.dao.UserRepository; +import com.epam.ta.reportportal.entity.user.ApiKey; +import jakarta.xml.bind.DatatypeConverter; +import java.time.LocalDate; +import org.apache.commons.codec.digest.DigestUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.convert.converter.Converter; +import org.springframework.security.authentication.AbstractAuthenticationToken; +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthenticationToken; +import org.springframework.stereotype.Component; + +@Component +public class ApiKeyAuthenticationProvider implements AuthenticationProvider { + + private final Log logger = LogFactory.getLog(getClass()); + private final Converter authenticationConverter = new ApiKeyReportPortalUserConverter(); + + @Autowired + private ApiKeyRepository apiKeyRepository; + + @Autowired + private UserRepository userRepository; + + + public Authentication authenticate(Authentication authentication) throws AuthenticationException { + BearerTokenAuthenticationToken bearer = (BearerTokenAuthenticationToken) authentication; + String apiToken = (String) bearer.getPrincipal(); + String hashedKey = DatatypeConverter.printHexBinary(DigestUtils.sha3_256(apiToken)); + ApiKey apiKey = apiKeyRepository.findByHash(hashedKey); + if (ApiKeyUtils.validateToken(apiToken) && apiKeyRepository.findByHash(hashedKey) != null) { + return userRepository.findReportPortalUser(apiKey.getUserId()) + .filter(ReportPortalUser::isEnabled) + .map(user -> { + LocalDate today = LocalDate.now(); + if (apiKey.getLastUsedAt() == null || !apiKey.getLastUsedAt().equals(today)) { + apiKeyRepository.updateLastUsedAt(apiKey.getId(), hashedKey, today); + } + return user; + }) + .map(authenticationConverter::convert) + .map(authToken -> { + if (authToken.getDetails() == null) { + authToken.setDetails(bearer.getDetails()); + } + return authToken; + }) + .orElseThrow(); + } + + return authentication; + } + + @Override + public boolean supports(Class authentication) { + return BearerTokenAuthenticationToken.class.isAssignableFrom(authentication); + } + +} diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/security/ApiKeyReportPortalUserConverter.java b/src/main/java/com/epam/ta/reportportal/core/configs/security/ApiKeyReportPortalUserConverter.java new file mode 100644 index 0000000000..578cff4d4b --- /dev/null +++ b/src/main/java/com/epam/ta/reportportal/core/configs/security/ApiKeyReportPortalUserConverter.java @@ -0,0 +1,49 @@ +/* + * Copyright 2025 EPAM Systems + * + * Licensed 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 com.epam.ta.reportportal.core.configs.security; + +import com.epam.ta.reportportal.auth.util.AuthUtils; +import com.epam.ta.reportportal.commons.ReportPortalUser; +import com.google.common.collect.Maps; +import org.springframework.core.convert.converter.Converter; +import org.springframework.security.authentication.AbstractAuthenticationToken; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; + +public class ApiKeyReportPortalUserConverter implements + Converter { + + public ApiKeyReportPortalUserConverter() { + } + + @Override + public final AbstractAuthenticationToken convert(ReportPortalUser rpUser) { + var userWithAuthorities = ReportPortalUser.userBuilder() + .withUserName(rpUser.getUsername()) + .withPassword(rpUser.getPassword()) + .withAuthorities(AuthUtils.AS_AUTHORITIES.apply(rpUser.getUserRole())) + .withUserId(rpUser.getUserId()).withUserRole(rpUser.getUserRole()) + .withProjectDetails(Maps.newHashMapWithExpectedSize(1)).withEmail(rpUser.getEmail()) + .build(); + + return new UsernamePasswordAuthenticationToken( + userWithAuthorities, + null, + userWithAuthorities.getAuthorities()); + + } + +} diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/security/JwtCustomAuthenticationProvider.java b/src/main/java/com/epam/ta/reportportal/core/configs/security/JwtCustomAuthenticationProvider.java new file mode 100644 index 0000000000..e740f13ae8 --- /dev/null +++ b/src/main/java/com/epam/ta/reportportal/core/configs/security/JwtCustomAuthenticationProvider.java @@ -0,0 +1,98 @@ +/* + * Copyright 2025 EPAM Systems + * + * Licensed 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 com.epam.ta.reportportal.core.configs.security; + +import static java.util.Objects.requireNonNull; + +import com.epam.reportportal.rules.commons.validation.BusinessRule; +import com.epam.reportportal.rules.exception.ErrorType; +import com.epam.ta.reportportal.auth.basic.DatabaseUserDetailsService; +import java.time.Instant; +import org.apache.commons.lang3.BooleanUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.authentication.AuthenticationServiceException; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.oauth2.jwt.BadJwtException; +import org.springframework.security.oauth2.jwt.Jwt; +import org.springframework.security.oauth2.jwt.JwtDecoder; +import org.springframework.security.oauth2.jwt.JwtException; +import org.springframework.security.oauth2.server.resource.InvalidBearerTokenException; +import org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthenticationToken; +import org.springframework.util.Assert; + +public class JwtCustomAuthenticationProvider implements AuthenticationProvider { + + private final Log logger = LogFactory.getLog(getClass()); + + private final JwtDecoder jwtDecoder; + private final DatabaseUserDetailsService userDetailsService; + + public JwtCustomAuthenticationProvider(JwtDecoder jwtDecoder, + DatabaseUserDetailsService userDetailsService) { + this.userDetailsService = userDetailsService; + Assert.notNull(jwtDecoder, "jwtDecoder cannot be null"); + this.jwtDecoder = jwtDecoder; + } + + + public Authentication authenticate(Authentication authentication) throws AuthenticationException { + BearerTokenAuthenticationToken bearer = (BearerTokenAuthenticationToken) authentication; + Jwt jwt = getJwt(bearer); + String username = jwt.getClaim("user_name"); + + BusinessRule.expect(isValid(jwt), BooleanUtils::isTrue) + .verify(ErrorType.FORBIDDEN_OPERATION, "User token expired"); + + UserDetails userDetails = userDetailsService.loadUserByUsername(username); + UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken( + userDetails, + null, + userDetails.getAuthorities() + ); + authToken.setDetails(authentication.getDetails()); + + return authToken; + + } + + private Jwt getJwt(BearerTokenAuthenticationToken bearer) { + try { + return this.jwtDecoder.decode(bearer.getToken()); + } catch (BadJwtException failed) { + this.logger.debug("Failed to authenticate since the JWT was invalid"); + throw new InvalidBearerTokenException(failed.getMessage(), failed); + } catch (JwtException failed) { + throw new AuthenticationServiceException(failed.getMessage(), failed); + } + } + + @Override + public boolean supports(Class authentication) { + return BearerTokenAuthenticationToken.class.isAssignableFrom(authentication); + } + + public boolean isValid(Jwt token) { + return Instant.now() + .isBefore(requireNonNull(requireNonNull(token).getExpiresAt())); + } + +} diff --git a/src/main/java/com/epam/ta/reportportal/auth/JwtReportPortalUserConverter.java b/src/main/java/com/epam/ta/reportportal/core/configs/security/JwtReportPortalUserConverter.java similarity index 97% rename from src/main/java/com/epam/ta/reportportal/auth/JwtReportPortalUserConverter.java rename to src/main/java/com/epam/ta/reportportal/core/configs/security/JwtReportPortalUserConverter.java index b087fed492..04c96b44fb 100644 --- a/src/main/java/com/epam/ta/reportportal/auth/JwtReportPortalUserConverter.java +++ b/src/main/java/com/epam/ta/reportportal/core/configs/security/JwtReportPortalUserConverter.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.epam.ta.reportportal.auth; +package com.epam.ta.reportportal.core.configs.security; import jakarta.validation.constraints.NotNull; import java.util.Collection; diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/SecurityConfiguration.java b/src/main/java/com/epam/ta/reportportal/core/configs/security/SecurityConfiguration.java similarity index 88% rename from src/main/java/com/epam/ta/reportportal/core/configs/SecurityConfiguration.java rename to src/main/java/com/epam/ta/reportportal/core/configs/security/SecurityConfiguration.java index 416a3f039f..50a6a7c051 100644 --- a/src/main/java/com/epam/ta/reportportal/core/configs/SecurityConfiguration.java +++ b/src/main/java/com/epam/ta/reportportal/core/configs/security/SecurityConfiguration.java @@ -13,13 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.epam.ta.reportportal.core.configs; -import com.epam.ta.reportportal.auth.JwtReportPortalUserConverter; +package com.epam.ta.reportportal.core.configs.security; + import com.epam.ta.reportportal.auth.UserRoleHierarchy; import com.epam.ta.reportportal.auth.basic.DatabaseUserDetailsService; import com.epam.ta.reportportal.auth.permissions.PermissionEvaluatorFactoryBean; -import com.epam.ta.reportportal.core.configs.filter.JwtFilter; +import com.epam.ta.reportportal.core.configs.utils.CustomAuthenticationManagerResolver; import com.epam.ta.reportportal.dao.ServerSettingsRepository; import com.epam.ta.reportportal.entity.ServerSettings; import java.nio.charset.StandardCharsets; @@ -54,7 +54,6 @@ import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler; import org.springframework.security.web.access.expression.WebExpressionVoter; -import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; /** * Spring's Security Configuration @@ -82,19 +81,22 @@ class SecurityConfiguration { private RoleHierarchy roleHierarchy; @Autowired - JwtFilter jwtFilter; + private ApiKeyAuthenticationProvider apiKeyAuthenticationProvider; + + @Autowired + private JwtCustomAuthenticationProvider jwtCustomAuthenticationProvider; + private static final String SECRET_KEY = "secret.key"; @Bean @Profile("!unittest") public JwtReportPortalUserConverter accessTokenConverter() { - JwtReportPortalUserConverter jwtConverter = new JwtReportPortalUserConverter(userDetailsService); + JwtReportPortalUserConverter jwtConverter = new JwtReportPortalUserConverter( + userDetailsService); JwtGrantedAuthoritiesConverter jwtGrantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter(); jwtGrantedAuthoritiesConverter.setAuthoritiesClaimName("authorities"); jwtGrantedAuthoritiesConverter.setAuthorityPrefix(""); - //jwtGrantedAuthoritiesConverter.setAuthoritiesClaimDelimiter(" "); - jwtConverter.setJwtGrantedAuthoritiesConverter(jwtGrantedAuthoritiesConverter); return jwtConverter; @@ -121,9 +123,8 @@ public SecurityFilterChain web(HttpSecurity http) throws Exception { .hasRole("USER") .anyRequest() .authenticated()) - .oauth2ResourceServer(resourceServer -> resourceServer - .jwt(jwt -> jwt.jwtAuthenticationConverter(accessTokenConverter()))) - .addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class) + .oauth2ResourceServer(resourceServer -> + resourceServer.authenticationManagerResolver(customAuthenticationManagerResolver())) .userDetailsService(userDetailsService) .csrf(AbstractHttpConfigurer::disable); @@ -187,8 +188,22 @@ private SecretKey getSecret() { .map(ServerSettings::getValue) .orElseGet(() -> serverSettingsRepository.generateSecret())); - return new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), 0, secret.length(), "HmacSha256"); + return new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), 0, secret.length(), + "HmacSha256"); } + + + @Bean + public CustomAuthenticationManagerResolver customAuthenticationManagerResolver() { + return new CustomAuthenticationManagerResolver(apiKeyAuthenticationProvider, + jwtCustomAuthenticationProvider, jwtDecoder()); + } + + @Bean + public JwtCustomAuthenticationProvider jwtCustomAuthenticationProvider() { + return new JwtCustomAuthenticationProvider(jwtDecoder(), userDetailsService); + } + } diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/utils/CustomAuthenticationManagerResolver.java b/src/main/java/com/epam/ta/reportportal/core/configs/utils/CustomAuthenticationManagerResolver.java new file mode 100644 index 0000000000..df9c317665 --- /dev/null +++ b/src/main/java/com/epam/ta/reportportal/core/configs/utils/CustomAuthenticationManagerResolver.java @@ -0,0 +1,83 @@ +/* + * Copyright 2025 EPAM Systems + * + * Licensed 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 com.epam.ta.reportportal.core.configs.utils; + +import static org.apache.http.HttpHeaders.AUTHORIZATION; + +import com.epam.reportportal.rules.exception.ErrorType; +import com.epam.reportportal.rules.exception.ReportPortalException; +import com.epam.ta.reportportal.core.configs.security.ApiKeyAuthenticationProvider; +import com.epam.ta.reportportal.core.configs.security.JwtCustomAuthenticationProvider; +import io.micrometer.common.util.StringUtils; +import jakarta.servlet.http.HttpServletRequest; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.AuthenticationManagerResolver; +import org.springframework.security.authentication.ProviderManager; +import org.springframework.security.oauth2.jwt.JwtDecoder; +import org.springframework.stereotype.Component; + +public class CustomAuthenticationManagerResolver implements + AuthenticationManagerResolver { + + private final ApiKeyAuthenticationProvider apiKeyAuthenticationProvider; + + private final JwtCustomAuthenticationProvider jwtCustomAuthenticationProvider; + + private final JwtDecoder jwtDecoder; + + public CustomAuthenticationManagerResolver( + ApiKeyAuthenticationProvider apiKeyAuthenticationProvider, + JwtCustomAuthenticationProvider jwtCustomAuthenticationProvider, JwtDecoder jwtDecoder) { + this.apiKeyAuthenticationProvider = apiKeyAuthenticationProvider; + this.jwtCustomAuthenticationProvider = jwtCustomAuthenticationProvider; + this.jwtDecoder = jwtDecoder; + } + + @Override + public AuthenticationManager resolve(HttpServletRequest request) { + if (isJwt(request)) { + return new ProviderManager(jwtCustomAuthenticationProvider); + } else { + return new ProviderManager(apiKeyAuthenticationProvider); + } + } + + private boolean isJwt(HttpServletRequest request) { + boolean isJwt; + try { + jwtDecoder.decode(getBearerValue(request)); + isJwt = true; + } catch (Exception e) { + isJwt = false; + } + return isJwt; + } + + private static String getBearerValue(HttpServletRequest request) { + String authHeader = request.getHeader(AUTHORIZATION); + if (authHeader != null && authHeader.toLowerCase().startsWith("bearer")) { + String token = authHeader.substring(7); + if (StringUtils.isEmpty(token)) { + throw new ReportPortalException(ErrorType.BAD_REQUEST_ERROR, "Bearer token"); + } + return token; + } + throw new ReportPortalException(ErrorType.BAD_REQUEST_ERROR, "Bearer token"); + + } + +} diff --git a/src/main/java/com/epam/ta/reportportal/core/project/settings/impl/DeleteProjectSettingsHandlerImpl.java b/src/main/java/com/epam/ta/reportportal/core/project/settings/impl/DeleteProjectSettingsHandlerImpl.java index fa4f15633f..1037863dac 100644 --- a/src/main/java/com/epam/ta/reportportal/core/project/settings/impl/DeleteProjectSettingsHandlerImpl.java +++ b/src/main/java/com/epam/ta/reportportal/core/project/settings/impl/DeleteProjectSettingsHandlerImpl.java @@ -127,9 +127,9 @@ public OperationCompletionRS deleteProjectIssueSubType(String projectName, Repor project.getProjectIssueTypes().remove(type); projectRepository.save(project); - issueTypeRepository.delete(type.getIssueType()); + updateWidgets(project, type.getIssueType()); - updateWidgets(project, type.getIssueType()); + issueTypeRepository.delete(type.getIssueType()); DefectTypeDeletedEvent defectTypeDeletedEvent = new DefectTypeDeletedEvent(TO_ACTIVITY_RESOURCE.apply(type.getIssueType()), user.getUserId(), diff --git a/src/main/java/com/epam/ta/reportportal/util/MultipartFileUtils.java b/src/main/java/com/epam/ta/reportportal/util/MultipartFileUtils.java index d241fa7ddb..e9f7c30fb9 100644 --- a/src/main/java/com/epam/ta/reportportal/util/MultipartFileUtils.java +++ b/src/main/java/com/epam/ta/reportportal/util/MultipartFileUtils.java @@ -16,40 +16,36 @@ package com.epam.ta.reportportal.util; -import org.apache.commons.fileupload.FileItem; -import org.apache.commons.fileupload.disk.DiskFileItem; -import org.apache.commons.io.IOUtils; +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Objects; import org.apache.tika.Tika; import org.springframework.core.io.ClassPathResource; import org.springframework.mock.web.MockMultipartFile; import org.springframework.web.multipart.MultipartFile; -import java.io.BufferedInputStream; -import java.io.IOException; -import java.io.InputStream; /** * @author Ihar Kahadouski */ public class MultipartFileUtils { - private static final Tika tika = new Tika(); + private static final Tika tika = new Tika(); + + private MultipartFileUtils() { + //static only + } - private MultipartFileUtils() { - //static only - } - public static MultipartFile getMultipartFile(String path) throws IOException { - ClassPathResource resource = new ClassPathResource(path); - //TODO investigate stream closing requirement - try (InputStream bufferedInputStream = new BufferedInputStream(resource.getInputStream())) { - FileItem fileItem = new DiskFileItem("mainFile", - tika.detect(bufferedInputStream), - false, - resource.getFilename(), - bufferedInputStream.available(), - null - ); - IOUtils.copy(bufferedInputStream, fileItem.getOutputStream()); - return new MockMultipartFile(resource.getFilename(), resource.getFilename(), tika.detect(bufferedInputStream), resource.getInputStream().readAllBytes()); - } - } + public static MultipartFile getMultipartFile(String path) throws IOException { + ClassPathResource resource = new ClassPathResource(path); + MultipartFile mockFile; + try (InputStream bufferedInputStream = new BufferedInputStream(resource.getInputStream())) { + mockFile = new MockMultipartFile( + Objects.requireNonNull(resource.getFilename()), + resource.getFilename(), + tika.detect(bufferedInputStream), + resource.getInputStream().readAllBytes()); + } + return mockFile; + } } diff --git a/src/main/java/com/epam/ta/reportportal/ws/converter/builders/UserBuilder.java b/src/main/java/com/epam/ta/reportportal/ws/converter/builders/UserBuilder.java index 51decf7d2a..f7f0623630 100644 --- a/src/main/java/com/epam/ta/reportportal/ws/converter/builders/UserBuilder.java +++ b/src/main/java/com/epam/ta/reportportal/ws/converter/builders/UserBuilder.java @@ -38,7 +38,7 @@ public class UserBuilder implements Supplier { public static final String USER_LAST_LOGIN = "last_login"; - private User user; + private final User user; public UserBuilder() { user = new User(); diff --git a/src/test/java/com/epam/ta/reportportal/TestConfig.java b/src/test/java/com/epam/ta/reportportal/TestConfig.java index e03eef49c3..219ff33554 100644 --- a/src/test/java/com/epam/ta/reportportal/TestConfig.java +++ b/src/test/java/com/epam/ta/reportportal/TestConfig.java @@ -16,7 +16,7 @@ package com.epam.ta.reportportal; -import com.epam.ta.reportportal.auth.JwtReportPortalUserConverter; +import com.epam.ta.reportportal.core.configs.security.JwtReportPortalUserConverter; import com.epam.ta.reportportal.auth.basic.DatabaseUserDetailsService; import com.epam.ta.reportportal.core.analyzer.auto.client.RabbitMqManagementClient; import com.epam.ta.reportportal.core.analyzer.auto.client.impl.RabbitMqManagementClientTemplate; diff --git a/src/test/java/com/epam/ta/reportportal/util/MultipartFileUtilsTest.java b/src/test/java/com/epam/ta/reportportal/util/MultipartFileUtilsTest.java index 44acb82b01..c7782e5254 100644 --- a/src/test/java/com/epam/ta/reportportal/util/MultipartFileUtilsTest.java +++ b/src/test/java/com/epam/ta/reportportal/util/MultipartFileUtilsTest.java @@ -36,7 +36,7 @@ class MultipartFileUtilsTest { void getMultipartFile() throws IOException { String path = "image/image.png"; File expected = new ClassPathResource(path).getFile(); - MockMultipartFile file = (MockMultipartFile)MultipartFileUtils.getMultipartFile(path); + MockMultipartFile file = (MockMultipartFile) MultipartFileUtils.getMultipartFile(path); assertEquals(expected.length(), file.getSize()); assertEquals(expected.getName(), file.getName()); assertEquals("image/png", file.getContentType()); diff --git a/src/test/java/com/epam/ta/reportportal/ws/controller/LaunchAsyncControllerTest.java b/src/test/java/com/epam/ta/reportportal/ws/controller/LaunchAsyncControllerTest.java index ffcf34f796..45693ce677 100644 --- a/src/test/java/com/epam/ta/reportportal/ws/controller/LaunchAsyncControllerTest.java +++ b/src/test/java/com/epam/ta/reportportal/ws/controller/LaunchAsyncControllerTest.java @@ -20,6 +20,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mockStatic; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -27,22 +28,27 @@ import com.epam.ta.reportportal.core.launch.FinishLaunchHandler; import com.epam.ta.reportportal.core.launch.MergeLaunchHandler; import com.epam.ta.reportportal.core.launch.StartLaunchHandler; +import com.epam.ta.reportportal.core.launch.util.LinkGenerator; import com.epam.ta.reportportal.entity.project.ProjectRole; import com.epam.ta.reportportal.entity.user.UserRole; import com.epam.ta.reportportal.reporting.async.controller.LaunchAsyncController; import com.epam.ta.reportportal.util.ProjectExtractor; +import com.epam.ta.reportportal.ws.BaseMvcTest; import com.epam.ta.reportportal.ws.reporting.FinishExecutionRQ; import com.epam.ta.reportportal.ws.reporting.MergeLaunchesRQ; import com.epam.ta.reportportal.ws.reporting.StartLaunchRQ; import com.google.common.collect.Lists; -import java.util.UUID; import jakarta.servlet.http.HttpServletRequest; +import java.util.UUID; +import org.apache.commons.math3.geometry.euclidean.twod.Line; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.ArgumentCaptor; import org.mockito.InjectMocks; import org.mockito.Mock; +import org.mockito.MockedStatic; import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.web.savedrequest.Enumerator; /** @@ -66,9 +72,6 @@ class LaunchAsyncControllerTest { @InjectMocks LaunchAsyncController launchAsyncController; - @Mock - HttpServletRequest httpServletRequest; - @Test void startLaunch() { ReportPortalUser user = @@ -120,11 +123,11 @@ void finishLaunch() { anyString() )).thenReturn(user.getProjectDetails().get("test_project")); - when(httpServletRequest.getRequestURL()).thenReturn(new StringBuffer("http://localhost:8080")); - when(httpServletRequest.getHeaderNames()).thenReturn(new Enumerator<>(Lists.newArrayList())); - launchAsyncController.finishLaunch("test_project", launchId, finishExecutionRQ, user, - httpServletRequest - ); + MockedStatic a = mockStatic(LinkGenerator.class); + a.when(() -> LinkGenerator.composeBaseUrl(any())) + .thenReturn("http://localhost:8080/api"); + + launchAsyncController.finishLaunch("test_project", launchId, finishExecutionRQ, user,null); verify(finishLaunchHandler).finishLaunch(launchIdArgumentCaptor.capture(), requestArgumentCaptor.capture(), projectDetailsArgumentCaptor.capture(), userArgumentCaptor.capture(), urlArgumentCaptor.capture() diff --git a/src/test/java/com/epam/ta/reportportal/ws/controller/UserControllerTest.java b/src/test/java/com/epam/ta/reportportal/ws/controller/UserControllerTest.java index 7810e93093..3a3ad04d1b 100644 --- a/src/test/java/com/epam/ta/reportportal/ws/controller/UserControllerTest.java +++ b/src/test/java/com/epam/ta/reportportal/ws/controller/UserControllerTest.java @@ -32,6 +32,7 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import com.epam.ta.reportportal.dao.ApiKeyRepository; import com.epam.ta.reportportal.dao.IssueTypeRepository; import com.epam.ta.reportportal.dao.ProjectRepository; import com.epam.ta.reportportal.dao.UserRepository; From 6cf7db45a128aedec2cca797a2b631edddf53bde Mon Sep 17 00:00:00 2001 From: siarhei_hrabko Date: Fri, 10 Jan 2025 14:08:00 +0300 Subject: [PATCH 7/7] EPMRPP-96333 migrate to Spring Boot 3 --- .../epam/ta/reportportal/ReportPortalApp.java | 7 +- .../reportportal/core/configs/MvcConfig.java | 83 ------------------- src/main/resources/application.properties | 7 +- 3 files changed, 8 insertions(+), 89 deletions(-) diff --git a/src/main/java/com/epam/ta/reportportal/ReportPortalApp.java b/src/main/java/com/epam/ta/reportportal/ReportPortalApp.java index 1e5692e1da..b938d44583 100644 --- a/src/main/java/com/epam/ta/reportportal/ReportPortalApp.java +++ b/src/main/java/com/epam/ta/reportportal/ReportPortalApp.java @@ -18,7 +18,6 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @@ -27,9 +26,9 @@ * * @author Andrei Varabyeu */ -@SpringBootApplication(scanBasePackages = {"com.epam.ta.reportportal", - "com.epam.reportportal"}, exclude = { - MultipartAutoConfiguration.class, FlywayAutoConfiguration.class}) +@SpringBootApplication( + scanBasePackages = {"com.epam.ta.reportportal", "com.epam.reportportal"}, + exclude = {FlywayAutoConfiguration.class}) @Configuration @Import({com.epam.ta.reportportal.config.DatabaseConfiguration.class}) public class ReportPortalApp { diff --git a/src/main/java/com/epam/ta/reportportal/core/configs/MvcConfig.java b/src/main/java/com/epam/ta/reportportal/core/configs/MvcConfig.java index 213e166eb2..7c638ecfa7 100644 --- a/src/main/java/com/epam/ta/reportportal/core/configs/MvcConfig.java +++ b/src/main/java/com/epam/ta/reportportal/core/configs/MvcConfig.java @@ -16,11 +16,6 @@ package com.epam.ta.reportportal.core.configs; -import static com.google.common.base.Strings.isNullOrEmpty; -import static org.apache.commons.io.FileUtils.ONE_GB; -import static org.apache.commons.io.FileUtils.ONE_KB; -import static org.apache.commons.io.FileUtils.ONE_MB; - import com.epam.reportportal.rules.commons.ExceptionMappings; import com.epam.reportportal.rules.commons.exception.forwarding.ClientResponseForwardingExceptionHandler; import com.epam.reportportal.rules.commons.exception.rest.DefaultErrorResolver; @@ -33,20 +28,14 @@ import com.epam.ta.reportportal.ws.resolver.PredefinedFilterCriteriaResolver; import com.epam.ta.reportportal.ws.resolver.SortArgumentResolver; import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.common.base.Preconditions; -import jakarta.servlet.http.HttpServletRequest; import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.http.HttpMessageConverters; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Profile; import org.springframework.core.Ordered; -import org.springframework.core.annotation.Order; import org.springframework.http.MediaType; import org.springframework.http.converter.ByteArrayHttpMessageConverter; import org.springframework.http.converter.HttpMessageConverter; @@ -54,18 +43,11 @@ import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.validation.beanvalidation.BeanValidationPostProcessor; import org.springframework.web.method.support.HandlerMethodArgumentResolver; -import org.springframework.web.multipart.MultipartException; -import org.springframework.web.multipart.MultipartHttpServletRequest; -import org.springframework.web.multipart.support.MultipartFilter; -import org.springframework.web.multipart.support.StandardMultipartHttpServletRequest; -import org.springframework.web.multipart.support.StandardServletMultipartResolver; -import org.springframework.web.servlet.DispatcherServlet; import org.springframework.web.servlet.HandlerExceptionResolver; import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer; import org.springframework.web.servlet.config.annotation.PathMatchConfigurer; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; -import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; /** * Class-based Spring MVC Configuration @@ -73,7 +55,6 @@ * @author Andrei Varabyeu */ @Configuration -@EnableConfigurationProperties(MvcConfig.MultipartConfig.class) public class MvcConfig implements WebMvcConfigurer { @Autowired @@ -197,68 +178,4 @@ HttpMessageConverters httpMessageConverters() { return new HttpMessageConverters(converters); } - @Profile("!unittest") - @Bean - @Order(0) - public MultipartFilter multipartFilter() { - MultipartFilter multipartFilter = new MultipartFilter(); - multipartFilter.setMultipartResolverBeanName(DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME); - return multipartFilter; - } - - @Profile("!unittest") - @Bean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME) - public StandardServletMultipartResolver multipartResolver(MultipartConfig multipartConfig) { - StandardServletMultipartResolver resolver = new StandardServletMultipartResolver() { - @Override - public MultipartHttpServletRequest resolveMultipart(HttpServletRequest request) - throws MultipartException { - return new StandardMultipartHttpServletRequest(request, true); - } - - @Override - public void cleanupMultipart(MultipartHttpServletRequest request) { - // - } - }; - - //Lazy resolving gives a way to process file limits inside a controller - //level and handle exceptions in proper way. Fixes reportportal/reportportal#19 - resolver.setResolveLazily(true); - - multipartConfig.setMaxUploadSize(String.valueOf(multipartConfig.maxUploadSize)); - //resolver.setMaxUploadSizePerFile(multipartConfig.maxFileSize); - return resolver; - } - - @ConfigurationProperties("rp.upload") - public static class MultipartConfig { - - long maxUploadSize = 128 * ONE_MB; - long maxFileSize = 128 * ONE_MB; - - public void setMaxUploadSize(String maxUploadSize) { - this.maxUploadSize = parseSize(maxUploadSize); - } - - public void setMaxFileSize(String maxFileSize) { - this.maxFileSize = parseSize(maxFileSize); - } - - private long parseSize(String size) { - Preconditions.checkArgument(!isNullOrEmpty(size), "Size must not be empty"); - size = size.toUpperCase(); - if (size.endsWith("KB")) { - return Long.parseLong(size.substring(0, size.length() - 2)) * ONE_KB; - } - if (size.endsWith("MB")) { - return Long.parseLong(size.substring(0, size.length() - 2)) * ONE_MB; - } - if (size.endsWith("GB")) { - return Long.parseLong(size.substring(0, size.length() - 2)) * ONE_GB; - } - return Long.parseLong(size); - } - } - } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 2fc46a1fce..46a3729fe5 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -192,8 +192,11 @@ rp.db.port=5432 rp.db.user= rp.db.pass= -rp.upload.maxUploadSize=128MB -rp.upload.maxFileSize=64MB +spring.servlet.multipart.enabled=true +spring.servlet.multipart.resolve-lazily=true +spring.servlet.multipart.file-size-threshold=128MB +spring.servlet.multipart.max-filesize=64MB + rp.analytics.enableByDefault=true rp.plugins.rootDir=/tmp/plugins rp.plugins.path=\${rp.plugins.rootDir}/resolved