You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@causeway.apache.org by ah...@apache.org on 2026/10/21 08:44:41 UTC

(causeway) branch main updated: CAUSEWAY-4076: restructure config to make reusable signin related configuration

This is an automated email from the ASF dual-hosted git repository.

andi-huber pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/causeway.git


The following commit(s) were added to refs/heads/main by this push:
     new 5fc30b7dcb7 CAUSEWAY-4076: restructure config to make reusable signin related configuration
5fc30b7dcb7 is described below

commit 5fc30b7dcb78e9f88dc7fbd9b533ce902e244dea
Author: andi-huber <ah...@apache.org>
AuthorDate: Wed Oct 21 10:44:31 2026 +0200

    CAUSEWAY-4076: restructure config to make reusable signin related
    configuration
---
 .../core/config/CausewayConfiguration.java         | 107 +++++++++++----------
 .../accmngt/password_reset/PasswordResetPage.java  |  12 +--
 .../pages/accmngt/signup/RegistrationFormPage.java |   6 +-
 .../wicket/ui/pages/login/CausewaySignInPanel.java |  36 ++-----
 .../wicket/ui/pages/login/SignInPanelAbstract.java |  20 ++--
 .../wicket/ui/pages/login/WicketSignInPage.java    |  22 +----
 .../integration/WebRequestCycleForCauseway.java    |  35 +------
 7 files changed, 86 insertions(+), 152 deletions(-)

diff --git a/core/config/src/main/java/org/apache/causeway/core/config/CausewayConfiguration.java b/core/config/src/main/java/org/apache/causeway/core/config/CausewayConfiguration.java
index e6a190fcd91..5c3c7724139 100644
--- a/core/config/src/main/java/org/apache/causeway/core/config/CausewayConfiguration.java
+++ b/core/config/src/main/java/org/apache/causeway/core/config/CausewayConfiguration.java
@@ -84,6 +84,8 @@
 import org.apache.causeway.applib.services.i18n.Mode;
 import org.apache.causeway.applib.services.iactn.Execution;
 import org.apache.causeway.applib.services.publishing.spi.ExecutionSubscriber;
+import org.apache.causeway.applib.services.userreg.EmailNotificationService;
+import org.apache.causeway.applib.services.userreg.UserRegistrationService;
 import org.apache.causeway.applib.value.semantics.TemporalValueSemantics.TemporalDisplayPattern;
 import org.apache.causeway.applib.value.semantics.TemporalValueSemantics.TemporalEditingPattern;
 import org.apache.causeway.commons.functional.Try;
