diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 657189d5..22b7bdd6 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -21,10 +21,10 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Set up JDK 17 + - name: Set up JDK 25 uses: actions/setup-java@v4 with: - java-version: '17' + java-version: '25' distribution: 'temurin' cache: maven - name: Build with Maven diff --git a/.gitignore b/.gitignore index c3d37923..85e0c1a5 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,4 @@ # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* +.vscode diff --git a/cosmo-api/pom.xml b/cosmo-api/pom.xml index 6447b0cc..c805bab9 100644 --- a/cosmo-api/pom.xml +++ b/cosmo-api/pom.xml @@ -4,7 +4,7 @@ net.oneandone.cosmo cosmo-multimodule - 7.1.2-SNAPSHOT + 8.0.0-SNAPSHOT cosmo-api diff --git a/cosmo-core/pom.xml b/cosmo-core/pom.xml index 25248950..9d68cf48 100644 --- a/cosmo-core/pom.xml +++ b/cosmo-core/pom.xml @@ -12,7 +12,7 @@ net.oneandone.cosmo cosmo-multimodule - 7.1.2-SNAPSHOT + 8.0.0-SNAPSHOT 4.0.0 cosmo-core @@ -32,6 +32,11 @@ org.springframework.boot spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-starter-validation + org.springframework.boot diff --git a/cosmo-core/src/main/java/org/unitedinternet/cosmo/acegisecurity/providers/ticket/ExtraTicketProcessingFilter.java b/cosmo-core/src/main/java/org/unitedinternet/cosmo/acegisecurity/providers/ticket/ExtraTicketProcessingFilter.java deleted file mode 100644 index 1f508aa6..00000000 --- a/cosmo-core/src/main/java/org/unitedinternet/cosmo/acegisecurity/providers/ticket/ExtraTicketProcessingFilter.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright 2008 Open Source Applications Foundation - * - * 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 org.unitedinternet.cosmo.acegisecurity.providers.ticket; - -import java.io.IOException; -import java.util.Enumeration; -import java.util.HashSet; -import java.util.Set; - -import jakarta.servlet.Filter; -import jakarta.servlet.FilterChain; -import jakarta.servlet.FilterConfig; -import jakarta.servlet.ServletException; -import jakarta.servlet.ServletRequest; -import jakarta.servlet.ServletResponse; -import jakarta.servlet.http.HttpServletRequest; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; -import org.unitedinternet.cosmo.dao.ContentDao; -import org.unitedinternet.cosmo.model.Ticket; -import org.unitedinternet.cosmo.security.CosmoSecurityManager; - -/** - * Servlet filter that examines request for additional ticket keys to include in the security context. - */ -@Component -public class ExtraTicketProcessingFilter implements Filter { - private static final Logger LOG = LoggerFactory.getLogger(ExtraTicketProcessingFilter.class); - - public static final String TICKET_HEADER = "X-Cosmo-Ticket"; - public static final String MORSE_CODE_TICKET_HEADER = "X-MorseCode-Ticket"; - public static final String PARAM_TICKET = "ticket"; - - private ContentDao contentDao = null; - private CosmoSecurityManager securityManager = null; - - /** - * - * @param contentDao - * @param securityManager - */ - public ExtraTicketProcessingFilter(ContentDao contentDao, CosmoSecurityManager securityManager) { - super(); - this.contentDao = contentDao; - this.securityManager = securityManager; - } - - /** - * Does nothing - we use IoC lifecycle methods instead - * - * @param filterConfig - * The filter config. - * @throws ServletException - * - if something is wrong this exception is thrown. - */ - public void init(FilterConfig filterConfig) throws ServletException { - } - - /** - * Examines HTTP servlet requests for extra ticket keys, and register them with the security manager. - * - * @param request - * The servlet request. - * @param response - * The servlet response. - * @param chain - * The filter chain. - * @throws IOException - * - if something is wrong this exception is thrown. - * @throws ServletException - * - if something is wrong this exception is thrown. - */ - public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) - throws IOException, ServletException { - if (!(request instanceof HttpServletRequest)) { - throw new IllegalStateException("Received request is of type [" + request.getClass().getName() - + "]. Expected type: [" + HttpServletRequest.class.getName() + "]."); - } - HttpServletRequest httpRequest = (HttpServletRequest) request; - - if (LOG.isDebugEnabled()) { - LOG.debug("looking for tickets in request headers"); - } - - Set tickets = new HashSet(); - - // Look for tickets in header in the format: - // X-Cosmo-Ticket: slkdfjsdf, slkdjfsdf, sdlfkjsfsdf - Enumeration ticketKeys = httpRequest.getHeaders(TICKET_HEADER); - while (ticketKeys.hasMoreElements()) { - String ticketKeyValue = ticketKeys.nextElement(); - for (String ticketKey : ticketKeyValue.split(",")) { - Ticket ticket = contentDao.findTicket(ticketKey.trim()); - if (ticket != null) { - tickets.add(ticket); - } - } - } - - // Look for tickets in header in the format: - // X-MorseCode-Ticket: slkdfjsdf, slkdjfsdf, sdlfkjsfsdf - ticketKeys = httpRequest.getHeaders(MORSE_CODE_TICKET_HEADER); - while (ticketKeys.hasMoreElements()) { - String ticketKeyValue = ticketKeys.nextElement(); - for (String ticketKey : ticketKeyValue.split(",")) { - Ticket ticket = contentDao.findTicket(ticketKey.trim()); - if (ticket != null) { - tickets.add(ticket); - } - } - } - - // look for tickets in request parameters - String[] paramTicketKeys = httpRequest.getParameterValues(PARAM_TICKET); - if (paramTicketKeys != null) { - for (String ticketKey : paramTicketKeys) { - Ticket ticket = contentDao.findTicket(ticketKey); - if (ticket != null) { - tickets.add(ticket); - } - } - } - - try { - // register tickets - securityManager.registerTickets(tickets); - chain.doFilter(request, response); - } finally { - // clear tickets - securityManager.unregisterTickets(); - } - } - - @Override - public void destroy() { - // Nothing to do - } -} diff --git a/cosmo-core/src/main/java/org/unitedinternet/cosmo/acegisecurity/providers/ticket/TicketAuthenticationConverter.java b/cosmo-core/src/main/java/org/unitedinternet/cosmo/acegisecurity/providers/ticket/TicketAuthenticationConverter.java new file mode 100644 index 00000000..08c72086 --- /dev/null +++ b/cosmo-core/src/main/java/org/unitedinternet/cosmo/acegisecurity/providers/ticket/TicketAuthenticationConverter.java @@ -0,0 +1,33 @@ +package org.unitedinternet.cosmo.acegisecurity.providers.ticket; + +import java.util.Set; + +import org.jspecify.annotations.Nullable; +import org.springframework.security.core.Authentication; +import org.springframework.security.web.authentication.AuthenticationConverter; +import org.unitedinternet.cosmo.server.ServerUtils; + +import jakarta.servlet.http.HttpServletRequest; + +public class TicketAuthenticationConverter implements AuthenticationConverter { + + private static final String SLASH = "/"; + + @Override + public @Nullable Authentication convert(HttpServletRequest httpRequest) { + + Set keys = ServerUtils.findTicketKeys(httpRequest); + + if (!keys.isEmpty()) { + String path = httpRequest.getPathInfo(); + if (path == null || path.isEmpty()) { + path = SLASH; + } + if (!path.equals(SLASH) && path.endsWith(SLASH)) { + path = path.substring(0, path.length() - 1); + } + return new TicketAuthenticationToken(path, keys); + } + return null; + } +} \ No newline at end of file diff --git a/cosmo-core/src/main/java/org/unitedinternet/cosmo/acegisecurity/providers/ticket/TicketProcessingFilter.java b/cosmo-core/src/main/java/org/unitedinternet/cosmo/acegisecurity/providers/ticket/TicketProcessingFilter.java deleted file mode 100644 index 8ceb5134..00000000 --- a/cosmo-core/src/main/java/org/unitedinternet/cosmo/acegisecurity/providers/ticket/TicketProcessingFilter.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright 2005-2006 Open Source Applications Foundation - * - * 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 org.unitedinternet.cosmo.acegisecurity.providers.ticket; - -import java.io.IOException; -import java.util.Set; - -import jakarta.servlet.Filter; -import jakarta.servlet.FilterChain; -import jakarta.servlet.FilterConfig; -import jakarta.servlet.ServletException; -import jakarta.servlet.ServletRequest; -import jakarta.servlet.ServletResponse; -import jakarta.servlet.http.HttpServletRequest; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContext; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.stereotype.Component; -import org.unitedinternet.cosmo.server.ServerUtils; - -/** - * Servlet filter that populates the - * {@link org.springframework.security.ContextHolder} with a - * {@link TicketAuthenticationToken} if needed. - */ -@Component -public class TicketProcessingFilter implements Filter { - - private static final Logger LOG = LoggerFactory.getLogger(TicketProcessingFilter.class); - - // Filter methods - - /** - * Does nothing - we use IoC lifecycle methods instead. - * @param filterConfig The filter config. - * @throws ServletException - if something is wrong this exception is thrown. - */ - public void init(FilterConfig filterConfig) throws ServletException { - } - - /** - * Examines HTTP servlet requests for ticket keys, creating a - * {@link TicketAuthenticationToken} if any are found. - * - * Tokens are created with the - * {@link #createAuthentication(String, Set)} method. - * - * A token's path is the path info of the request URI less any - * trailing "/", or "/" if the URI represents the root resource. - * @param request The servlet request. - * @param response The servlet response. - * @param chain The filter chain. - * @throws IOException - if something is wrong this exception is thrown. - * @throws ServletException - if something is wrong this exception is thrown. - */ - public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) - throws IOException, ServletException { - SecurityContext sc = SecurityContextHolder.getContext(); - if (sc.getAuthentication() == null && request instanceof HttpServletRequest) { - HttpServletRequest httpRequest = (HttpServletRequest) request; - Set keys = ServerUtils.findTicketKeys(httpRequest); - - if (! keys.isEmpty()) { - String path = httpRequest.getPathInfo(); - if (path == null || path.equals("")) { - path = "/"; - } - if (! path.equals("/") && path.endsWith("/")) { - path = path.substring(0, path.length()-1); - } - // XXX: refactor so this path prefix is not - // hardcoded .. or look at making security happen - // after url-rewriting, not before - if (path.startsWith("/atom/1.0")) { - path = path.substring(9); - } - - Authentication token = createAuthentication(path, keys); - sc.setAuthentication(token); - if (LOG.isDebugEnabled()) { - LOG.debug("Replaced ContextHolder with ticket token: " + - sc.getAuthentication()); - } - } - } - - chain.doFilter(request, response); - } - - /** - * Does nothing - we use IoC lifecycle methods instead - */ - public void destroy() { - } - - // our methods - - /** - * Returns a {@link TicketAuthenticationToken} for the given - * path and ticket keys. - * @param path The given path. - * @param keys The ticket keys. - * @return The authentication. - */ - protected Authentication createAuthentication(String path, Set keys) { - return new TicketAuthenticationToken(path, keys); - } -} diff --git a/cosmo-core/src/main/java/org/unitedinternet/cosmo/acegisecurity/providers/ticket/TicketVoter.java b/cosmo-core/src/main/java/org/unitedinternet/cosmo/acegisecurity/providers/ticket/TicketVoter.java deleted file mode 100644 index b60fd086..00000000 --- a/cosmo-core/src/main/java/org/unitedinternet/cosmo/acegisecurity/providers/ticket/TicketVoter.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 2005-2006 Open Source Applications Foundation - * - * 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 org.unitedinternet.cosmo.acegisecurity.providers.ticket; - -import java.util.Collection; - -import org.springframework.security.access.AccessDecisionVoter; -import org.springframework.security.access.ConfigAttribute; -import org.springframework.security.core.Authentication; -import org.springframework.security.web.FilterInvocation; -import org.unitedinternet.cosmo.dav.CaldavMethodType; -import org.unitedinternet.cosmo.model.Ticket; -import org.unitedinternet.cosmo.model.TicketType; - -/** - * Votes affirmatively if the authenticated principal is a ticket and - * the ticket has the privilege required by the requested WebDAV - * method. - * - * This is a temporary approach until a full ACL system is in place. - */ -public class TicketVoter implements AccessDecisionVoter { - - /** - * @param authentication The authentication. - * @param object The obj. - * @param attributes The attributes. - * @return The type of access. - */ - @Override - public int vote(Authentication authentication, Object object, Collection attributes) { - if (! (authentication instanceof TicketAuthenticationToken)) { - return ACCESS_ABSTAIN; - } - - Ticket ticket = (Ticket) authentication.getPrincipal(); - - FilterInvocation fi = (FilterInvocation) object; - String method = fi.getHttpRequest().getMethod(); - - // freebusy reports and certain propfinds have their own rules, and - // since we haven't parsed the request body yet, we have to defer - // authorization to the servlet layer - if (method.equals("REPORT") || - method.equals("PROPFIND")) { - return ACCESS_GRANTED; - } - - // you can't make or delete a ticket with another ticket - if (method.equals("MKTICKET") || method.equals("DELTICKET")) { - return ACCESS_DENIED; - } - - if (CaldavMethodType.isReadMethod(method)) { - return ticket.getPrivileges().contains(TicketType.PRIVILEGE_READ) ? - ACCESS_GRANTED : - ACCESS_DENIED; - } - - if (CaldavMethodType.isWriteMethod(method)) { - return ticket.getPrivileges().contains(TicketType.PRIVILEGE_WRITE) ? - ACCESS_GRANTED : - ACCESS_DENIED; - } - - return ACCESS_ABSTAIN; - } - - /** - * Always returns true, since this voter does not examine any - * config attributes. - * @param attribute The config attribute. - * @return True. - */ - public boolean supports(ConfigAttribute attribute) { - return true; - } - - /** - * Returns true if the secure object is a - * {@link org.springframework.security.intercept.web.FilterInvocation} - * @param clazz Clazz. - * @return boolean. - */ - public boolean supports(Class clazz) { - return FilterInvocation.class.isAssignableFrom(clazz); - } -} diff --git a/cosmo-core/src/main/java/org/unitedinternet/cosmo/boot/DelegatingAuthenticationFilter.java b/cosmo-core/src/main/java/org/unitedinternet/cosmo/boot/DelegatingAuthenticationFilter.java new file mode 100644 index 00000000..6cc29b52 --- /dev/null +++ b/cosmo-core/src/main/java/org/unitedinternet/cosmo/boot/DelegatingAuthenticationFilter.java @@ -0,0 +1,67 @@ +package org.unitedinternet.cosmo.boot; + +import java.io.IOException; +import java.util.Optional; + +import org.jspecify.annotations.NonNull; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.web.authentication.AuthenticationConverter; +import org.springframework.security.web.authentication.AuthenticationFilter; +import org.springframework.security.web.authentication.Http403ForbiddenEntryPoint; +import org.springframework.security.web.util.matcher.AnyRequestMatcher; +import org.springframework.security.web.util.matcher.RequestMatcher; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +/** + * Derived AuthenticationFilter which replaces unusable defaults with more sensible ones + */ +@SuppressWarnings("unused") +public final class DelegatingAuthenticationFilter extends AuthenticationFilter { + + private static final Logger LOG = LoggerFactory.getLogger(DelegatingAuthenticationFilter.class); + + public DelegatingAuthenticationFilter(AuthenticationManager authenticationManager, + AuthenticationConverter authenticationConverter) { + this(authenticationManager, authenticationConverter, AnyRequestMatcher.INSTANCE); + } + + public DelegatingAuthenticationFilter(AuthenticationManager authenticationManager, + AuthenticationConverter authenticationConverter, RequestMatcher requestMatcher) { + super(authenticationManager, authenticationConverter); + // 403 instead of 401, as in Webflux + setFailureHandler(DelegatingAuthenticationFilter::handleAuthenticationFailuresAsForbidden); + // prevent redirect which should only be done for sessions + setSuccessHandler((request, response, auth) -> { + }); + setRequestMatcher(requestMatcher); + } + + @Override + @NonNull + protected String getAlreadyFilteredAttributeName() { + return getAuthenticationConverter().getClass().getName() + "_and_" + + getAuthenticationManagerResolver().getClass().getName(); + } + + /** + * @return RequestMatcher which matches whenever not yet authenticated. This is especially useful when a mocked + * authentication should override any functional one. + */ + public static RequestMatcher needsAuthenticationRequestMatcher() { + return request -> Optional.ofNullable(SecurityContextHolder.getContext().getAuthentication()) + .filter(Authentication::isAuthenticated).isEmpty(); + } + + private static void handleAuthenticationFailuresAsForbidden(HttpServletRequest request, + HttpServletResponse response, AuthenticationException exception) throws IOException { + LOG.debug("Handling AuthenticationException as 403 Forbidden", exception); + new Http403ForbiddenEntryPoint().commence(request, response, exception); + } +} diff --git a/cosmo-core/src/main/java/org/unitedinternet/cosmo/boot/SecurityFilterConfig.java b/cosmo-core/src/main/java/org/unitedinternet/cosmo/boot/SecurityFilterConfig.java index 60d07263..744013b5 100644 --- a/cosmo-core/src/main/java/org/unitedinternet/cosmo/boot/SecurityFilterConfig.java +++ b/cosmo-core/src/main/java/org/unitedinternet/cosmo/boot/SecurityFilterConfig.java @@ -1,29 +1,21 @@ package org.unitedinternet.cosmo.boot; -import java.util.Collection; -import java.util.LinkedHashMap; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter; -import org.springframework.security.access.ConfigAttribute; -import org.springframework.security.access.SecurityConfig; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.web.DefaultSecurityFilterChain; import org.springframework.security.web.FilterChainProxy; import org.springframework.security.web.SecurityFilterChain; -import org.springframework.security.web.access.intercept.DefaultFilterInvocationSecurityMetadataSource; -import org.springframework.security.web.access.intercept.FilterSecurityInterceptor; +import org.springframework.security.web.access.intercept.AuthorizationFilter; import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; import org.springframework.security.web.firewall.HttpFirewall; import org.springframework.security.web.util.matcher.AnyRequestMatcher; -import org.springframework.security.web.util.matcher.RequestMatcher; import org.springframework.web.context.support.HttpRequestHandlerServlet; -import org.unitedinternet.cosmo.acegisecurity.providers.ticket.ExtraTicketProcessingFilter; -import org.unitedinternet.cosmo.acegisecurity.providers.ticket.TicketProcessingFilter; +import org.unitedinternet.cosmo.acegisecurity.providers.ticket.TicketAuthenticationConverter; import org.unitedinternet.cosmo.acegisecurity.ui.CosmoAuthenticationEntryPoint; import org.unitedinternet.cosmo.dav.acegisecurity.DavAccessDecisionManager; import org.unitedinternet.cosmo.dav.servlet.StandardRequestHandler; @@ -36,23 +28,15 @@ * */ @Configuration -@SuppressWarnings("serial") public class SecurityFilterConfig { - public static final String PATH_DAV = "/dav/*"; - public static final String ROLES = "ROLES_WE_DONT_HAVE"; + public static final String PATH_DAV = "/dav/*"; /** * @see StandardRequestHandler component. */ private static final String DAV_SERVLET_NAME = "davRequestHandler"; - @Autowired - private ExtraTicketProcessingFilter extraTicketFilter; - - @Autowired - private TicketProcessingFilter ticketFilter; - @Autowired private CosmoAuthenticationEntryPoint authEntryPoint; @@ -93,19 +77,16 @@ public FilterRegistrationBean openEntityManagerInViewFilter() { @Bean public FilterRegistrationBean securityFilterChain() { - FilterSecurityInterceptor securityFilter = new FilterSecurityInterceptor(); - securityFilter.setAuthenticationManager(this.authManager); - securityFilter.setAccessDecisionManager(this.davDecisionManager); - LinkedHashMap> metadata = new LinkedHashMap>(); - metadata.put(AnyRequestMatcher.INSTANCE, SecurityConfig.createList(ROLES)); - securityFilter.setSecurityMetadataSource(new DefaultFilterInvocationSecurityMetadataSource(metadata)); - + AuthorizationFilter autorizationFilter = new AuthorizationFilter(this.davDecisionManager); + DelegatingAuthenticationFilter delegatingAuthenticationFilter = new DelegatingAuthenticationFilter( + this.authManager, new TicketAuthenticationConverter()); /* * Note that the order in which filters are defined is highly important. */ SecurityFilterChain filterChain = new DefaultSecurityFilterChain(AnyRequestMatcher.INSTANCE, - this.cosmoExceptionFilter, this.extraTicketFilter, this.ticketFilter, - new BasicAuthenticationFilter(authManager, this.authEntryPoint), securityFilter); + this.cosmoExceptionFilter, + delegatingAuthenticationFilter, + new BasicAuthenticationFilter(authManager, this.authEntryPoint), autorizationFilter); FilterChainProxy proxy = new FilterChainProxy(filterChain); proxy.setFirewall(this.httpFirewall); FilterRegistrationBean filterBean = new FilterRegistrationBean<>(proxy); diff --git a/cosmo-core/src/main/java/org/unitedinternet/cosmo/dao/hibernate/CalendarDaoImpl.java b/cosmo-core/src/main/java/org/unitedinternet/cosmo/dao/hibernate/CalendarDaoImpl.java index d5d69091..bb7c1324 100644 --- a/cosmo-core/src/main/java/org/unitedinternet/cosmo/dao/hibernate/CalendarDaoImpl.java +++ b/cosmo-core/src/main/java/org/unitedinternet/cosmo/dao/hibernate/CalendarDaoImpl.java @@ -27,7 +27,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.orm.hibernate5.SessionFactoryUtils; +import org.springframework.orm.jpa.EntityManagerFactoryUtils; import org.springframework.stereotype.Repository; import org.unitedinternet.cosmo.calendar.query.CalendarFilter; import org.unitedinternet.cosmo.calendar.query.CalendarFilterEvaluater; @@ -147,7 +147,7 @@ public Set findCalendarItems(CollectionItem collection, CalendarF return results; } catch (HibernateException e) { this.em.clear(); - throw SessionFactoryUtils.convertHibernateAccessException(e); + throw EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(e); } } @@ -175,7 +175,7 @@ public Set findEvents(CollectionItem collection, Date rangeStart, Date ran return itemFilterProcessor.processFilter(itemFilter); } catch (HibernateException e) { this.em.clear(); - throw SessionFactoryUtils.convertHibernateAccessException(e); + throw EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(e); } } @@ -196,7 +196,7 @@ public ContentItem findEventByIcalUid(String uid, CollectionItem calendar) { return null; } catch (HibernateException e) { this.em.clear(); - throw SessionFactoryUtils.convertHibernateAccessException(e); + throw EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(e); } } diff --git a/cosmo-core/src/main/java/org/unitedinternet/cosmo/dao/hibernate/UserDaoImpl.java b/cosmo-core/src/main/java/org/unitedinternet/cosmo/dao/hibernate/UserDaoImpl.java index d7ad2e26..1d2a7641 100644 --- a/cosmo-core/src/main/java/org/unitedinternet/cosmo/dao/hibernate/UserDaoImpl.java +++ b/cosmo-core/src/main/java/org/unitedinternet/cosmo/dao/hibernate/UserDaoImpl.java @@ -25,7 +25,7 @@ import org.hibernate.HibernateException; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.orm.hibernate5.SessionFactoryUtils; +import org.springframework.orm.jpa.EntityManagerFactoryUtils; import org.springframework.stereotype.Repository; import org.unitedinternet.cosmo.dao.DuplicateEmailException; import org.unitedinternet.cosmo.dao.DuplicateUsernameException; @@ -107,7 +107,7 @@ public void removeUser(String username) { } } catch (HibernateException e) { this.em.clear(); - throw SessionFactoryUtils.convertHibernateAccessException(e); + throw EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(e); } } diff --git a/cosmo-core/src/main/java/org/unitedinternet/cosmo/dav/acegisecurity/DavAccessDecisionManager.java b/cosmo-core/src/main/java/org/unitedinternet/cosmo/dav/acegisecurity/DavAccessDecisionManager.java index 1115e1a3..a26518e9 100644 --- a/cosmo-core/src/main/java/org/unitedinternet/cosmo/dav/acegisecurity/DavAccessDecisionManager.java +++ b/cosmo-core/src/main/java/org/unitedinternet/cosmo/dav/acegisecurity/DavAccessDecisionManager.java @@ -15,17 +15,19 @@ */ package org.unitedinternet.cosmo.dav.acegisecurity; -import java.util.Collection; +import java.util.function.Supplier; import jakarta.servlet.http.HttpServletRequest; +import org.jspecify.annotations.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.security.access.AccessDecisionManager; import org.springframework.security.access.AccessDeniedException; -import org.springframework.security.access.ConfigAttribute; import org.springframework.security.authentication.InsufficientAuthenticationException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.authorization.AuthorizationDecision; +import org.springframework.security.authorization.AuthorizationManager; +import org.springframework.security.authorization.AuthorizationResult; import org.springframework.security.core.Authentication; import org.springframework.security.web.FilterInvocation; import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken; @@ -53,7 +55,7 @@ */ @Service public class DavAccessDecisionManager - implements AccessDecisionManager, ExtendedDavConstants { + implements AuthorizationManager , ExtendedDavConstants { private static final Logger LOG = LoggerFactory.getLogger(DavAccessDecisionManager.class); @@ -77,10 +79,10 @@ public DavAccessDecisionManager(UserService userService) { * {@link TicketAuthenticationToken}. */ @Override - public void decide(Authentication authentication, Object object, - Collection configAttributes) + public AuthorizationResult authorize(Supplier authenticationSupplier, HttpServletRequest object) throws AccessDeniedException, InsufficientAuthenticationException { AclEvaluator evaluator = null; + Authentication authentication = authenticationSupplier.get(); if (authentication instanceof UsernamePasswordAuthenticationToken) { CosmoUserDetails details = (CosmoUserDetails) authentication.getPrincipal(); @@ -96,8 +98,7 @@ public void decide(Authentication authentication, Object object, throw new InsufficientAuthenticationException("Unrecognized authentication token"); } - HttpServletRequest request = - ((FilterInvocation) object).getHttpRequest(); + HttpServletRequest request = object; String path = request.getPathInfo(); if (path == null) { @@ -110,20 +111,13 @@ public void decide(Authentication authentication, Object object, try { match(path, request.getMethod(), evaluator); + return new AuthorizationDecision(true); } catch (AclEvaluationException e) { throw new DavAccessDeniedException(request.getRequestURI(), e.getPrivilege()); } } - /** - * Always returns true, as this manager does not support any - * config attributes. - */ - public boolean supports(ConfigAttribute attribute) { - return true; - } - /** * Returns true if the secure object is a * {@link FilterInvocation}. diff --git a/cosmo-core/src/main/java/org/unitedinternet/cosmo/dav/impl/StandardDavResponse.java b/cosmo-core/src/main/java/org/unitedinternet/cosmo/dav/impl/StandardDavResponse.java index 2f125baf..5bbd6de1 100644 --- a/cosmo-core/src/main/java/org/unitedinternet/cosmo/dav/impl/StandardDavResponse.java +++ b/cosmo-core/src/main/java/org/unitedinternet/cosmo/dav/impl/StandardDavResponse.java @@ -125,6 +125,11 @@ public void setCharacterEncoding(String charset) { public void sendRedirect(String location) throws IOException { originalHttpServletResponse.sendRedirect(location); } + + @Override + public void sendRedirect(String location, int sc, boolean clearBuffer) throws IOException{ + originalHttpServletResponse.sendRedirect(location, sc, clearBuffer); + } public void setDateHeader(String name, long date) { diff --git a/cosmo-core/src/main/java/org/unitedinternet/cosmo/hibernate/CompoundInterceptor.java b/cosmo-core/src/main/java/org/unitedinternet/cosmo/hibernate/CompoundInterceptor.java index ec92c34f..722a6245 100644 --- a/cosmo-core/src/main/java/org/unitedinternet/cosmo/hibernate/CompoundInterceptor.java +++ b/cosmo-core/src/main/java/org/unitedinternet/cosmo/hibernate/CompoundInterceptor.java @@ -15,45 +15,41 @@ */ package org.unitedinternet.cosmo.hibernate; -import java.io.Serializable; import java.util.List; -import org.hibernate.EmptyInterceptor; import org.hibernate.Interceptor; import org.hibernate.type.Type; /** * Hibernate Interceptor supports invoking multiple Interceptors */ -public class CompoundInterceptor extends EmptyInterceptor { +public class CompoundInterceptor implements Interceptor { - private static final long serialVersionUID = 1L; private List interceptors; @Override - public boolean onFlushDirty(Object object, Serializable id, Object[] currentState, Object[] previousState, - String[] propertyNames, Type[] types) { + public boolean onFlushDirty(Object entity, Object id, Object[] currentState, Object[] previousState, + String[] propertyNames, Type[] types) { boolean modified = false; for(Interceptor i: interceptors){ - modified = modified | i.onFlushDirty(object, id, currentState, previousState, propertyNames, types); + modified = modified | i.onFlushDirty(entity, id, currentState, previousState, propertyNames, types); } return modified; } @Override - public boolean onSave(Object object, Serializable id, Object[] state, String[] propertyNames, Type[] types) { + public boolean onPersist(Object entity, Object id, Object[] state, String[] propertyNames, Type[] types) { boolean modified = false; for(Interceptor i: interceptors){ - modified = modified | i.onSave(object, id, state, propertyNames, types); + modified = modified | i.onPersist(entity, id, state, propertyNames, types); } return modified; } @Override - public void onDelete(Object entity, Serializable id, Object[] state, - String[] propertyNames, Type[] types) { + public void onRemove(Object entity, Object id, Object[] state, String[] propertyNames, Type[] types) { for(Interceptor i: interceptors) { - i.onDelete(entity, id, state, propertyNames, types); + i.onRemove(entity, id, state, propertyNames, types); } } diff --git a/cosmo-core/src/main/java/org/unitedinternet/cosmo/hibernate/HibernateAdditionalConfiguration.java b/cosmo-core/src/main/java/org/unitedinternet/cosmo/hibernate/HibernateAdditionalConfiguration.java index 1a3a332e..e62ec3a8 100644 --- a/cosmo-core/src/main/java/org/unitedinternet/cosmo/hibernate/HibernateAdditionalConfiguration.java +++ b/cosmo-core/src/main/java/org/unitedinternet/cosmo/hibernate/HibernateAdditionalConfiguration.java @@ -6,7 +6,7 @@ import org.hibernate.Interceptor; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.orm.jpa.HibernatePropertiesCustomizer; +import org.springframework.boot.hibernate.autoconfigure.HibernatePropertiesCustomizer; import org.springframework.context.annotation.Configuration; import org.unitedinternet.cosmo.model.hibernate.AuditableObjectInterceptor; import org.unitedinternet.cosmo.model.hibernate.EventStampInterceptor; diff --git a/cosmo-core/src/main/java/org/unitedinternet/cosmo/model/hibernate/AuditableObjectInterceptor.java b/cosmo-core/src/main/java/org/unitedinternet/cosmo/model/hibernate/AuditableObjectInterceptor.java index 0e957b3d..b6f94fac 100644 --- a/cosmo-core/src/main/java/org/unitedinternet/cosmo/model/hibernate/AuditableObjectInterceptor.java +++ b/cosmo-core/src/main/java/org/unitedinternet/cosmo/model/hibernate/AuditableObjectInterceptor.java @@ -15,9 +15,7 @@ */ package org.unitedinternet.cosmo.model.hibernate; -import java.io.Serializable; - -import org.hibernate.EmptyInterceptor; +import org.hibernate.Interceptor; import org.hibernate.type.Type; import org.springframework.stereotype.Component; @@ -26,20 +24,22 @@ * and etag each time an AuditableObject is saved/updated. */ @Component -public class AuditableObjectInterceptor extends EmptyInterceptor { - - private static final long serialVersionUID = 2206186604411196082L; +public class AuditableObjectInterceptor implements Interceptor { @Override - public boolean onFlushDirty(Object object, Serializable id, Object[] currentState, - Object[] previousState, String[] propertyNames, Type[] types) { - if(! (object instanceof HibAuditableObject)) { + public boolean onFlushDirty(Object entity, + Object id, + Object[] currentState, + Object[] previousState, + String[] propertyNames, + Type[] types) { + if(! (entity instanceof HibAuditableObject)) { return false; } // Set new modifyDate so that calculateEntityTag() // has access to it - HibAuditableObject ao = (HibAuditableObject) object; + HibAuditableObject ao = (HibAuditableObject) entity; Long currentTime = System.currentTimeMillis(); ao.setModifiedDate(currentTime); @@ -55,15 +55,15 @@ public boolean onFlushDirty(Object object, Serializable id, Object[] currentStat } @Override - public boolean onSave(Object object, Serializable id, Object[] state, String[] propertyNames, Type[] types) { + public boolean onPersist(Object entity, Object id, Object[] state, String[] propertyNames, Type[] types) { - if(! (object instanceof HibAuditableObject)) { + if(! (entity instanceof HibAuditableObject)) { return false; } // Set new modifyDate so that calculateEntityTag() // has access to it - HibAuditableObject ao = (HibAuditableObject) object; + HibAuditableObject ao = (HibAuditableObject) entity; Long currentTime = System.currentTimeMillis(); ao.setModifiedDate(currentTime); diff --git a/cosmo-core/src/main/java/org/unitedinternet/cosmo/model/hibernate/EventStampInterceptor.java b/cosmo-core/src/main/java/org/unitedinternet/cosmo/model/hibernate/EventStampInterceptor.java index 81a7bf37..6b419ef1 100644 --- a/cosmo-core/src/main/java/org/unitedinternet/cosmo/model/hibernate/EventStampInterceptor.java +++ b/cosmo-core/src/main/java/org/unitedinternet/cosmo/model/hibernate/EventStampInterceptor.java @@ -15,10 +15,9 @@ */ package org.unitedinternet.cosmo.model.hibernate; -import java.io.Serializable; import java.time.temporal.TemporalAmount; -import org.hibernate.EmptyInterceptor; +import org.hibernate.Interceptor; import org.hibernate.type.Type; import org.springframework.stereotype.Component; import org.unitedinternet.cosmo.calendar.RecurrenceExpander; @@ -33,19 +32,17 @@ * Hibernate Interceptor that updates BaseEventStamp timeRangeIndexes. */ @Component -public class EventStampInterceptor extends EmptyInterceptor { - - private static final long serialVersionUID = 5339230223113722458L; +public class EventStampInterceptor implements Interceptor { @Override - public boolean onFlushDirty(Object object, Serializable id, Object[] currentState, + public boolean onFlushDirty(Object entity, Object id, Object[] currentState, Object[] previousState, String[] propertyNames, Type[] types) { - if(! (object instanceof HibBaseEventStamp)) { + if(! (entity instanceof HibBaseEventStamp)) { return false; } // calculate time-range-index - HibBaseEventStamp es = (HibBaseEventStamp) object; + HibBaseEventStamp es = (HibBaseEventStamp) entity; HibEventTimeRangeIndex index = calculateEventStampIndexes(es); if(index==null) { @@ -64,14 +61,14 @@ public boolean onFlushDirty(Object object, Serializable id, Object[] currentStat } @Override - public boolean onSave(Object object, Serializable id, Object[] state, String[] propertyNames, Type[] types) { + public boolean onPersist(Object entity, Object id, Object[] state, String[] propertyNames, Type[] types) { - if(! (object instanceof HibBaseEventStamp)) { + if(! (entity instanceof HibBaseEventStamp)) { return false; } // calculate time-range-index - HibBaseEventStamp es = (HibBaseEventStamp) object; + HibBaseEventStamp es = (HibBaseEventStamp) entity; HibEventTimeRangeIndex index = calculateEventStampIndexes(es); if(index==null) { diff --git a/cosmo-core/src/main/java/org/unitedinternet/cosmo/model/hibernate/HibAttribute.java b/cosmo-core/src/main/java/org/unitedinternet/cosmo/model/hibernate/HibAttribute.java index 27286905..049e137e 100644 --- a/cosmo-core/src/main/java/org/unitedinternet/cosmo/model/hibernate/HibAttribute.java +++ b/cosmo-core/src/main/java/org/unitedinternet/cosmo/model/hibernate/HibAttribute.java @@ -17,7 +17,7 @@ import org.hibernate.annotations.Cache; import org.hibernate.annotations.CacheConcurrencyStrategy; -import org.hibernate.annotations.Target; +import org.hibernate.annotations.TargetEmbeddable; import org.unitedinternet.cosmo.model.Attribute; import org.unitedinternet.cosmo.model.Item; import org.unitedinternet.cosmo.model.QName; @@ -54,7 +54,7 @@ public abstract class HibAttribute extends HibAuditableObject implements Attribu // Fields @Embedded - @Target(HibQName.class) + @TargetEmbeddable(HibQName.class) private QName qname; @ManyToOne(targetEntity = HibItem.class, fetch = FetchType.LAZY) diff --git a/cosmo-core/src/main/java/org/unitedinternet/cosmo/model/hibernate/HibAttributeTombstone.java b/cosmo-core/src/main/java/org/unitedinternet/cosmo/model/hibernate/HibAttributeTombstone.java index 72e38997..d076805d 100644 --- a/cosmo-core/src/main/java/org/unitedinternet/cosmo/model/hibernate/HibAttributeTombstone.java +++ b/cosmo-core/src/main/java/org/unitedinternet/cosmo/model/hibernate/HibAttributeTombstone.java @@ -24,7 +24,7 @@ import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; -import org.hibernate.annotations.Target; +import org.hibernate.annotations.TargetEmbeddable; import org.unitedinternet.cosmo.model.Attribute; import org.unitedinternet.cosmo.model.AttributeTombstone; import org.unitedinternet.cosmo.model.Item; @@ -39,7 +39,7 @@ public class HibAttributeTombstone extends HibTombstone implements AttributeTomb private static final long serialVersionUID = -5316512272555844439L; @Embedded - @Target(HibQName.class) + @TargetEmbeddable(HibQName.class) @AttributeOverrides( { @AttributeOverride(name="namespace", column = @Column(name="namespace", length=255) ), @AttributeOverride(name="localName", column = @Column(name="localname", length=255) ) diff --git a/cosmo-core/src/main/java/org/unitedinternet/cosmo/model/hibernate/HibCollectionItem.java b/cosmo-core/src/main/java/org/unitedinternet/cosmo/model/hibernate/HibCollectionItem.java index 7a0b30ab..84490f88 100644 --- a/cosmo-core/src/main/java/org/unitedinternet/cosmo/model/hibernate/HibCollectionItem.java +++ b/cosmo-core/src/main/java/org/unitedinternet/cosmo/model/hibernate/HibCollectionItem.java @@ -21,13 +21,13 @@ import java.util.HashSet; import java.util.Set; +import jakarta.persistence.CascadeType; import jakarta.persistence.DiscriminatorValue; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; import jakarta.persistence.OneToMany; -import org.hibernate.annotations.Cascade; -import org.hibernate.annotations.CascadeType; + import org.unitedinternet.cosmo.model.CollectionItem; import org.unitedinternet.cosmo.model.CollectionItemDetails; import org.unitedinternet.cosmo.model.Item; @@ -46,8 +46,7 @@ public class HibCollectionItem extends HibItem implements CollectionItem { private static final long serialVersionUID = 2873258323314048223L; - @OneToMany(targetEntity=HibCollectionItemDetails.class, mappedBy="primaryKey.collection", fetch=FetchType.LAZY) - @Cascade( {CascadeType.DELETE }) + @OneToMany(targetEntity=HibCollectionItemDetails.class, mappedBy="primaryKey.collection", fetch=FetchType.LAZY, cascade = CascadeType.REMOVE) private Set childDetails = new HashSet(0); private transient Set children = null; diff --git a/cosmo-core/src/main/java/org/unitedinternet/cosmo/model/hibernate/HibContentItem.java b/cosmo-core/src/main/java/org/unitedinternet/cosmo/model/hibernate/HibContentItem.java index fe94625f..32162107 100644 --- a/cosmo-core/src/main/java/org/unitedinternet/cosmo/model/hibernate/HibContentItem.java +++ b/cosmo-core/src/main/java/org/unitedinternet/cosmo/model/hibernate/HibContentItem.java @@ -20,7 +20,7 @@ import jakarta.persistence.Embedded; import jakarta.persistence.Entity; -import org.hibernate.annotations.Target; +import org.hibernate.annotations.TargetEmbeddable; import org.unitedinternet.cosmo.model.ContentItem; import org.unitedinternet.cosmo.model.Item; import org.unitedinternet.cosmo.model.TriageStatus; @@ -44,7 +44,7 @@ public abstract class HibContentItem extends HibItem implements ContentItem { private Integer lastModification = null; @Embedded - @Target(HibTriageStatus.class) + @TargetEmbeddable(HibTriageStatus.class) private TriageStatus triageStatus = new HibTriageStatus(); @Column(name = "sent", columnDefinition = "tinyint(4)") diff --git a/cosmo-core/src/main/java/org/unitedinternet/cosmo/model/hibernate/HibNoteItem.java b/cosmo-core/src/main/java/org/unitedinternet/cosmo/model/hibernate/HibNoteItem.java index 90c72e66..018e6a5d 100644 --- a/cosmo-core/src/main/java/org/unitedinternet/cosmo/model/hibernate/HibNoteItem.java +++ b/cosmo-core/src/main/java/org/unitedinternet/cosmo/model/hibernate/HibNoteItem.java @@ -21,6 +21,7 @@ import java.util.HashSet; import java.util.Set; +import jakarta.persistence.CascadeType; import jakarta.persistence.Column; import jakarta.persistence.DiscriminatorValue; import jakarta.persistence.Entity; @@ -31,8 +32,6 @@ import org.hibernate.annotations.Cache; import org.hibernate.annotations.CacheConcurrencyStrategy; -import org.hibernate.annotations.Cascade; -import org.hibernate.annotations.CascadeType; import org.unitedinternet.cosmo.hibernate.validator.TaskJournal; import org.unitedinternet.cosmo.model.Item; import org.unitedinternet.cosmo.model.NoteItem; @@ -58,9 +57,7 @@ public class HibNoteItem extends HibICalendarItem implements NoteItem { private static final Set EMPTY_MODS = Collections .unmodifiableSet(new HashSet(0)); - @OneToMany(targetEntity=HibNoteItem.class, mappedBy = "modifies", fetch=FetchType.LAZY) - @Cascade( {CascadeType.DELETE} ) - //@BatchSize(size=50) + @OneToMany(targetEntity=HibNoteItem.class, mappedBy = "modifies", fetch=FetchType.LAZY, cascade = CascadeType.REMOVE) @Cache(usage = CacheConcurrencyStrategy.READ_WRITE) private Set modifications = new HashSet(0); diff --git a/cosmo-core/src/main/java/org/unitedinternet/cosmo/model/hibernate/HibUser.java b/cosmo-core/src/main/java/org/unitedinternet/cosmo/model/hibernate/HibUser.java index c7b55be2..4239b5ae 100644 --- a/cosmo-core/src/main/java/org/unitedinternet/cosmo/model/hibernate/HibUser.java +++ b/cosmo-core/src/main/java/org/unitedinternet/cosmo/model/hibernate/HibUser.java @@ -27,6 +27,7 @@ import jakarta.persistence.Index; import jakarta.persistence.OneToMany; import jakarta.persistence.Table; +import jakarta.validation.constraints.Email; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Pattern; @@ -34,7 +35,6 @@ import org.hibernate.annotations.Cache; import org.hibernate.annotations.CacheConcurrencyStrategy; import org.hibernate.annotations.NaturalId; -import org.hibernate.validator.constraints.Email; import org.hibernate.validator.constraints.Length; import org.unitedinternet.cosmo.model.CollectionSubscription; import org.unitedinternet.cosmo.model.Preference; diff --git a/cosmo-core/src/test/unit/java/org/unitedinternet/cosmo/boot/CalendarTestApplication.java b/cosmo-core/src/test/unit/java/org/unitedinternet/cosmo/boot/CalendarTestApplication.java index 890cf996..cb761a2e 100644 --- a/cosmo-core/src/test/unit/java/org/unitedinternet/cosmo/boot/CalendarTestApplication.java +++ b/cosmo-core/src/test/unit/java/org/unitedinternet/cosmo/boot/CalendarTestApplication.java @@ -4,8 +4,7 @@ import org.springframework.boot.SpringBootConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.autoconfigure.domain.EntityScan; -import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; +import org.springframework.boot.persistence.autoconfigure.EntityScan; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; import org.springframework.context.annotation.ComponentScan; @@ -17,7 +16,7 @@ */ @SpringBootApplication @SpringBootConfiguration -@EnableAutoConfiguration(exclude = SecurityAutoConfiguration.class) +@EnableAutoConfiguration @ComponentScan(basePackages = { "org.unitedinternet.cosmo" }) @EntityScan(basePackages = "org.unitedinternet.cosmo.model.hibernate") public class CalendarTestApplication extends SpringBootServletInitializer { diff --git a/cosmo-webapp/pom.xml b/cosmo-webapp/pom.xml index 35fd968e..117c2bf1 100644 --- a/cosmo-webapp/pom.xml +++ b/cosmo-webapp/pom.xml @@ -5,7 +5,7 @@ cosmo-multimodule net.oneandone.cosmo - 7.0.2 + 8.0.0-SNAPSHOT 4.0.0 @@ -17,7 +17,7 @@ net.oneandone.cosmo cosmo-core - 7.0.2 + 8.0.0-SNAPSHOT diff --git a/cosmo-webapp/src/main/java/com/unitedinternet/calendar/CalendarDemoApplication.java b/cosmo-webapp/src/main/java/com/unitedinternet/calendar/CalendarDemoApplication.java index dadcd901..d6220c75 100644 --- a/cosmo-webapp/src/main/java/com/unitedinternet/calendar/CalendarDemoApplication.java +++ b/cosmo-webapp/src/main/java/com/unitedinternet/calendar/CalendarDemoApplication.java @@ -7,8 +7,7 @@ import org.springframework.boot.SpringBootConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.autoconfigure.domain.EntityScan; -import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; +import org.springframework.boot.persistence.autoconfigure.EntityScan; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; @@ -25,7 +24,7 @@ */ @SpringBootApplication @SpringBootConfiguration -@EnableAutoConfiguration(exclude = SecurityAutoConfiguration.class) +@EnableAutoConfiguration @ComponentScan(basePackages = { "org.unitedinternet.cosmo", "com.unitedinternet.calendar" }) @EntityScan(basePackages = "org.unitedinternet.cosmo.model.hibernate") public class CalendarDemoApplication extends SpringBootServletInitializer { diff --git a/pom.xml b/pom.xml index c4cc1c9f..0541bb71 100644 --- a/pom.xml +++ b/pom.xml @@ -1,18 +1,18 @@ - 4.0.0 net.oneandone.cosmo cosmo-multimodule - 7.1.2-SNAPSHOT + 8.0.0-SNAPSHOT pom cosmo-multimodule CalDAV core implementation server @@ -20,30 +20,30 @@ UTF-8 - - 17 - 17 - + + 25 + 25 + false UTF-8 - - 3.4.5 - + + 4.0.5 + 3.0.1 3.2.14 - + 1.9.22.1 - 3.4.0 + 3.4.0 2.12.2 1.6.1 1.0.1 4.0.6 - + 2.18.3 1.1.3 5.10.3 - + true true @@ -52,19 +52,20 @@ true false true - - - 4.7.3.4 - 3.6.0 - 2.5.3 - 3.0.1 - 3.0.1 - 1.6 - 3.0 - 3.2.5 - 3.4.0 - 3.13.0 - + + + 4.7.3.4 + 3.6.0 + 2.5.3 + 3.0.1 + 3.0.1 + 1.6 + 3.0 + 3.5.5 + 3.4.0 + 3.13.0 + 3.5.0 + @@ -74,7 +75,7 @@ - + org.springframework.boot @@ -83,7 +84,7 @@ pom import - + @@ -114,14 +115,14 @@ mariadb-java-client ${mariadb.version} - + dev.atchison.mariaDB4j mariaDB4j test 2.7.2 - + dev.atchison.mariaDB4j mariaDB4j-db-linux64 @@ -140,8 +141,8 @@ commons-logging - org.slf4j - slf4j-log4j12 + org.slf4j + slf4j-log4j12 commons-codec @@ -149,7 +150,7 @@ - + net.oneandone jackrabbit-webdav @@ -165,13 +166,13 @@ - + org.aspectj aspectjweaver ${aspectjweaver.version} - + xerces xercesImpl @@ -186,7 +187,7 @@ - org.apache.abdera @@ -230,7 +231,7 @@ - + com.fasterxml.jackson.core jackson-core @@ -241,18 +242,18 @@ jackson-databind ${jackson.version} - + org.apache.commons commons-text - 1.12.0 + 1.12.0 commons-io commons-io 2.16.1 - + org.junit.jupiter @@ -262,7 +263,7 @@ - + @@ -291,7 +292,7 @@ SLASHSTAR_STYLE - + @@ -300,18 +301,18 @@ ${maven-javadoc-plugin.version} none - true + true - + org.apache.maven.plugins maven-compiler-plugin - ${maven-compiler-plugin.version} + ${maven-compiler-plugin.version} true - -parameters + -parameters @@ -319,7 +320,7 @@ maven-gpg-plugin ${maven-gpg-plugin.version} - + org.apache.maven.plugins maven-release-plugin @@ -334,7 +335,13 @@ true - + + + org.apache.maven.plugins + maven-jar-plugin + ${maven-jar-plugin.version} + + @@ -347,7 +354,7 @@ false checkstyle-suppressions.xml - + @@ -429,7 +436,7 @@ developer - - - + + +