diff --git a/documents-api/src/main/java/org/exoplatform/documents/webdav/valve/WebdavLoggingValve.java b/documents-api/src/main/java/org/exoplatform/documents/webdav/valve/WebdavLoggingValve.java index 5b20b71d32..29d0c97b12 100644 --- a/documents-api/src/main/java/org/exoplatform/documents/webdav/valve/WebdavLoggingValve.java +++ b/documents-api/src/main/java/org/exoplatform/documents/webdav/valve/WebdavLoggingValve.java @@ -23,10 +23,10 @@ import java.io.InputStream; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; import java.security.Principal; import java.util.Collection; import java.util.Enumeration; -import java.util.List; import java.util.Locale; import java.util.Map; import java.util.UUID; @@ -44,6 +44,7 @@ import org.apache.catalina.valves.ValveBase; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Strings; import org.apache.coyote.ContinueResponseTiming; import org.apache.tomcat.util.buf.MessageBytes; import org.apache.tomcat.util.http.ServerCookies; @@ -80,7 +81,7 @@ public class WebdavLoggingValve extends ValveBase { private static final Log LOG = ExoLogger.getLogger(WebdavLoggingValve.class); @Override - public void invoke(Request request, Response response) throws IOException, ServletException { + public void invoke(Request request, Response response) throws IOException, ServletException { // NOSONAR if (LOG.isDebugEnabled()) { UUID reqUuid = UUID.randomUUID(); try { // NOSONAR @@ -103,9 +104,9 @@ public void invoke(Request request, Response response) throws IOException, Servl if (arrayInputStream.available() > 0 && (arrayInputStream.available() < 2048 - || StringUtils.contains(request.getContentType(), "text/") - || StringUtils.equals(request.getContentType(), "application/xml") - || StringUtils.equals(request.getContentType(), "application.json/"))) { + || Strings.CS.contains(request.getContentType(), "text/") + || Strings.CS.equals(request.getContentType(), "application/xml") + || Strings.CS.equals(request.getContentType(), "application.json/"))) { byte[] bytes = arrayInputStream.readAllBytes(); arrayInputStream.reset(); LOG.debug("[{}] + Request Body: {}", reqUuid, new String(bytes)); @@ -121,7 +122,7 @@ public void invoke(Request request, Response response) throws IOException, Servl byte[] responseBytes = wrappedResponse.getBufferedContent(); if (LOG.isTraceEnabled() - && StringUtils.contains(response.getContentType(), "text/") + && Strings.CS.contains(response.getContentType(), "text/") && responseBytes.length > 0) { LOG.trace("[{}] + Response Body: {}", reqUuid, new String(responseBytes)); } @@ -151,14 +152,39 @@ private class RequestWrapper extends Request { private ByteArrayInputStream arrayInputStream; public RequestWrapper(Request request, ByteArrayInputStream arrayInputStream) { - super(request.getConnector()); + super(request.getConnector(), request.getCoyoteRequest()); this.request = request; this.arrayInputStream = arrayInputStream; } @Override - public void setCoyoteRequest(org.apache.coyote.Request coyoteRequest) { - request.setCoyoteRequest(coyoteRequest); + public String toString() { + return request.toString(); + } + + @Override + public void recycleSessionInfo() { + request.recycleSessionInfo(); + } + + @Override + public void setMaxParameterCount(int maxParameterCount) { + request.setMaxParameterCount(maxParameterCount); + } + + @Override + public void setMaxPartCount(int maxPartCount) { + request.setMaxPartCount(maxPartCount); + } + + @Override + public void setMaxPartHeaderSize(int maxPartHeaderSize) { + request.setMaxPartHeaderSize(maxPartHeaderSize); + } + + @Override + public void setCharacterEncoding(Charset charset) { + request.setCharacterEncoding(charset); } @Override @@ -602,15 +628,11 @@ public Map getTrailerFields() { } @Override + @SuppressWarnings("deprecation") public PushBuilder newPushBuilder() { return request.newPushBuilder(); } - @Override - public PushBuilder newPushBuilder(HttpServletRequest httpServletRequest) { - return request.newPushBuilder(httpServletRequest); - } - @Override public T upgrade(Class httpUpgradeHandlerClass) throws IOException, ServletException { return request.upgrade(httpUpgradeHandlerClass); @@ -811,6 +833,16 @@ public Part getPart(String name) throws IOException, IllegalStateException, Serv return request.getPart(name); } + @Override + public int hashCode() { + return request.hashCode(); + } + + @Override + public boolean equals(Object obj) { + return request.equals(obj); + } + private HttpServletRequestWrapper newHttpServletRequestWrapper(HttpServletRequest httpRequest, ByteArrayInputStream arrayInputStream) { return new HttpServletRequestWrapper(httpRequest) { @@ -866,9 +898,25 @@ private class ResponseWrapper extends Response { private Response response; public ResponseWrapper(Response response) { + super(response.getCoyoteResponse()); this.response = response; } + @Override + public void sendRedirect(String location, boolean clearBuffer) throws IOException { + response.sendRedirect(location, clearBuffer); + } + + @Override + public void setCharacterEncoding(Charset charset) { + response.setCharacterEncoding(charset); + } + + @Override + public void sendRedirect(String location, int status, boolean clearBuffer) throws IOException { + response.sendRedirect(location, status, clearBuffer); + } + @Override public ServletOutputStream getOutputStream() throws IOException { return bufferOutputStream; @@ -882,11 +930,6 @@ public PrintWriter getWriter() throws IOException { return bufferWriter; } - @Override - public void setCoyoteResponse(org.apache.coyote.Response coyoteResponse) { - response.setCoyoteResponse(coyoteResponse); - } - @Override public org.apache.coyote.Response getCoyoteResponse() { return response.getCoyoteResponse(); @@ -902,11 +945,6 @@ public void recycle() { response.recycle(); } - @Override - public List getCookies() { - return response.getCookies(); - } - @Override public long getContentWritten() { return response.getContentWritten(); @@ -966,9 +1004,8 @@ public boolean isClosed() { } @Override - @SuppressWarnings("deprecation") - public boolean setError() { - return response.setError(); + public void setError() { + response.setError(); } @Override @@ -1167,7 +1204,7 @@ public String encodeURL(String url) { } @Override - public void sendAcknowledgement(ContinueResponseTiming continueResponseTiming) throws IOException { + public void sendAcknowledgement(ContinueResponseTiming continueResponseTiming) { response.sendAcknowledgement(continueResponseTiming); } @@ -1216,6 +1253,16 @@ public void setStatus(int status) { response.setStatus(status); } + @Override + public int hashCode() { + return response.hashCode(); + } + + @Override + public boolean equals(Object obj) { + return response.equals(obj); + } + public byte[] getBufferedContent() { return buffer.toByteArray(); } diff --git a/documents-services/src/main/java/org/exoplatform/documents/entity/PublicDocumentAccessEntity.java b/documents-services/src/main/java/org/exoplatform/documents/entity/PublicDocumentAccessEntity.java index 58468ec4e5..4a51a19499 100644 --- a/documents-services/src/main/java/org/exoplatform/documents/entity/PublicDocumentAccessEntity.java +++ b/documents-services/src/main/java/org/exoplatform/documents/entity/PublicDocumentAccessEntity.java @@ -16,23 +16,28 @@ */ package org.exoplatform.documents.entity; -import lombok.Data; -import org.exoplatform.commons.api.persistence.ExoEntity; - -import jakarta.persistence.*; import java.io.Serializable; import java.util.Date; +import io.meeds.common.persistence.PortableSequence; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.NamedQuery; +import jakarta.persistence.Table; +import lombok.Data; + @Entity(name = "PublicDocumentAccess") -@ExoEntity @Table(name = "DOCUMENTS_PUBLIC_ACCESS") @Data @NamedQuery(name = "PublicDocumentAccess.getPublicAccessByNodeId", query = "SELECT DISTINCT c FROM PublicDocumentAccess c where c.nodeId = :nodeId") public class PublicDocumentAccessEntity implements Serializable { + private static final long serialVersionUID = -7234365786103959973L; + @Id - @SequenceGenerator(name = "SEQ_DOCUMENT_PUBLIC_ACCESS_ID", sequenceName = "SEQ_DOCUMENT_PUBLIC_ACCESS_ID", allocationSize = 1) - @GeneratedValue(strategy = GenerationType.AUTO, generator = "SEQ_DOCUMENT_PUBLIC_ACCESS_ID") + @PortableSequence(name = "SEQ_DOCUMENT_PUBLIC_ACCESS_ID") @Column(name = "ID", nullable = false) private Long id; diff --git a/documents-services/src/main/java/org/exoplatform/documents/filter/DocumentModeRedirectHandler.java b/documents-services/src/main/java/org/exoplatform/documents/filter/DocumentModeRedirectHandler.java index 4bf4b1a188..ed2f8bd1e7 100644 --- a/documents-services/src/main/java/org/exoplatform/documents/filter/DocumentModeRedirectHandler.java +++ b/documents-services/src/main/java/org/exoplatform/documents/filter/DocumentModeRedirectHandler.java @@ -28,10 +28,13 @@ import org.exoplatform.social.core.manager.IdentityManager; import org.exoplatform.web.filter.Filter; +import io.meeds.common.ContainerTransactional; + public class DocumentModeRedirectHandler implements Filter { @SneakyThrows @Override + @ContainerTransactional public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) { DocumentFileService documentFileService = ExoContainerContext.getService(DocumentFileService.class); IdentityManager identityManager = ExoContainerContext.getService(IdentityManager.class); diff --git a/documents-services/src/main/resources/jpa-entities.idx b/documents-services/src/main/resources/jpa-entities.idx new file mode 100644 index 0000000000..66fb7eb26c --- /dev/null +++ b/documents-services/src/main/resources/jpa-entities.idx @@ -0,0 +1 @@ +org.exoplatform.documents.entity.PublicDocumentAccessEntity diff --git a/documents-services/src/test/java/org/exoplatform/documents/service/DocumentFileServiceTest.java b/documents-services/src/test/java/org/exoplatform/documents/service/DocumentFileServiceTest.java index f60cc14491..cebcf83456 100644 --- a/documents-services/src/test/java/org/exoplatform/documents/service/DocumentFileServiceTest.java +++ b/documents-services/src/test/java/org/exoplatform/documents/service/DocumentFileServiceTest.java @@ -17,7 +17,6 @@ package org.exoplatform.documents.service; import static org.junit.Assert.*; -import static org.mockito.Matchers.eq; import static org.mockito.Mockito.*; import java.io.ByteArrayInputStream; diff --git a/documents-storage-jcr/src/test/java/org/exoplatform/documents/storage/jcr/JCRDocumentFileStorageTest.java b/documents-storage-jcr/src/test/java/org/exoplatform/documents/storage/jcr/JCRDocumentFileStorageTest.java index be8532f650..32c00b558c 100644 --- a/documents-storage-jcr/src/test/java/org/exoplatform/documents/storage/jcr/JCRDocumentFileStorageTest.java +++ b/documents-storage-jcr/src/test/java/org/exoplatform/documents/storage/jcr/JCRDocumentFileStorageTest.java @@ -1082,14 +1082,24 @@ public void testFoldersThenFilesLoading() throws RepositoryException, ObjectNotF QueryResult queryResult = mock(QueryResult.class); when(userSession.getWorkspace()).thenReturn(workspace); - Node folderAbc = createFolderMock("Abc", Calendar.getInstance(), userSession); - Node folderXyz = createFolderMock("Xyz", Calendar.getInstance(), userSession); - Node folderEfg = createFolderMock("Efg", Calendar.getInstance(), userSession); + // Explicitly spaced out timestamps (rather than successive + // Calendar.getInstance() calls) so the created/modified date sort + // assertions below don't depend on the clock resolution of the + // machine running the test. + Calendar folderAbcDate = Calendar.getInstance(); + Calendar folderXyzDate = (Calendar) folderAbcDate.clone(); + folderXyzDate.add(Calendar.MINUTE, 1); + Calendar folderEfgDate = (Calendar) folderAbcDate.clone(); + folderEfgDate.add(Calendar.MINUTE, 2); + + Node folderAbc = createFolderMock("Abc", folderAbcDate, userSession); + Node folderXyz = createFolderMock("Xyz", folderXyzDate, userSession); + Node folderEfg = createFolderMock("Efg", folderEfgDate, userSession); Node file1 = createFileMock("file1", Calendar.getInstance(), userSession); Node file2 = createFileMock("file2", Calendar.getInstance(), userSession); Node symlinkFile2 = createSymlinkMock("file2FileIdentifier", "file2"); - Node symlinkFolderEfg = createSymlinkMock("EfgIdentifier", "Efg"); + Node symlinkFolderEfg = createSymlinkMock("EfgIdentifier", "Efg", folderEfgDate); when(subItemsIterator.hasNext()).thenReturn(true, true, true, true, true, false); when(subItemsIterator.nextNode()).thenReturn(file1, symlinkFile2, folderXyz, folderAbc, symlinkFolderEfg); @@ -1254,6 +1264,10 @@ private Node createFileMock(String name, Calendar createdDate, Session session) } private Node createSymlinkMock(String nodeIdentifier, String nodeName) throws RepositoryException { + return createSymlinkMock(nodeIdentifier, nodeName, Calendar.getInstance()); + } + + private Node createSymlinkMock(String nodeIdentifier, String nodeName, Calendar createdDate) throws RepositoryException { Node symlink = mock(NodeImpl.class); when(symlink.isNodeType(NodeTypeConstants.EXO_SYMLINK)).thenReturn(true); Property symlinkUUIDProperty = mock(Property.class); @@ -1261,9 +1275,9 @@ private Node createSymlinkMock(String nodeIdentifier, String nodeName) throws Re when(symlink.getProperty(NodeTypeConstants.EXO_SYMLINK_UUID)).thenReturn(symlinkUUIDProperty); when(symlink.getName()).thenReturn(nodeName + ".lnk"); when(symlink.getPath()).thenReturn("/path/to/" + nodeName); - Property createdDate = mock(Property.class); - when(createdDate.getDate()).thenReturn(Calendar.getInstance()); - when(symlink.getProperty(NodeTypeConstants.EXO_DATE_CREATED)).thenReturn(createdDate); + Property createdDateProperty = mock(Property.class); + when(createdDateProperty.getDate()).thenReturn(createdDate); + when(symlink.getProperty(NodeTypeConstants.EXO_DATE_CREATED)).thenReturn(createdDateProperty); when(symlink.hasProperty(NodeTypeConstants.EXO_DATE_CREATED)).thenReturn(true); when(((NodeImpl)symlink).getIdentifier()).thenReturn(nodeName + "LinkIdentifier"); return symlink; @@ -1677,6 +1691,7 @@ public void getDocumentDownloadItem() throws RepositoryException { Value mimeTypeValue = mock(Value.class); when(dataProperty.getValue()).thenReturn(dataValue); when(dataValue.getStream()).thenReturn(inputStream); + when(dataProperty.getStream()).thenReturn(inputStream); when(mimeTypeProperty.getValue()).thenReturn(mimeTypeValue); when(mimeTypeValue.getString()).thenReturn("application/pdf"); when(contentNode.getProperty(NodeTypeConstants.JCR_DATA)).thenReturn(dataProperty); diff --git a/documents-storage-jcr/src/test/java/org/exoplatform/documents/storage/jcr/listener/CategoryLinkModifiedDocumentListenerTest.java b/documents-storage-jcr/src/test/java/org/exoplatform/documents/storage/jcr/listener/CategoryLinkModifiedDocumentListenerTest.java index dab9500433..5f6d791eaf 100644 --- a/documents-storage-jcr/src/test/java/org/exoplatform/documents/storage/jcr/listener/CategoryLinkModifiedDocumentListenerTest.java +++ b/documents-storage-jcr/src/test/java/org/exoplatform/documents/storage/jcr/listener/CategoryLinkModifiedDocumentListenerTest.java @@ -16,10 +16,23 @@ */ package org.exoplatform.documents.storage.jcr.listener; -import static org.mockito.Mockito.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.mockStatic; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import javax.jcr.Node; +import javax.jcr.Session; + +import org.junit.jupiter.api.Test; +import org.mockito.MockedStatic; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.bean.override.mockito.MockitoBean; -import io.meeds.social.category.model.CategoryObject; -import lombok.SneakyThrows; import org.exoplatform.documents.service.DocumentFileService; import org.exoplatform.documents.storage.jcr.util.JCRDocumentsUtil; import org.exoplatform.services.jcr.RepositoryService; @@ -29,31 +42,27 @@ import org.exoplatform.services.jcr.ext.common.SessionProvider; import org.exoplatform.services.listener.Event; import org.exoplatform.services.listener.ListenerService; -import org.junit.jupiter.api.Test; -import org.mockito.MockedStatic; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import javax.jcr.Node; -import javax.jcr.Session; +import io.meeds.social.category.model.CategoryObject; + +import lombok.SneakyThrows; @SpringBootTest(classes = { CategoryLinkModifiedDocumentListener.class, }) class CategoryLinkModifiedDocumentListenerTest { - @MockBean + @MockitoBean private DocumentFileService documentFileService; - @MockBean + @MockitoBean private RepositoryService repositoryService; - @MockBean + @MockitoBean private SessionProviderService sessionProviderService; - @MockBean + @MockitoBean private ListenerService listenerService; - @MockBean + @MockitoBean private Event event; @Autowired diff --git a/documents-webapp/pom.xml b/documents-webapp/pom.xml index adefbda501..f134b20e76 100644 --- a/documents-webapp/pom.xml +++ b/documents-webapp/pom.xml @@ -106,7 +106,7 @@ org.apache.maven.plugins maven-war-plugin - **/*.less,**/less/**,**/*.vue,css/lib/*,vue-app/**,js/mock/**/*,**-dev.* + WEB-INF/lib/**,**/*.less,**/less/**,**/*.vue,css/lib/*,vue-app/**,js/mock/**/*,**-dev.* diff --git a/documents-webapp/src/main/java/org/exoplatform/documents/DocumentApplication.java b/documents-webapp/src/main/java/org/exoplatform/documents/DocumentApplication.java index b5e7747a8a..f91b378e15 100644 --- a/documents-webapp/src/main/java/org/exoplatform/documents/DocumentApplication.java +++ b/documents-webapp/src/main/java/org/exoplatform/documents/DocumentApplication.java @@ -17,7 +17,7 @@ package org.exoplatform.documents; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration; +import org.springframework.boot.liquibase.autoconfigure.LiquibaseAutoConfiguration; import org.springframework.context.annotation.PropertySource; import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; diff --git a/documents-webdav-webapp/pom.xml b/documents-webdav-webapp/pom.xml index 326384f218..3b1ce5e453 100644 --- a/documents-webdav-webapp/pom.xml +++ b/documents-webdav-webapp/pom.xml @@ -27,5 +27,13 @@ webdav + + + maven-war-plugin + + WEB-INF/lib/** + + + diff --git a/documents-webdav-webapp/src/main/java/org/exoplatform/documents/webdav/WebdavApplication.java b/documents-webdav-webapp/src/main/java/org/exoplatform/documents/webdav/WebdavApplication.java index 16617c9e11..fc2129e752 100644 --- a/documents-webdav-webapp/src/main/java/org/exoplatform/documents/webdav/WebdavApplication.java +++ b/documents-webdav-webapp/src/main/java/org/exoplatform/documents/webdav/WebdavApplication.java @@ -17,8 +17,8 @@ package org.exoplatform.documents.webdav; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration; -import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration; +import org.springframework.boot.data.jpa.autoconfigure.DataJpaRepositoriesAutoConfiguration; +import org.springframework.boot.liquibase.autoconfigure.LiquibaseAutoConfiguration; import org.springframework.context.annotation.PropertySource; import io.meeds.spring.AvailableIntegration; @@ -28,8 +28,8 @@ WebdavApplication.MODULE_NAME, AvailableIntegration.KERNEL_MODULE, }, exclude = { + DataJpaRepositoriesAutoConfiguration.class, LiquibaseAutoConfiguration.class, - JpaRepositoriesAutoConfiguration.class, }) @PropertySource("classpath:application.properties") @PropertySource("classpath:documents-webdav.properties") diff --git a/documents-webdav-webapp/src/main/java/org/exoplatform/documents/webdav/configuration/WebFilterConfiguration.java b/documents-webdav-webapp/src/main/java/org/exoplatform/documents/webdav/configuration/WebFilterConfiguration.java index c9992b639f..6dd4ad3b96 100644 --- a/documents-webdav-webapp/src/main/java/org/exoplatform/documents/webdav/configuration/WebFilterConfiguration.java +++ b/documents-webdav-webapp/src/main/java/org/exoplatform/documents/webdav/configuration/WebFilterConfiguration.java @@ -16,6 +16,9 @@ */ package org.exoplatform.documents.webdav.configuration; +import java.util.EnumSet; +import java.util.List; + import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -25,15 +28,20 @@ import io.meeds.spring.web.security.PortalIdentityFilter; import io.meeds.spring.web.transaction.PortalTransactionFilter; +import jakarta.servlet.DispatcherType; + @Configuration @EnableMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true) public class WebFilterConfiguration { + private static final String DRIVES_PATH_PATTERN = "/drives/*"; + @Bean public FilterRegistrationBean identityFilter() { FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(); registrationBean.setFilter(new PortalIdentityFilter()); - registrationBean.addUrlPatterns("/drives/*"); + registrationBean.setUrlPatterns(List.of(DRIVES_PATH_PATTERN)); + registrationBean.setDispatcherTypes(EnumSet.allOf(DispatcherType.class)); registrationBean.setOrder(2); return registrationBean; } @@ -42,7 +50,7 @@ public FilterRegistrationBean identityFilter() { public FilterRegistrationBean httpRequestLocaleFilter() { FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(); registrationBean.setFilter(new HttpRequestLocaleFilter()); - registrationBean.addUrlPatterns("/drives/*"); + registrationBean.setUrlPatterns(List.of(DRIVES_PATH_PATTERN)); registrationBean.setOrder(4); return registrationBean; } @@ -51,7 +59,7 @@ public FilterRegistrationBean httpRequestLocaleFilter() public FilterRegistrationBean transactionFilter() { FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(); registrationBean.setFilter(new PortalTransactionFilter()); - registrationBean.addUrlPatterns("/rest/*"); + registrationBean.setUrlPatterns(List.of(DRIVES_PATH_PATTERN)); registrationBean.setOrder(1); return registrationBean; } diff --git a/documents-webdav-webapp/src/main/java/org/exoplatform/documents/webdav/configuration/WebSecurityConfiguration.java b/documents-webdav-webapp/src/main/java/org/exoplatform/documents/webdav/configuration/WebSecurityConfiguration.java index 631a4d59e2..bb6bf4e3f1 100644 --- a/documents-webdav-webapp/src/main/java/org/exoplatform/documents/webdav/configuration/WebSecurityConfiguration.java +++ b/documents-webdav-webapp/src/main/java/org/exoplatform/documents/webdav/configuration/WebSecurityConfiguration.java @@ -20,7 +20,7 @@ import java.util.function.Supplier; -import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Strings; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Qualifier; @@ -29,11 +29,12 @@ import org.springframework.http.HttpStatus; import org.springframework.security.authorization.AuthorizationDecision; import org.springframework.security.authorization.AuthorizationManager; +import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configurers.CsrfConfigurer; import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer; -import org.springframework.security.config.annotation.web.configurers.JeeConfigurer; +import org.springframework.security.config.core.GrantedAuthorityDefaults; import org.springframework.security.core.Authentication; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.WebAttributes; @@ -43,7 +44,6 @@ import org.springframework.security.web.util.matcher.RequestMatcher; import org.springframework.web.context.ServletContextAware; -import io.meeds.spring.web.security.GrantedAuthorityDefaults; import io.meeds.spring.web.security.PortalAuthenticationManager; import jakarta.servlet.DispatcherType; @@ -62,11 +62,10 @@ public class WebSecurityConfiguration implements ServletContextAware { @Bean public static GrantedAuthorityDefaults grantedAuthorityDefaults() { // Reset prefix to be empty. By default it adds "ROLE_" prefix - return new GrantedAuthorityDefaults(); + return new GrantedAuthorityDefaults(""); } @Bean - @SuppressWarnings("removal") public SecurityFilterChain filterChain(HttpSecurity http, PortalAuthenticationManager authenticationProvider, @Qualifier("restRequestMatcher") @@ -76,11 +75,11 @@ public SecurityFilterChain filterChain(HttpSecurity http, @Qualifier("accessDeniedHandler") AccessDeniedHandler accessDeniedHandler, @Qualifier("requestAuthorizationManager") - AuthorizationManager requestAuthorizationManager) throws Exception { + AuthorizationManager requestAuthorizationManager) { return http.authenticationProvider(authenticationProvider) - .jee(JeeConfigurer::and) // NOSONAR no method replacement .csrf(CsrfConfigurer::disable) .headers(HeadersConfigurer::disable) + .jee(Customizer.withDefaults()) .authorizeHttpRequests(customizer -> { try { customizer.requestMatchers(restRequestMatcher) @@ -100,12 +99,12 @@ public SecurityFilterChain filterChain(HttpSecurity http, @Bean("restRequestMatcher") public RequestMatcher restRequestMatcher() { - return request -> StringUtils.startsWith(request.getRequestURI(), servletContext.getContextPath() + "/rest/"); + return request -> Strings.CS.startsWith(request.getRequestURI(), servletContext.getContextPath() + "/rest/"); } @Bean("staticResourcesRequestMatcher") public RequestMatcher staticResourcesRequestMatcher() { - return request -> !StringUtils.startsWith(request.getRequestURI(), servletContext.getContextPath() + "/rest/"); + return request -> !Strings.CS.startsWith(request.getRequestURI(), servletContext.getContextPath() + "/rest/"); } @Bean("accessDeniedHandler") @@ -126,7 +125,7 @@ public AccessDeniedHandler accessDeniedHandler() { @Bean("requestAuthorizationManager") public AuthorizationManager requestAuthorizationManager() { - return (Supplier authentication, RequestAuthorizationContext object) -> { + return (Supplier authentication, RequestAuthorizationContext object) -> { Authentication userAuthentication = authentication.get(); // Permit anonymous and authentication users to access // the REST endpoints and rely on jee & secured permission diff --git a/documents-webdav-webapp/src/main/java/org/exoplatform/documents/webdav/plugin/WebDavHttpMethodPlugin.java b/documents-webdav-webapp/src/main/java/org/exoplatform/documents/webdav/plugin/WebDavHttpMethodPlugin.java index 8b0ef60742..aca6d62df3 100644 --- a/documents-webdav-webapp/src/main/java/org/exoplatform/documents/webdav/plugin/WebDavHttpMethodPlugin.java +++ b/documents-webdav-webapp/src/main/java/org/exoplatform/documents/webdav/plugin/WebDavHttpMethodPlugin.java @@ -38,6 +38,7 @@ import javax.xml.stream.events.XMLEvent; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Strings; import org.springframework.beans.factory.annotation.Autowired; import org.exoplatform.common.http.HTTPStatus; @@ -60,13 +61,13 @@ @Getter public abstract class WebDavHttpMethodPlugin { - public static final String CONTEXT_PATH = "/webdav/drives"; + public static final String CONTEXT_PATH = "/webdav/drives"; // NOSONAR - public static final String CONTEXT_PATH_ROOT = CONTEXT_PATH + "/"; + public static final String CONTEXT_PATH_ROOT = CONTEXT_PATH + "/"; // NOSONAR public static final String CONTEXT_PATH_SINGLE_DRIVE = CONTEXT_PATH + "/d"; - public static final String CONTEXT_PATH_SINGLE_DRIVE_ROOT = CONTEXT_PATH_SINGLE_DRIVE + "/"; + public static final String CONTEXT_PATH_SINGLE_DRIVE_ROOT = CONTEXT_PATH_SINGLE_DRIVE + "/"; // NOSONAR public static final String OPAQUE_LOCK_TOKEN = "opaquelocktoken"; @@ -182,7 +183,7 @@ protected String getDepth(HttpServletRequest httpRequest) { protected int getDepthInt(HttpServletRequest httpRequest) { String depth = getDepth(httpRequest); - return StringUtils.isBlank(depth) || StringUtils.equalsIgnoreCase(depth, INFINITY_DEPTH) ? -1 : Integer.parseInt(depth); + return StringUtils.isBlank(depth) || Strings.CI.equals(depth, INFINITY_DEPTH) ? -1 : Integer.parseInt(depth); } protected String getDestinationPath(HttpServletRequest httpRequest) { @@ -196,11 +197,11 @@ protected String getDestinationPath(HttpServletRequest httpRequest) { } protected boolean getOverwriteParameter(HttpServletRequest httpRequest) { - return StringUtils.equalsIgnoreCase("f", httpRequest.getHeader(ExtHttpHeaders.OVERWRITE)); + return Strings.CI.equals("f", httpRequest.getHeader(ExtHttpHeaders.OVERWRITE)); } protected boolean getRemoveDestinationParameter(HttpServletRequest httpRequest) { - return StringUtils.equalsIgnoreCase("t", httpRequest.getHeader(ExtHttpHeaders.OVERWRITE)); + return Strings.CI.equals("t", httpRequest.getHeader(ExtHttpHeaders.OVERWRITE)); } @SneakyThrows diff --git a/documents-webdav-webapp/src/main/java/org/exoplatform/documents/webdav/plugin/impl/GetWebDavHandler.java b/documents-webdav-webapp/src/main/java/org/exoplatform/documents/webdav/plugin/impl/GetWebDavHandler.java index e5ba0baca4..a23bffca11 100644 --- a/documents-webdav-webapp/src/main/java/org/exoplatform/documents/webdav/plugin/impl/GetWebDavHandler.java +++ b/documents-webdav-webapp/src/main/java/org/exoplatform/documents/webdav/plugin/impl/GetWebDavHandler.java @@ -33,7 +33,7 @@ import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.io.IOUtils; -import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Strings; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import org.springframework.util.MimeTypeUtils; @@ -283,7 +283,7 @@ private void println(OutputStream ostream) throws IOException { private List parseRanges(HttpServletRequest httpRequest, HttpServletResponse httpResponse) { String rangeHeader = httpRequest.getHeader(ExtHttpHeaders.RANGE); - if (StringUtils.startsWith(rangeHeader, "bytes=")) { + if (Strings.CI.startsWith(rangeHeader, "bytes=")) { List ranges = new ArrayList<>(); String rangeString = rangeHeader.substring(rangeHeader.indexOf("=") + 1);