@@ -2255,7 +2257,9 @@ public record Common(
              * and <a href="https://github.com/spring-projects/spring-boot/wiki/IDE-binding-features#simple-pojo">this wiki page</a>.
              */
             @DefaultValue
-            List<Credit> credit) {
+            List<Credit> credit,
+            @DefaultValue
+            Signin signin) {
 
             public record Application(
                 /**
@@ -2353,6 +2357,59 @@ public record Credit(
                  */
                 public boolean isDefined() { return (name != null || image != null) && url != null; }
             }
+
+            public record Signin(
+
+                    /**
+                     * Whether to suppress the sign-up link on the sign-in page.
+                     *
+                     * <p>Although this is disabled by default (in other words the sign-up link is not suppressed), note that
+                     * in addition the application must provide an implementation of the
+                     * {@link UserRegistrationService} as well as a
+                     * configured {@link EmailNotificationService} (same conditions
+                     * as for the {@link #isSuppressPasswordReset()} password reset link).
+                     */
+                    @DefaultValue("false")
+                    boolean suppressSignUp,
+
+                    /**
+                     * Whether to suppress the password reset link on the sign-in page.
+                     *
+                     * <p>Although this is disabled by default (in other words the 'reset password' link is not suppressed),
+                     * note that in addition the application must provide an implementation of the
+                     * {@link UserRegistrationService} as well as a
+                     * configured {@link EmailNotificationService} (same conditions
+                     * as for the {@link #isSuppressSignUp()} sign-up link).
+                     */
+                    @DefaultValue("false")
+                    boolean suppressPasswordReset,
+
+                    @DefaultValue
+                    RememberMe rememberMe
+            		) {
+
+                public record RememberMe(
+                        /**
+                         * Whether the sign-in page should have a 'remember me' link (the default), or if it should
+                         * be suppressed.
+                         *
+                         * <p> If 'remember me' is available and checked, then the viewer will remember 'username' and 'timezone'
+                         * for the login page using cookies. This does not include any secrets nor requires encryption.
+                         */
+                        @DefaultValue("false")
+                        boolean suppress,
+
+                        /**
+                         * If the 'remember me' feature is available, specifies the cookie name prefix that is used for cookies to store timezone and username data.
+                         */
+                        @DefaultValue("causewayRememberMe")
+                        String cookieKey,
+
+                        @DefaultValue("Remember 'username' and 'timezone' for the next login.")
+                        String description) {
+                }
+            }
+
         }
 
         public record Graphql(
@@ -3139,30 +3196,6 @@ public record Wicket(
             @DefaultValue("true")
             boolean stripWicketTags,
 
-            /**
-             * Whether to suppress the sign-up link on the sign-in page.
-             *
-             * <p>Although this is disabled by default (in other words the sign-up link is not suppressed), note that
-             * in addition the application must provide an implementation of the
-             * {@link UserRegistrationService} as well as a
-             * configured {@link EmailNotificationService} (same conditions
-             * as for the {@link #isSuppressPasswordReset()} password reset link).
-             */
-            @DefaultValue("false")
-            boolean suppressSignUp,
-
-            /**
-             * Whether to suppress the password reset link on the sign-in page.
-             *
-             * <p>Although this is disabled by default (in other words the 'reset password' link is not suppressed),
-             * note that in addition the application must provide an implementation of the
-             * {@link UserRegistrationService} as well as a
-             * configured {@link EmailNotificationService} (same conditions
-             * as for the {@link #isSuppressSignUp()} sign-up link).
-             */
-            @DefaultValue("false")
-            boolean suppressPasswordReset,
-
             /**
              * How to interpret tooltip content, e.g. as HTML or TEXT. default = TEXT
              */
@@ -3213,8 +3246,6 @@ public record Wicket(
             @DefaultValue
             FileUpload fileUpload,
             @DefaultValue
-            RememberMe rememberMe,
-            @DefaultValue
             Themes themes,
             @DefaultValue
             Welcome welcome,
@@ -3383,28 +3414,6 @@ public record FileUpload(
         			boolean showPreview) {
             }
 
-            public record RememberMe(
-                /**
-                 * Whether the sign-in page should have a 'remember me' link (the default), or if it should
-                 * be suppressed.
-                 *
-                 * <p> If 'remember me' is available and checked, then the viewer will remember 'username' and 'timezone'
-                 * for the login page using cookies. This does not include any secrets nor requires encryption.
-                 */
-                @DefaultValue("false")
-                boolean suppress,
-
-                /**
-                 * If the 'remember me' feature is available, specifies the cookie name prefix that is used for cookies to store timezone and username data.
-                 */
-                @DefaultValue("causewayWicketRememberMe")
-                String cookieKey,
-
-                @DefaultValue("Remember 'username' and 'timezone' for the next login.")
-                String description) {
-
-            }
-
             public record Themes(
                 /**
                  * A comma separated list of enabled theme names, as defined by https://bootswatch.com.
diff --git a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/pages/accmngt/password_reset/PasswordResetPage.java b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/pages/accmngt/password_reset/PasswordResetPage.java
index 79c208b75a8..0e28c4261ab 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/pages/accmngt/password_reset/PasswordResetPage.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/pages/accmngt/password_reset/PasswordResetPage.java
@@ -44,13 +44,11 @@ public PasswordResetPage(final PageParameters parameters) {
         this(parameters, getAndClearExceptionModelIfAny());
     }
 
-    private PasswordResetPage(final PageParameters parameters, ExceptionModel exceptionModel) {
+    private PasswordResetPage(final PageParameters parameters, final ExceptionModel exceptionModel) {
         super(parameters, exceptionModel);
 
-        boolean suppressPasswordResetLink = getWicketViewerSettings().suppressPasswordReset();
-        if(suppressPasswordResetLink) {
-            throw new RestartResponseAtInterceptPageException(WicketSignInPage.class);
-        }
+        if(getCommonViewerSettings().signin().suppressPasswordReset())
+			throw new RestartResponseAtInterceptPageException(WicketSignInPage.class);
     }
 
     @Override
@@ -94,7 +92,7 @@ protected void onInitialize() {
      * @param uuid A unique id used to identify the email of the user whose password will be reset
      * @return A panel with "password reset" form fields
      */
-    protected PasswordResetPanel addPasswordResetPanel(String id, String uuid) {
+    protected PasswordResetPanel addPasswordResetPanel(final String id, final String uuid) {
         final PasswordResetPanel passwordResetPanel = new PasswordResetPanel(id, uuid);
         addOrReplace(passwordResetPanel);
         return passwordResetPanel;
@@ -109,7 +107,7 @@ protected PasswordResetPanel addPasswordResetPanel(String id, String uuid) {
      * @param id The component id
      * @return A panel with "send email for password reset" functionality
      */
-    protected PasswordResetEmailPanel addPasswordResetEmailPanel(String id) {
+    protected PasswordResetEmailPanel addPasswordResetEmailPanel(final String id) {
         final PasswordResetEmailPanel passwordResetEmailPanel = new PasswordResetEmailPanel(id);
         addOrReplace(passwordResetEmailPanel);
         return passwordResetEmailPanel;
diff --git a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/pages/accmngt/signup/RegistrationFormPage.java b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/pages/accmngt/signup/RegistrationFormPage.java
index 1b7c6b7e00a..8aa860917c4 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/pages/accmngt/signup/RegistrationFormPage.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/pages/accmngt/signup/RegistrationFormPage.java
@@ -40,14 +40,12 @@ public RegistrationFormPage(final PageParameters parameters) {
         this(parameters, getAndClearExceptionModelIfAny());
     }
 
-    private RegistrationFormPage(final PageParameters parameters, ExceptionModel exceptionModel) {
+    private RegistrationFormPage(final PageParameters parameters, final ExceptionModel exceptionModel) {
         super(parameters, exceptionModel);
 
-        boolean suppressSignUp = getWicketViewerSettings().suppressSignUp();
-        if(suppressSignUp) {
+        if(getCommonViewerSettings().signin().suppressSignUp()) {
             pageNavigationService.interceptAndRestartAt(PageType.SIGN_IN);
         }
-
     }
 
     @Override
diff --git a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/pages/login/CausewaySignInPanel.java b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/pages/login/CausewaySignInPanel.java
index d4fed14f0c9..4f6554f868e 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/pages/login/CausewaySignInPanel.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/pages/login/CausewaySignInPanel.java
@@ -62,34 +62,12 @@ public class CausewaySignInPanel extends SignInPanelAbstract {
     transient Can<UserRegistrationService> anyUserRegistrationService;
     transient Can<EmailNotificationService> anyEmailNotificationService;
 
-    private final boolean signUpLink;
-    private final boolean passwordResetLink;
-    private final boolean isClearOriginalDestination;
-
-    /**
-     * Constructor
-     *  @param id
-     *            the component id
-     * @param rememberMe
-     *            True if form should include a remember-me checkbox
-     * @param signUpLink
-     * @param passwordResetLink
-     *            True if form should include the password reset link
-     * @param continueToOriginalDestination
-     */
     public CausewaySignInPanel(
-            final String id,
-            final boolean rememberMe,
-            final boolean signUpLink,
-            final boolean passwordResetLink,
-            final boolean continueToOriginalDestination) {
-        super(id, rememberMe);
-        this.signUpLink = signUpLink;
-        this.passwordResetLink = passwordResetLink;
-        this.isClearOriginalDestination = !continueToOriginalDestination;
+            final String id) {
+        super(id);
     }
 
-    @Override
+	@Override
     protected void onInitialize() {
         super.onInitialize();
 
@@ -108,7 +86,7 @@ protected void onInitialize() {
 
     @Override
     protected void onSignInSucceeded() {
-        if(isClearOriginalDestination) {
+        if(getWicketViewerSettings().clearOriginalDestination()) {
             clearOriginalDestination();
         }
         super.onSignInSucceeded();
@@ -139,11 +117,13 @@ protected void clearUserTimeZoneFromSession() {
     // -- HELPER
 
     private BookmarkablePageLink<Void> addPasswordResetLink() {
-        return addLink("passwdResetLink", PageType.PASSWORD_RESET, this.passwordResetLink);
+    	var signinConf = getConfiguration().viewer().common().signin();
+        return addLink("passwdResetLink", PageType.PASSWORD_RESET, !signinConf.suppressPasswordReset());
     }
 
     private BookmarkablePageLink<Void> addSignUpLink() {
-        return addLink("signUpLink", PageType.SIGN_UP, this.signUpLink);
+    	var signinConf = getConfiguration().viewer().common().signin();
+    	return addLink("signUpLink", PageType.SIGN_UP, !signinConf.suppressSignUp());
     }
 
     private BookmarkablePageLink<Void> addLink(
diff --git a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/pages/login/SignInPanelAbstract.java b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/pages/login/SignInPanelAbstract.java
index aaf3bcbf2c1..865435b5779 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/pages/login/SignInPanelAbstract.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/pages/login/SignInPanelAbstract.java
@@ -44,7 +44,7 @@
 import org.apache.causeway.applib.services.i18n.TranslationContext;
 import org.apache.causeway.applib.value.semantics.TimeZoneChoiceProvider;
 import org.apache.causeway.commons.internal.base._Strings;
-import org.apache.causeway.core.config.CausewayConfiguration.Viewer.Wicket.RememberMe;
+import org.apache.causeway.core.config.CausewayConfiguration.Viewer.Common.Signin.RememberMe;
 import org.apache.causeway.core.metamodel.context.HasMetaModelContext;
 import org.apache.causeway.viewer.wicket.ui.util.Wkt;
 
@@ -65,9 +65,6 @@ public abstract class SignInPanelAbstract
     private static final String SIGN_IN_FORM = "signInForm";
     private static final String TIME_ZONE_SELECT = "timezone-select";
 
-    /** True if the panel should display a remember-me checkbox */
-    private boolean includeRememberMe = true;
-
     /**
      * True if the username and timezone should be remembered via form persistence (cookies).
      * This does not include any secrets.
@@ -94,11 +91,9 @@ public abstract class SignInPanelAbstract
      *            True if form should include a remember-me checkbox
      * @see org.apache.wicket.Component#Component(String)
      */
-    protected SignInPanelAbstract(final String id, final boolean includeRememberMe) {
+    protected SignInPanelAbstract(final String id) {
         super(id);
 
-        this.includeRememberMe = includeRememberMe;
-
         // Create feedback panel and add to page
         add(new FeedbackPanel("feedback"));
 
@@ -214,13 +209,16 @@ public SignInFormWithTimeZone(final String id) {
 
             // Add rememberMe checkbox
             rememberMeContainer.add(new CheckBox("rememberMe"));
+
+            var signinConf = getConfiguration().viewer().common().signin();
+
             rememberMeContainer.add(new Label("rememberMeDescription",
             		getTranslationService().translate(
             				TranslationContext.named("Login"),
-            				getConfiguration().viewer().wicket().rememberMe().description())));
+            				signinConf.rememberMe().description())));
 
             // Show remember me checkbox?
-            rememberMeContainer.setVisible(includeRememberMe);
+            rememberMeContainer.setVisible(!signinConf.rememberMe().suppress());
         }
 
         /**
@@ -282,7 +280,7 @@ Optional<String> recoverUsername() {
     }
 
     private UsernameCookie usernameCookie() {
-    	return new UsernameCookie(getConfiguration().viewer().wicket().rememberMe());
+    	return new UsernameCookie(getConfiguration().viewer().common().signin().rememberMe());
     }
 
     // -- TIME ZONE COOKIES
@@ -308,6 +306,6 @@ Optional<ZoneId> recoverTimezone() {
     }
 
     private TimezoneCookie timezoneCookie() {
-    	return new TimezoneCookie(getConfiguration().viewer().wicket().rememberMe());
+    	return new TimezoneCookie(getConfiguration().viewer().common().signin().rememberMe());
     }
 }
diff --git a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/pages/login/WicketSignInPage.java b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/pages/login/WicketSignInPage.java
index 4155bfbdc25..1fcd9a0a811 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/pages/login/WicketSignInPage.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/pages/login/WicketSignInPage.java
@@ -38,6 +38,8 @@ public class WicketSignInPage extends AccountManagementPageAbstract {
 
     private static final long serialVersionUID = 1L;
 
+    @Inject private transient PageNavigationService pageNavigationService;
+
     public WicketSignInPage(final PageParameters parameters) {
         this(parameters, getAndClearExceptionModelIfAny());
     }
@@ -54,7 +56,7 @@ public WicketSignInPage(final PageParameters parameters, final ExceptionModel ex
     protected void onInitialize() {
         super.onInitialize();
 
-        add(createSignInPanel());
+        add(new CausewaySignInPanel("signInPanel"));
 
         SuccessFeedbackCookieManager.drainSuccessFeedback(this::success);
     }
@@ -66,22 +68,4 @@ public void renderHead(final IHeaderResponse response) {
                 SignInPanelAbstract.getJsForTimezoneSelectDefault()));
     }
 
-    protected CausewaySignInPanel createSignInPanel() {
-
-        final boolean rememberMeSuppress = getWicketViewerSettings().rememberMe().suppress();
-        final boolean suppressRememberMe = rememberMeSuppress;
-
-        final boolean suppressSignUpLink = getWicketViewerSettings().suppressSignUp();
-        final boolean suppressPasswordResetLink = getWicketViewerSettings().suppressPasswordReset();
-        final boolean clearOriginalDestination = getWicketViewerSettings().clearOriginalDestination();
-        final boolean rememberMe = !suppressRememberMe;
-        final boolean signUpLink = !suppressSignUpLink;
-        final boolean passwordReset = !suppressPasswordResetLink;
-        final boolean continueToOriginalDestination = !clearOriginalDestination;
-        var signInPanel =
-                new CausewaySignInPanel("signInPanel", rememberMe, signUpLink, passwordReset, continueToOriginalDestination);
-        return signInPanel;
-    }
-
-    @Inject private PageNavigationService pageNavigationService;
 }
diff --git a/viewers/wicket/viewer/src/main/java/org/apache/causeway/viewer/wicket/viewer/integration/WebRequestCycleForCauseway.java b/viewers/wicket/viewer/src/main/java/org/apache/causeway/viewer/wicket/viewer/integration/WebRequestCycleForCauseway.java
index dd57d840c5b..3d6f3a5763d 100644
--- a/viewers/wicket/viewer/src/main/java/org/apache/causeway/viewer/wicket/viewer/integration/WebRequestCycleForCauseway.java
+++ b/viewers/wicket/viewer/src/main/java/org/apache/causeway/viewer/wicket/viewer/integration/WebRequestCycleForCauseway.java
@@ -23,8 +23,6 @@
 import java.util.List;
 import java.util.Optional;
 
-import jakarta.servlet.http.HttpServletRequest;
-
 import org.apache.wicket.Application;
 import org.apache.wicket.IPageFactory;
 import org.apache.wicket.MetaDataKey;
@@ -132,19 +130,6 @@ public WebRequestCycleForCauseway(final MetaModelContext mmc, final PageClassReg
 
     @Override
     public void onBeginRequest(final RequestCycle requestCycle) {
-
-        if (!Session.exists()) {
-            // Track if session was created from an expired one to notify user of the refresh.
-            // If there is no remember me cookie, user will be redirected to sign in and no need to notify.
-            if (userHasSessionWithRememberMe(requestCycle)) {
-                requestCycle.setMetaData(SESSION_LIFECYCLE_PHASE_KEY, SessionLifecyclePhase.EXPIRED);
-                if(log.isTraceEnabled()) {
-                    log.trace("flagging the RequestCycle as expired (rememberMe feature is active for the current user)");
-                }
-            }
-            return;
-        }
-
         sessionAuthenticator.determineInteractionContext()
             .ifPresent(interactionService::openInteraction);
     }
@@ -411,9 +396,7 @@ private IRequestablePage newSignInPage(final ExceptionModel exceptionModel) {
 
     /**
      * TODO: this is very hacky...
-     *
-     * <p>
-     * Matters should improve once CAUSEWAY-299 gets implemented...
+     * <p>Matters should improve once CAUSEWAY-299 gets implemented...
      */
     protected boolean isSignedIn() {
         if(!interactionService.isInInteraction())
@@ -421,20 +404,4 @@ protected boolean isSignedIn() {
         return AuthenticatedWebSession.get().isSignedIn();
     }
 
-    private boolean userHasSessionWithRememberMe(final RequestCycle requestCycle) {
-        var containerRequest = requestCycle.getRequest().getContainerRequest();
-
-        if (containerRequest instanceof HttpServletRequest) {
-            var cookies = Can.ofArray(((HttpServletRequest) containerRequest).getCookies());
-            var cookieKey = _Strings.nullToEmpty(
-                    getConfiguration().viewer().wicket().rememberMe().cookieKey());
-
-            for (var cookie : cookies) {
-                if (cookieKey.equals(cookie.getName()))
-                    return true;
-            }
-        }
-        return false;
-    }
-
 }