From 82f50a65ced449e264bc6863df005eb0bc873e01 Mon Sep 17 00:00:00 2001 From: Bernd Ritter Date: Fri, 20 Dec 2024 16:35:42 +0100 Subject: [PATCH] Pagination + Login/Logout mit Meldung --- .../auth/web/SecureAccountFailureHandler.java | 21 ++++++--- .../db/repositories/NewsRepository.java | 5 +-- .../java/de/holarse/config/AppConfig.java | 6 +++ .../config/MultipleHttpSecurityConfig.java | 10 +++-- .../web/controller/LoginController.java | 5 ++- .../web/controller/NewsController.java | 5 ++- .../web/controller/WelcomeController.java | 4 +- .../WEB-INF/templates/sites/news/index.html | 10 +++-- .../templates/sites/search/pagination.html | 6 +-- .../templates/sites/sessions/login.html | 44 ++++++++++++++++++- 10 files changed, 89 insertions(+), 27 deletions(-) diff --git a/src/main/java/de/holarse/auth/web/SecureAccountFailureHandler.java b/src/main/java/de/holarse/auth/web/SecureAccountFailureHandler.java index c7914140..25ec2b53 100644 --- a/src/main/java/de/holarse/auth/web/SecureAccountFailureHandler.java +++ b/src/main/java/de/holarse/auth/web/SecureAccountFailureHandler.java @@ -44,8 +44,7 @@ public void onAuthenticationFailure(final HttpServletRequest request, final String username = request.getParameter("username"); - - log.debug("Login für User " + username + " fehlgeschlagen.", exception); + log.debug("Login für User {} fehlgeschlagen.", username, exception); final User user = userRepository.findByLogin(username); if (user != null) { @@ -54,18 +53,28 @@ public void onAuthenticationFailure(final HttpServletRequest request, userStatus.setFailedLogins(user.getStatus().getFailedLogins() + 1); userStatus.setUpdated(OffsetDateTime.now()); + log.info("Benutzer {} hat nun {} fehlgeschlagene Login-Versuche.", username, user.getStatus().getFailedLogins()); + if (!userStatus.isLocked() && hasTooManyFailedAttempts(userStatus)) { userStatus.setLocked(true); log.warn("Benutzer {} wurde wegen zu vielen Fehlversuchen gesperrt.", username); + userStatusRepository.save(userStatus); + super.setDefaultFailureUrl("/login?error=too-many-attempts"); + } else { + log.warn("Benutzer {} ist gesperrt.", username); + super.setDefaultFailureUrl("/login?error=locked"); } - userStatusRepository.save(userStatus); - super.setDefaultFailureUrl("/login?error=locked"); + + } else { log.error("User login {} has no user_status assoc", username); super.setDefaultFailureUrl("/login?error=incomplete"); } - } - + } else { + log.error("User login {} is not known", username); + super.setDefaultFailureUrl("/login?error=invalid"); + } + super.onAuthenticationFailure(request, response, exception); } diff --git a/src/main/java/de/holarse/backend/db/repositories/NewsRepository.java b/src/main/java/de/holarse/backend/db/repositories/NewsRepository.java index 33f23569..2ceaa5a9 100644 --- a/src/main/java/de/holarse/backend/db/repositories/NewsRepository.java +++ b/src/main/java/de/holarse/backend/db/repositories/NewsRepository.java @@ -1,14 +1,13 @@ package de.holarse.backend.db.repositories; -import de.holarse.backend.db.Article; import de.holarse.backend.db.News; import de.holarse.backend.view.FrontpageItemView; +import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; -import java.util.List; import java.util.Optional; import org.springframework.data.repository.query.Param; @@ -20,7 +19,7 @@ public interface NewsRepository extends JpaRepository, NodeAwareR + "JOIN n.nodeStatus as ns " + "JOIN n.nodeSlugz as sl " + "WHERE ns.published and NOT ns.deleted and sl.id = (SELECT max(_sl.id) FROM NodeSlug _sl where _sl.nodeId = n.nodeId)") - List findFrontpageItems(final Pageable pageable); + Page findFrontpageItems(final Pageable pageable); @Query(value = "FROM News n " + "JOIN FETCH n.nodeRevision nr " + diff --git a/src/main/java/de/holarse/config/AppConfig.java b/src/main/java/de/holarse/config/AppConfig.java index 39cb82b2..5433b161 100644 --- a/src/main/java/de/holarse/config/AppConfig.java +++ b/src/main/java/de/holarse/config/AppConfig.java @@ -13,6 +13,7 @@ import org.springframework.context.annotation.PropertySources; import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; import org.springframework.data.web.config.EnableSpringDataWebSupport; +import org.springframework.data.web.config.PageableHandlerMethodArgumentResolverCustomizer; import org.springframework.format.FormatterRegistry; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.transaction.annotation.EnableTransactionManagement; @@ -139,4 +140,9 @@ public void addFormatters(FormatterRegistry registry) { registry.addConverter(new StringToFilepondConverter()); } + @Bean + PageableHandlerMethodArgumentResolverCustomizer pageableResolverCustomizer() { + return pageableResolver -> pageableResolver.setOneIndexedParameters(true); + } + } diff --git a/src/main/java/de/holarse/config/MultipleHttpSecurityConfig.java b/src/main/java/de/holarse/config/MultipleHttpSecurityConfig.java index 491f9add..33449f23 100644 --- a/src/main/java/de/holarse/config/MultipleHttpSecurityConfig.java +++ b/src/main/java/de/holarse/config/MultipleHttpSecurityConfig.java @@ -137,6 +137,7 @@ public SecurityFilterChain webFormSecurityFilterChain(final HttpSecurity http, f // Normale Webseite, auch als Gast nutzbar .authorizeHttpRequests((requests) -> requests.requestMatchers(antMatcher("/"), + antMatcher("/login**"), antMatcher("/search/**"), antMatcher("/tags/**"), antMatcher("/wiki/**"), @@ -150,10 +151,11 @@ public SecurityFilterChain webFormSecurityFilterChain(final HttpSecurity http, f antMatcher("/imprint")).permitAll()) // Form-Login - .formLogin(form -> form.loginPage("/login").permitAll() - .successHandler(successHandler()) - .failureHandler(failureHandler())) - + .formLogin(form -> form + .loginPage("/login").permitAll() + .failureHandler(failureHandler()) + .successHandler(successHandler())) + // Logout .logout(logout -> logout.logoutUrl("/logout")) diff --git a/src/main/java/de/holarse/web/controller/LoginController.java b/src/main/java/de/holarse/web/controller/LoginController.java index 4cb9d4a4..5653ac86 100644 --- a/src/main/java/de/holarse/web/controller/LoginController.java +++ b/src/main/java/de/holarse/web/controller/LoginController.java @@ -7,6 +7,7 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.support.SessionStatus; import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.servlet.view.RedirectView; @Controller public class LoginController { @@ -22,10 +23,10 @@ public ModelAndView index(final ModelAndView mv) { } @GetMapping("/logout") - public String logout(final SessionStatus session) { + public RedirectView logout(final SessionStatus session) { SecurityContextHolder.getContext().setAuthentication(null); session.setComplete(); - return "/login?logout=true"; + return new RedirectView("login?logout=true"); } } diff --git a/src/main/java/de/holarse/web/controller/NewsController.java b/src/main/java/de/holarse/web/controller/NewsController.java index 81b13c38..39b463d8 100644 --- a/src/main/java/de/holarse/web/controller/NewsController.java +++ b/src/main/java/de/holarse/web/controller/NewsController.java @@ -21,6 +21,7 @@ import de.holarse.web.defines.WebDefines; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; import org.springframework.data.web.PageableDefault; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; @@ -70,12 +71,12 @@ public class NewsController { private NewsCategoryRepository newsCategoryRepository; @GetMapping - public ModelAndView index(@PageableDefault(sort = {"title"}, value = NEWS_ARTICLES_DEFAULT_PAGE_SIZE) final Pageable pageable, final ModelAndView mv) { + public ModelAndView index(@PageableDefault(sort = {"nr.updated", "nr.created"}, direction = Sort.Direction.ASC, value = NEWS_ARTICLES_DEFAULT_PAGE_SIZE) final Pageable pageable, final ModelAndView mv) { mv.setViewName("layouts/bare"); mv.addObject("title", "Die Linuxspiele-Seite für Linuxspieler"); mv.addObject(WebDefines.DEFAULT_VIEW_ATTRIBUTE_NAME, "sites/news/index"); - mv.addObject("items", newsRepository.findFrontpageItems(pageable)); + mv.addObject("searchResults", newsRepository.findFrontpageItems(pageable)); return mv; } diff --git a/src/main/java/de/holarse/web/controller/WelcomeController.java b/src/main/java/de/holarse/web/controller/WelcomeController.java index 7689ffcc..d54ac8a8 100644 --- a/src/main/java/de/holarse/web/controller/WelcomeController.java +++ b/src/main/java/de/holarse/web/controller/WelcomeController.java @@ -37,10 +37,10 @@ public ModelAndView index(final ModelAndView mv) { mv.addObject("title", "Die Linuxspiele-Seite für Linuxspieler"); mv.addObject(WebDefines.DEFAULT_VIEW_ATTRIBUTE_NAME, "sites/welcome"); - var pageRequest = PageRequest.of(0, 10, Sort.by("nr.updated").descending().and(Sort.by("nr.created").descending())); + var pageRequest = PageRequest.of(1, 10, Sort.by("nr.updated").descending().and(Sort.by("nr.created").descending())); final List articles = articleRepository.findFrontpageItems(pageRequest); - final List news = newsRepository.findFrontpageItems(pageRequest); + final List news = newsRepository.findFrontpageItems(pageRequest) != null ? newsRepository.findFrontpageItems(pageRequest).getContent() : new ArrayList<>(); final List items = new ArrayList<>(); items.addAll(articles); diff --git a/src/main/webapp/WEB-INF/templates/sites/news/index.html b/src/main/webapp/WEB-INF/templates/sites/news/index.html index 89bb5281..f8da5ee6 100644 --- a/src/main/webapp/WEB-INF/templates/sites/news/index.html +++ b/src/main/webapp/WEB-INF/templates/sites/news/index.html @@ -1,4 +1,4 @@ - +
@@ -6,13 +6,15 @@

Die News-Beiträge

-
    -
  • +
      +
- + + +
diff --git a/src/main/webapp/WEB-INF/templates/sites/search/pagination.html b/src/main/webapp/WEB-INF/templates/sites/search/pagination.html index d8a5a743..13003465 100644 --- a/src/main/webapp/WEB-INF/templates/sites/search/pagination.html +++ b/src/main/webapp/WEB-INF/templates/sites/search/pagination.html @@ -4,7 +4,7 @@