This is an automated email from the ASF dual-hosted git repository. ilgrosso pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/syncope.git
The following commit(s) were added to refs/heads/master by this push: new 0f3b83cde3 [SYNCOPE-1722] Allow password fields to reveal their value to the end-user 0f3b83cde3 is described below commit 0f3b83cde33f7aa151322f7ce71fdb623bce6e61 Author: Francesco Chicchiriccò <ilgro...@apache.org> AuthorDate: Tue Feb 14 16:16:22 2023 +0100 [SYNCOPE-1722] Allow password fields to reveal their value to the end-user --- .../markup/html/list/ConnConfPropertyListView.java | 2 +- .../markup/html/form/AjaxPasswordFieldPanel.java | 23 +++--- .../html/form/SyncopePasswordStrengthConfig.java | 54 +++++++++++++ .../ui/commons/wizards/any/PasswordPanel.java | 2 +- .../resources/ui-commons/css/syncopeUI.scss | 81 +++++--------------- .../markup/html/form/AjaxPasswordFieldPanel.html | 20 ++++- client/idrepo/console/pom.xml | 11 ++- client/idrepo/enduser/pom.xml | 12 ++- .../client/enduser/SyncopeWebApplication.java | 28 ++++++- .../syncope/client/enduser/pages/BasePage.java | 6 +- .../client/enduser/pages/EditChangePassword.java | 5 +- .../syncope/client/enduser/pages/EditUser.java | 5 +- .../enduser/pages/SelfConfirmPasswordReset.java | 7 +- .../client/enduser/panels/ChangePasswordPanel.java | 26 +++---- .../syncope/client/enduser/panels/Sidebar.java | 89 ++++++++++------------ .../client/enduser/panels/any/UserDetails.java | 7 +- .../src/test/resources/enduser-debug.properties | 3 +- 17 files changed, 218 insertions(+), 163 deletions(-) diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/list/ConnConfPropertyListView.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/list/ConnConfPropertyListView.java index 59bd19b46a..923c79c55f 100644 --- a/client/idm/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/list/ConnConfPropertyListView.java +++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/list/ConnConfPropertyListView.java @@ -83,7 +83,7 @@ public class ConnConfPropertyListView extends ListView<ConnConfProperty> { || IdMConstants.GUARDED_STRING.equalsIgnoreCase(property.getSchema().getType()) || IdMConstants.GUARDED_BYTE_ARRAY.equalsIgnoreCase(property.getSchema().getType())) { - field = new AjaxPasswordFieldPanel("panel", label, new Model<>(), false); + field = new AjaxPasswordFieldPanel("panel", label, Model.of(), false); ((PasswordTextField) field.getField()).setResetPassword(false); required = property.getSchema().isRequired(); diff --git a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AjaxPasswordFieldPanel.java b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AjaxPasswordFieldPanel.java index 3dbadf01ce..6253f5f50a 100644 --- a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AjaxPasswordFieldPanel.java +++ b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AjaxPasswordFieldPanel.java @@ -19,6 +19,7 @@ package org.apache.syncope.client.ui.commons.markup.html.form; import de.agilecoders.wicket.extensions.markup.html.bootstrap.form.password.strength.PasswordStrengthBehavior; +import java.util.Optional; import org.apache.syncope.client.ui.commons.Constants; import org.apache.syncope.client.ui.commons.ajax.form.IndicatorAjaxFormComponentUpdatingBehavior; import org.apache.wicket.ajax.AjaxRequestTarget; @@ -30,25 +31,27 @@ public class AjaxPasswordFieldPanel extends FieldPanel<String> { private static final long serialVersionUID = -5490115280336667460L; - public AjaxPasswordFieldPanel(final String id, final String name, final IModel<String> model) { - this(id, name, model, true, null); - } - - public AjaxPasswordFieldPanel(final String id, final String name, final IModel<String> model, + public AjaxPasswordFieldPanel( + final String id, + final String name, + final IModel<String> model, final boolean enableOnChange) { + this(id, name, model, enableOnChange, null); } public AjaxPasswordFieldPanel( - final String id, final String name, final IModel<String> model, final boolean enableOnChange, + final String id, + final String name, + final IModel<String> model, + final boolean enableOnChange, final PasswordStrengthBehavior passwordStrengthBehavior) { + super(id, name, model); field = new PasswordTextField("passwordField", model); - if (passwordStrengthBehavior != null) { - field.add(passwordStrengthBehavior); - } add(field.setLabel(new ResourceModel(name, name)).setRequired(false).setOutputMarkupId(true)); + Optional.ofNullable(passwordStrengthBehavior).ifPresent(field::add); if (enableOnChange && !isReadOnly()) { field.add(new IndicatorAjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) { @@ -56,7 +59,7 @@ public class AjaxPasswordFieldPanel extends FieldPanel<String> { private static final long serialVersionUID = -1107858522700306810L; @Override - protected void onUpdate(final AjaxRequestTarget art) { + protected void onUpdate(final AjaxRequestTarget target) { // nothing to do } }); diff --git a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/SyncopePasswordStrengthConfig.java b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/SyncopePasswordStrengthConfig.java new file mode 100644 index 0000000000..7b4c72d317 --- /dev/null +++ b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/SyncopePasswordStrengthConfig.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.syncope.client.ui.commons.markup.html.form; + +import de.agilecoders.wicket.extensions.markup.html.bootstrap.form.password.strength.PasswordStrengthConfig; +import de.agilecoders.wicket.jquery.AbstractConfig; +import de.agilecoders.wicket.jquery.IKey; +import de.agilecoders.wicket.jquery.Key; + +public class SyncopePasswordStrengthConfig extends PasswordStrengthConfig { + + private static final long serialVersionUID = -5625052394514215251L; + + public enum KeyType { + common, + ui, + rules; + + } + + public SyncopePasswordStrengthConfig() { + super(); + + withProgressExtraCssClasses("pwstrengthProgress"). + withShowVerdictsInsideProgressBar(true). + withShowProgressBar(true); + } + + protected <T> void put(final KeyType keyType, final IKey<T> key, final T value) { + AbstractConfig ui = (AbstractConfig) all().get(keyType.name()); + ui.put(key, value); + } + + public PasswordStrengthConfig withProgressExtraCssClasses(final String progressExtraCssClasses) { + put(KeyType.ui, new Key<>("progressExtraCssClasses"), progressExtraCssClasses); + return this; + } +} diff --git a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/wizards/any/PasswordPanel.java b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/wizards/any/PasswordPanel.java index 09fecc67f9..214c64ff92 100644 --- a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/wizards/any/PasswordPanel.java +++ b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/wizards/any/PasswordPanel.java @@ -57,7 +57,7 @@ public class PasswordPanel extends Panel { add(form); AjaxPasswordFieldPanel confirmPasswordField = new AjaxPasswordFieldPanel( - "confirmPassword", "confirmPassword", new Model<>(), false, null); + "confirmPassword", "confirmPassword", Model.of(), false); ((PasswordTextField) confirmPasswordField.getField()).setResetPassword(false); form.add(confirmPasswordField.setPlaceholder("confirmPassword").setMarkupId("confirmPassword")); diff --git a/client/idrepo/common-ui/src/main/resources/META-INF/resources/ui-commons/css/syncopeUI.scss b/client/idrepo/common-ui/src/main/resources/META-INF/resources/ui-commons/css/syncopeUI.scss index e0bf1f48a5..9feb80a774 100644 --- a/client/idrepo/common-ui/src/main/resources/META-INF/resources/ui-commons/css/syncopeUI.scss +++ b/client/idrepo/common-ui/src/main/resources/META-INF/resources/ui-commons/css/syncopeUI.scss @@ -19,12 +19,10 @@ @import 'utils'; - pre { @include white_space_pre_wrap; } - #veil { display: none; position: fixed; @@ -66,22 +64,18 @@ pre { border-radius: 0.5em; @include animation(spinner 2000ms infinite linear); - @include shadow(rgba(0, 0, 0, 0.75) 1.5em 0 0 0, - rgba(0, 0, 0, 0.75) 1.1em 1.1em 0 0, - rgba(0, 0, 0, 0.75) 0 1.5em 0 0, - rgba(0, 0, 0, 0.75) -1.1em 1.1em 0 0, - rgba(0, 0, 0, 0.5) -1.5em 0 0 0, - rgba(0, 0, 0, 0.5) -1.1em -1.1em 0 0, - rgba(0, 0, 0, 0.75) 0 -1.5em 0 0, + @include shadow(rgba(0, 0, 0, 0.75) 1.5em 0 0 0, + rgba(0, 0, 0, 0.75) 1.1em 1.1em 0 0, + rgba(0, 0, 0, 0.75) 0 1.5em 0 0, + rgba(0, 0, 0, 0.75) -1.1em 1.1em 0 0, + rgba(0, 0, 0, 0.5) -1.5em 0 0 0, + rgba(0, 0, 0, 0.5) -1.1em -1.1em 0 0, + rgba(0, 0, 0, 0.75) 0 -1.5em 0 0, rgba(0, 0, 0, 0.75) 1.1em -1.1em 0 0); } } } - - - - /* General ============================================================================= */ @@ -320,7 +314,6 @@ a.help { } } - .wizard-buttons { padding: 10px 0px 5px 0px; position: absolute; @@ -374,7 +367,7 @@ span.overridable div.checkbox { } } -#outer.modal-lg, +#outer.modal-lg, #utilityModal.modal-lg { max-width: 1200px; width: 97%; @@ -416,7 +409,11 @@ td.checkGroupColumn { color: #fff!important; } - +.pwstrengthProgress { + position: absolute; + bottom: 0px; + width: 100%; +} /* Style for Information panel ============================================================================= */ @@ -461,7 +458,6 @@ td.checkGroupColumn { margin-left: 155px; } - #ownership div.toggle { width: 110px !important; } @@ -513,9 +509,6 @@ td.checkGroupColumn { padding-left: 15px; } - - - /* Startat ============================================================================= */ @@ -541,10 +534,6 @@ td.checkGroupColumn { } } - - - - /* Notifications ============================================================================= */ /*Temporany fix diagonal stacking*/ @@ -599,11 +588,6 @@ td.checkGroupColumn { } } - - - - - /* Actions ============================================================================= */ @@ -666,12 +650,6 @@ div.listview-actions a { margin: 0px; } - - - - - - /* Datatable ============================================================================= */ @@ -778,7 +756,6 @@ div.panel-collapse.collapse.show span.ui-spinner.ui-corner-all.ui-widget.ui-widg top: 5px !important; } - /* Parameters Details ============================================================================= */ @@ -786,8 +763,6 @@ div#parametersForm { min-height: 220px; } - - li.todoitem a { cursor: default; } @@ -843,11 +818,6 @@ div#userFilter { width: 20px; } - - - - - /* Alert widget onside menu ============================================================================= */ @@ -898,10 +868,6 @@ div#userFilter { } } - - - - /* Transformers toggle panel ============================================================================= */ @@ -965,9 +931,6 @@ div#userFilter { clear: both; } - - - /* Events ============================================================================= */ @@ -1006,9 +969,6 @@ div#userFilter { min-width: 585px; } - - - /* Others ============================================================================= */ .form-check { @@ -1072,8 +1032,8 @@ th ul.menu { padding: 0; } -#inline-actions ul.menu, -#tablehandling ul.menu, +#inline-actions ul.menu, +#tablehandling ul.menu, .listview-actions ul.menu { list-style-type: none; margin: 0; @@ -1088,7 +1048,7 @@ th ul.menu li { } #inline-actions ul.menu li, -#tablehandling ul.menu li, +#tablehandling ul.menu li, .listview-actions ul.menu li { display: inline-block; } @@ -1098,8 +1058,8 @@ th ul.menu li a { display: inline-block !important; } -#inline-actions ul.menu li a, -.listview-actions ul.menu li a, +#inline-actions ul.menu li a, +.listview-actions ul.menu li a, #tablehandling ul.menu li a { margin-left: 5px; display: inline-block !important; @@ -1115,7 +1075,7 @@ ul.menu { } } -#inline-actions ul.menu i, +#inline-actions ul.menu i, #tablehandling ul.menu i { width: auto !important; } @@ -1164,9 +1124,6 @@ h3.card-title { @include shadow(0px 0px 20px 1px rgba(0,0,0,0.75)); } - - - /* Utility classes ============================================================================= */ diff --git a/client/idrepo/common-ui/src/main/resources/org/apache/syncope/client/ui/commons/markup/html/form/AjaxPasswordFieldPanel.html b/client/idrepo/common-ui/src/main/resources/org/apache/syncope/client/ui/commons/markup/html/form/AjaxPasswordFieldPanel.html index 30329ae917..4de436c344 100644 --- a/client/idrepo/common-ui/src/main/resources/org/apache/syncope/client/ui/commons/markup/html/form/AjaxPasswordFieldPanel.html +++ b/client/idrepo/common-ui/src/main/resources/org/apache/syncope/client/ui/commons/markup/html/form/AjaxPasswordFieldPanel.html @@ -22,6 +22,22 @@ under the License. <label wicket:id="field-label">[LABEL]</label><span wicket:id="required"/> <span wicket:id="externalAction"/> </wicket:enclosure> - <input type="password" class="form-control" wicket:id="passwordField" /> + <div class="input-group" style="height: 3.5rem;"> + <input type="password" class="form-control" wicket:id="passwordField"/> + <span class="input-group-btn"> + <button type="button" class="btn btn-warning btn-flat" onclick=" + var input = $(this).parent().prevAll('input'); + var type = input.attr('type'); + var children = $(this).children(); + if (type !== 'text') { + $(input).attr('type', 'text'); + $(children).addClass('fa-eye-slash').removeClass('fa-eye'); + } else { + $(input).attr('type', 'password'); + $(children).removeClass('fa-eye-slash').addClass('fa-eye'); + } + return false;"><i class="fa fa-eye"></i></button> + </span> + </div> </wicket:extend> -</html> \ No newline at end of file +</html> diff --git a/client/idrepo/console/pom.xml b/client/idrepo/console/pom.xml index dffc0596cb..cf6f387dad 100644 --- a/client/idrepo/console/pom.xml +++ b/client/idrepo/console/pom.xml @@ -263,11 +263,12 @@ under the License. <id>debug</id> <properties> + <maven.build.cache.skipCache>true</maven.build.cache.skipCache> <skipTests>true</skipTests> </properties> <build> - <defaultGoal>clean package spring-boot:run</defaultGoal> + <defaultGoal>clean package</defaultGoal> <plugins> <plugin> @@ -284,6 +285,14 @@ under the License. <profile>debug</profile> </profiles> </configuration> + <executions> + <execution> + <phase>package</phase> + <goals> + <goal>run</goal> + </goals> + </execution> + </executions> </plugin> </plugins> diff --git a/client/idrepo/enduser/pom.xml b/client/idrepo/enduser/pom.xml index d8999e3948..8ebbed46c0 100644 --- a/client/idrepo/enduser/pom.xml +++ b/client/idrepo/enduser/pom.xml @@ -255,11 +255,12 @@ under the License. <id>debug</id> <properties> + <maven.build.cache.skipCache>true</maven.build.cache.skipCache> <skipTests>true</skipTests> </properties> <build> - <defaultGoal>clean package spring-boot:run</defaultGoal> + <defaultGoal>clean package</defaultGoal> <plugins> <plugin> @@ -267,6 +268,7 @@ under the License. <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <jvmArguments> + -Djavax.net.ssl.trustStore=${basedir}/../../../fit/wa-reference/src/test/resources/keystore.jks -Djavax.net.ssl.trustStorePassword=password -Dwicket.core.settings.general.configuration-type=development -XX:+AllowEnhancedClassRedefinition -XX:HotswapAgent=fatjar -Xdebug -Xrunjdwp:transport=dt_socket,address=8004,server=y,suspend=n @@ -275,6 +277,14 @@ under the License. <profile>debug</profile> </profiles> </configuration> + <executions> + <execution> + <phase>package</phase> + <goals> + <goal>run</goal> + </goals> + </execution> + </executions> </plugin> </plugins> diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeWebApplication.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeWebApplication.java index c7dda3204c..191102a92d 100644 --- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeWebApplication.java +++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeWebApplication.java @@ -20,7 +20,7 @@ package org.apache.syncope.client.enduser; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.json.JsonMapper; -import com.giffing.wicket.spring.boot.starter.app.WicketBootStandardWebApplication; +import com.giffing.wicket.spring.boot.starter.app.WicketBootSecuredWebApplication; import de.agilecoders.wicket.core.Bootstrap; import de.agilecoders.wicket.core.settings.BootstrapSettings; import de.agilecoders.wicket.core.settings.IBootstrapSettings; @@ -28,6 +28,7 @@ import de.agilecoders.wicket.core.settings.SingleThemeProvider; import java.io.InputStream; import java.util.List; import java.util.Locale; +import java.util.Map; import org.apache.syncope.client.enduser.init.ClassPathScanImplementationLookup; import org.apache.syncope.client.enduser.layout.UserFormLayoutInfo; import org.apache.syncope.client.enduser.pages.BasePage; @@ -47,12 +48,15 @@ import org.apache.syncope.common.keymaster.client.api.model.NetworkService; import org.apache.wicket.Page; import org.apache.wicket.Session; import org.apache.wicket.WicketRuntimeException; +import org.apache.wicket.authorization.IAuthorizationStrategy; +import org.apache.wicket.authorization.IAuthorizationStrategy.AllowAllAuthorizationStrategy; import org.apache.wicket.markup.html.WebPage; import org.apache.wicket.protocol.http.ResourceIsolationRequestCycleListener; import org.apache.wicket.protocol.http.WebApplication; import org.apache.wicket.protocol.http.servlet.XForwardedRequestWrapperFactory; import org.apache.wicket.request.Request; import org.apache.wicket.request.Response; +import org.apache.wicket.request.component.IRequestableComponent; import org.apache.wicket.request.component.IRequestablePage; import org.apache.wicket.request.cycle.IRequestCycleListener; import org.apache.wicket.request.cycle.RequestCycle; @@ -65,7 +69,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.io.ResourceLoader; -public class SyncopeWebApplication extends WicketBootStandardWebApplication { +public class SyncopeWebApplication extends WicketBootSecuredWebApplication { protected static final Logger LOG = LoggerFactory.getLogger(SyncopeWebApplication.class); @@ -117,6 +121,8 @@ public class SyncopeWebApplication extends WicketBootStandardWebApplication { getResourceSettings().setUseDefaultOnMissingResource(true); getResourceSettings().setThrowExceptionOnMissingResource(false); + getSecuritySettings().setAuthorizationStrategy(getAuthorizationStrategy()); + getMarkupSettings().setStripWicketTags(true); getMarkupSettings().setCompressWhitespace(true); @@ -201,6 +207,23 @@ public class SyncopeWebApplication extends WicketBootStandardWebApplication { } } + protected IAuthorizationStrategy getAuthorizationStrategy() { + return new AllowAllAuthorizationStrategy() { + + @Override + public <T extends IRequestableComponent> boolean isInstantiationAuthorized(final Class<T> componentClass) { + if (BasePage.class.isAssignableFrom(componentClass)) { + return props.getPage().entrySet().stream(). + filter(entry -> componentClass.equals(entry.getValue())). + map(Map.Entry::getKey).findFirst(). + map(k -> SyncopeEnduserSession.get().isAuthenticated()). + orElse(true); + } + return true; + } + }; + } + @Override public Class<? extends Page> getHomePage() { return SyncopeEnduserSession.get().isAuthenticated() @@ -247,6 +270,7 @@ public class SyncopeWebApplication extends WicketBootStandardWebApplication { return props.getPage().getOrDefault(name, defaultValue); } + @Override protected Class<? extends WebPage> getSignInPageClass() { return Login.class; } diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/BasePage.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/BasePage.java index 36d371e82f..c41998b238 100644 --- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/BasePage.java +++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/BasePage.java @@ -19,7 +19,6 @@ package org.apache.syncope.client.enduser.pages; import java.io.Serializable; -import java.lang.reflect.InvocationTargetException; import java.util.List; import org.apache.syncope.client.enduser.SyncopeEnduserSession; import org.apache.syncope.client.enduser.SyncopeWebApplication; @@ -84,8 +83,7 @@ public class BasePage extends BaseWebPage { PageReference.class, List.class). newInstance("sidebar", getPageReference(), lookup.getExtPageClasses()); - } catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException - | IllegalArgumentException | InvocationTargetException e) { + } catch (Exception e) { throw new IllegalArgumentException("Could not instantiate " + clazz.getName(), e); } @@ -108,7 +106,7 @@ public class BasePage extends BaseWebPage { @Override public void onClick(final AjaxRequestTarget target) { Session.get().setAttribute(Constants.MENU_COLLAPSE, - Session.get().getAttribute(Constants.MENU_COLLAPSE) == null + Session.get().getAttribute(Constants.MENU_COLLAPSE) == null ? true : !(Boolean) Session.get().getAttribute(Constants.MENU_COLLAPSE)); } diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/EditChangePassword.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/EditChangePassword.java index d4df1da270..d2e33711dc 100644 --- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/EditChangePassword.java +++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/EditChangePassword.java @@ -21,7 +21,6 @@ package org.apache.syncope.client.enduser.pages; import org.apache.syncope.client.enduser.SyncopeEnduserSession; import org.apache.syncope.client.enduser.SyncopeWebApplication; import org.apache.syncope.client.enduser.commons.ProvisioningUtils; -import org.apache.syncope.client.enduser.rest.UserSelfRestClient; import org.apache.syncope.client.ui.commons.markup.html.form.AjaxPasswordFieldPanel; import org.apache.syncope.common.lib.request.PasswordPatch; import org.apache.syncope.common.lib.request.UserUR; @@ -35,8 +34,6 @@ public class EditChangePassword extends AbstractChangePassword { private static final long serialVersionUID = -537205681762708502L; - private final UserSelfRestClient userSelfRestClient = new UserSelfRestClient(); - public EditChangePassword(final PageParameters parameters) { super(parameters); } @@ -56,7 +53,7 @@ public class EditChangePassword extends AbstractChangePassword { setResponsePage(new SelfResult(provisioningResult, ProvisioningUtils.managePageParams(EditChangePassword.this, "pwd.change", !SyncopeWebApplication.get().isReportPropagationErrors() - || provisioningResult.getPropagationStatuses().stream() + || provisioningResult.getPropagationStatuses().stream() .allMatch(ps -> ExecStatus.SUCCESS == ps.getStatus())))); } catch (Exception e) { LOG.error("While changing password for {}", SyncopeEnduserSession.get().getSelfTO().getUsername(), e); diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/EditUser.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/EditUser.java index e9cc7874f6..c56eff8372 100644 --- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/EditUser.java +++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/EditUser.java @@ -18,6 +18,7 @@ */ package org.apache.syncope.client.enduser.pages; +import java.util.Optional; import org.apache.syncope.client.enduser.SyncopeEnduserSession; import org.apache.syncope.client.enduser.SyncopeWebApplication; import org.apache.syncope.client.enduser.layout.UserFormLayoutInfo; @@ -55,7 +56,7 @@ public class EditUser extends BasePage { } protected UserFormLayoutInfo buildFormLayout() { - UserFormLayoutInfo customlayoutInfo = SyncopeWebApplication.get().getCustomFormLayout(); - return customlayoutInfo != null ? customlayoutInfo : new UserFormLayoutInfo(); + return Optional.ofNullable(SyncopeWebApplication.get().getCustomFormLayout()). + orElseGet(() -> new UserFormLayoutInfo()); } } diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset.java index 6038d738bb..cdd7665857 100644 --- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset.java +++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset.java @@ -19,10 +19,10 @@ package org.apache.syncope.client.enduser.pages; import de.agilecoders.wicket.extensions.markup.html.bootstrap.form.password.strength.PasswordStrengthBehavior; -import de.agilecoders.wicket.extensions.markup.html.bootstrap.form.password.strength.PasswordStrengthConfig; import org.apache.syncope.client.enduser.SyncopeEnduserSession; import org.apache.syncope.client.enduser.commons.EnduserConstants; import org.apache.syncope.client.ui.commons.Constants; +import org.apache.syncope.client.ui.commons.markup.html.form.SyncopePasswordStrengthConfig; import org.apache.syncope.client.ui.commons.panels.CardPanel; import org.apache.syncope.client.ui.commons.wizards.any.PasswordPanel; import org.apache.syncope.client.ui.commons.wizards.any.UserWrapper; @@ -72,10 +72,7 @@ public class SelfConfirmPasswordReset extends BasePage { new UserWrapper(fakeUserTO), false, false, - new PasswordStrengthBehavior(new PasswordStrengthConfig(). - withDebug(false). - withShowVerdictsInsideProgressBar(true). - withShowProgressBar(true))); + new PasswordStrengthBehavior(new SyncopePasswordStrengthConfig())); passwordPanel.setOutputMarkupId(true); form.add(new CardPanel.Builder<PasswordPanel>() diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/ChangePasswordPanel.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/ChangePasswordPanel.java index 240f7f7373..b9f5111f1e 100644 --- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/ChangePasswordPanel.java +++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/ChangePasswordPanel.java @@ -19,12 +19,12 @@ package org.apache.syncope.client.enduser.panels; import de.agilecoders.wicket.extensions.markup.html.bootstrap.form.password.strength.PasswordStrengthBehavior; -import de.agilecoders.wicket.extensions.markup.html.bootstrap.form.password.strength.PasswordStrengthConfig; import org.apache.syncope.client.enduser.SyncopeWebApplication; import org.apache.syncope.client.enduser.commons.EnduserConstants; import org.apache.syncope.client.enduser.panels.captcha.CaptchaPanel; import org.apache.syncope.client.ui.commons.markup.html.form.AbstractFieldPanel; import org.apache.syncope.client.ui.commons.markup.html.form.AjaxPasswordFieldPanel; +import org.apache.syncope.client.ui.commons.markup.html.form.SyncopePasswordStrengthConfig; import org.apache.syncope.client.ui.commons.panels.CardPanel; import org.apache.syncope.client.ui.commons.panels.NotificationPanel; import org.apache.syncope.common.lib.to.UserTO; @@ -75,24 +75,24 @@ public abstract class ChangePasswordPanel extends Panel { // div that is not visible (but not display:none either) buffer.append(String.format( - "<div style=\"width:0px;height:0px;position:absolute;" + "<div style=\"width:0px;height:0px;position:absolute;" + "left:-100px;top:-100px;overflow:hidden\" class=\"%s\">", - cssClass)); + cssClass)); // add an empty textfield (otherwise IE doesn't work) buffer.append("<input title=\"text_hidden\" " - + "aria-label=\"text_hidden\" type=\"text\" " - + "tabindex=\"-1\" autocomplete=\"off\"/>"); + + "aria-label=\"text_hidden\" type=\"text\" " + + "tabindex=\"-1\" autocomplete=\"off\"/>"); // add the submitting component final Component submittingComponent = (Component) getDefaultButton(); buffer.append("<input title=\"submit_hidden\" aria-label=\"submit_hidden\" " - + "type=\"submit\" tabindex=\"-1\" name=\""); + + "type=\"submit\" tabindex=\"-1\" name=\""); buffer.append(getDefaultButton().getInputName()); buffer.append("\" onclick=\" var b=document.getElementById('"); buffer.append(submittingComponent.getMarkupId()); buffer.append( - "'); if (b!=null&&b.onclick!=null&&typeof(b.onclick) != 'undefined') " + "'); if (b!=null&&b.onclick!=null&&typeof(b.onclick) != 'undefined') " + "{ var r = Wicket.bind(b.onclick, b)(); if (r != false) b.click(); } " + "else { b.click(); }; return false;\" "); buffer.append(" />"); @@ -109,13 +109,9 @@ public abstract class ChangePasswordPanel extends Panel { passwordField = new AjaxPasswordFieldPanel( "password", getString("password"), - new Model<>(), + Model.of(), false, - new PasswordStrengthBehavior( - new PasswordStrengthConfig() - .withDebug(true) - .withShowVerdictsInsideProgressBar(true) - .withShowProgressBar(true))); + new PasswordStrengthBehavior(new SyncopePasswordStrengthConfig())); passwordField.setRequired(true); passwordField.setMarkupId("password"); passwordField.setPlaceholder("password"); @@ -126,8 +122,8 @@ public abstract class ChangePasswordPanel extends Panel { ((PasswordTextField) passwordField.getField()).setResetPassword(true); form.add(passwordField); - confirmPasswordField = new AjaxPasswordFieldPanel("confirmPassword", - getString("confirmPassword"), new Model<>()); + confirmPasswordField = new AjaxPasswordFieldPanel( + "confirmPassword", getString("confirmPassword"), Model.of(), true); confirmPasswordField.setRequired(true); confirmPasswordField.setMarkupId("confirmPassword"); confirmPasswordField.setPlaceholder("confirmPassword"); diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/Sidebar.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/Sidebar.java index 2abca3e356..b952b93437 100644 --- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/Sidebar.java +++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/Sidebar.java @@ -25,6 +25,7 @@ import org.apache.commons.lang3.StringUtils; import org.apache.syncope.client.enduser.BookmarkablePageLinkBuilder; import org.apache.syncope.client.enduser.SyncopeEnduserSession; import org.apache.syncope.client.enduser.SyncopeWebApplication; +import org.apache.syncope.client.enduser.layout.SidebarLayout; import org.apache.syncope.client.enduser.pages.BasePage; import org.apache.syncope.client.enduser.pages.Dashboard; import org.apache.syncope.client.enduser.pages.EditChangePassword; @@ -122,55 +123,55 @@ public class Sidebar extends Panel { } } - ListView<Class<? extends BasePage>> extPages = - new ListView<>("extPages", extPageClasses.stream() - .filter(epc -> SyncopeWebApplication.get().getCustomFormLayout().getSidebarLayout() - .isExtensionEnabled(StringUtils.remove(epc.getAnnotation(ExtPage.class).label(), - StringUtils.SPACE))) - .collect(Collectors.toList())) { + ListView<Class<? extends BasePage>> extPages = new ListView<>("extPages", extPageClasses.stream(). + filter(epc -> SyncopeWebApplication.get().getCustomFormLayout().getSidebarLayout(). + isExtensionEnabled(StringUtils.remove(epc.getAnnotation(ExtPage.class).label(), StringUtils.SPACE))). + collect(Collectors.toList())) { - private static final long serialVersionUID = 4949588177564901031L; + private static final long serialVersionUID = 4949588177564901031L; - @Override - protected void populateItem(final ListItem<Class<? extends BasePage>> item) { - WebMarkupContainer containingLI = new WebMarkupContainer("extPageLI"); - item.add(containingLI); + @Override + protected void populateItem(final ListItem<Class<? extends BasePage>> item) { + WebMarkupContainer containingLI = new WebMarkupContainer("extPageLI"); + item.add(containingLI); - ExtPage ann = item.getModelObject().getAnnotation(ExtPage.class); + ExtPage ann = item.getModelObject().getAnnotation(ExtPage.class); - BookmarkablePageLink<Page> link = new BookmarkablePageLink<>("extPage", item.getModelObject()); + BookmarkablePageLink<Page> link = new BookmarkablePageLink<>("extPage", item.getModelObject()); - link.add(new Label("extPageLabel", ann.label())); + link.add(new Label("extPageLabel", ann.label())); - if (item.getModelObject().equals(pageRef.getPage().getClass())) { - link.add(new Behavior() { + if (item.getModelObject().equals(pageRef.getPage().getClass())) { + link.add(new Behavior() { - private static final long serialVersionUID = 1469628524240283489L; + private static final long serialVersionUID = 1469628524240283489L; - @Override - public void renderHead(final Component component, final IHeaderResponse response) { - response.render(OnDomReadyHeaderItem.forScript( + @Override + public void renderHead(final Component component, final IHeaderResponse response) { + response.render(OnDomReadyHeaderItem.forScript( "$('#extensionsLink').addClass('active')")); - } - - @Override - public void onComponentTag(final Component component, final ComponentTag tag) { - tag.append("class", "active", " "); - } - }); - } - containingLI.add(link); + } - Label extPageIcon = new Label("extPageIcon"); - extPageIcon.add(new AttributeModifier("class", "nav-icon " + ann.icon())); - link.add(extPageIcon); + @Override + public void onComponentTag(final Component component, final ComponentTag tag) { + tag.append("class", "active", " "); + } + }); } - }; + containingLI.add(link); + + Label extPageIcon = new Label("extPageIcon"); + extPageIcon.add(new AttributeModifier("class", "nav-icon " + ann.icon())); + link.add(extPageIcon); + } + }; add(extPages.setRenderBodyOnly(true).setOutputMarkupId(true)); } protected void buildBaseSidebar() { + SidebarLayout layout = SyncopeWebApplication.get().getCustomFormLayout().getSidebarLayout(); + dashboardLIContainer = new WebMarkupContainer(getLIContainerId("dashboard")); add(dashboardLIContainer); dashboardLIContainer.add(BookmarkablePageLinkBuilder.build( @@ -180,33 +181,27 @@ public class Sidebar extends Panel { add(profileLIContainer); profileULContainer = new WebMarkupContainer(getULContainerId("profile")); profileLIContainer.add(profileULContainer); - profileLIContainer.setVisible(SyncopeWebApplication.get().getCustomFormLayout().getSidebarLayout(). - isEditUserEnabled() - || SyncopeWebApplication.get().getCustomFormLayout().getSidebarLayout(). - isPasswordManagementEnabled() - || (SyncopeWebApplication.get().getCustomFormLayout().getSidebarLayout(). - isSecurityQuestionManagementEnabled() + profileLIContainer.setVisible(layout.isEditUserEnabled() + || layout.isPasswordManagementEnabled() + || (layout.isSecurityQuestionManagementEnabled() && SyncopeEnduserSession.get().getPlatformInfo().isPwdResetRequiringSecurityQuestions())); WebMarkupContainer liContainer = new WebMarkupContainer(getLIContainerId("edituser")); profileULContainer.add(liContainer); - liContainer.add(BookmarkablePageLinkBuilder.build("edituser", EditUser.class)) - .setVisible(SyncopeWebApplication.get().getCustomFormLayout().getSidebarLayout() - .isEditUserEnabled()); + liContainer.add(BookmarkablePageLinkBuilder.build("edituser", EditUser.class)). + setVisible(layout.isEditUserEnabled()); liContainer = new WebMarkupContainer(getLIContainerId("editchangepassword")); profileULContainer.add(liContainer); - liContainer.add(BookmarkablePageLinkBuilder.build("editchangepassword", EditChangePassword.class)) - .setVisible(SyncopeWebApplication.get().getCustomFormLayout().getSidebarLayout(). - isPasswordManagementEnabled()); + liContainer.add(BookmarkablePageLinkBuilder.build("editchangepassword", EditChangePassword.class)). + setVisible(layout.isPasswordManagementEnabled()); liContainer = new WebMarkupContainer(getLIContainerId("editsecurityquestion")); profileULContainer.add(liContainer); liContainer.add(BookmarkablePageLinkBuilder.build("editsecurityquestion", EditSecurityQuestion.class)); liContainer.setOutputMarkupPlaceholderTag(true); - liContainer.setVisible(SyncopeWebApplication.get().getCustomFormLayout().getSidebarLayout(). - isSecurityQuestionManagementEnabled() + liContainer.setVisible(layout.isSecurityQuestionManagementEnabled() && SyncopeEnduserSession.get().getPlatformInfo().isPwdResetRequiringSecurityQuestions()); } diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/any/UserDetails.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/any/UserDetails.java index fed52d49d4..d68070e20c 100644 --- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/any/UserDetails.java +++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/any/UserDetails.java @@ -19,7 +19,6 @@ package org.apache.syncope.client.enduser.panels.any; import de.agilecoders.wicket.extensions.markup.html.bootstrap.form.password.strength.PasswordStrengthBehavior; -import de.agilecoders.wicket.extensions.markup.html.bootstrap.form.password.strength.PasswordStrengthConfig; import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; import org.apache.syncope.client.enduser.rest.RealmRestClient; @@ -27,6 +26,7 @@ import org.apache.syncope.client.ui.commons.ajax.markup.html.LabelInfo; import org.apache.syncope.client.ui.commons.markup.html.form.AjaxDropDownChoicePanel; import org.apache.syncope.client.ui.commons.markup.html.form.AjaxTextFieldPanel; import org.apache.syncope.client.ui.commons.markup.html.form.FieldPanel; +import org.apache.syncope.client.ui.commons.markup.html.form.SyncopePasswordStrengthConfig; import org.apache.syncope.client.ui.commons.wizards.any.PasswordPanel; import org.apache.syncope.client.ui.commons.wizards.any.UserWrapper; import org.apache.syncope.common.lib.to.RealmTO; @@ -89,10 +89,7 @@ public class UserDetails extends Details<UserTO> { wrapper, false, wrapper.getInnerObject().getKey() == null, - new PasswordStrengthBehavior(new PasswordStrengthConfig(). - withDebug(false). - withShowVerdictsInsideProgressBar(true). - withShowProgressBar(true)))); + new PasswordStrengthBehavior(new SyncopePasswordStrengthConfig()))); } } } diff --git a/client/idrepo/enduser/src/test/resources/enduser-debug.properties b/client/idrepo/enduser/src/test/resources/enduser-debug.properties index dc5eaed661..bcdebf8d47 100644 --- a/client/idrepo/enduser/src/test/resources/enduser-debug.properties +++ b/client/idrepo/enduser/src/test/resources/enduser-debug.properties @@ -15,10 +15,11 @@ # specific language governing permissions and limitations # under the License. keymaster.address=http://localhost:9080/syncope/rest/keymaster +#keymaster.address=https://localhost:9443/syncope/rest/keymaster keymaster.username=${anonymousUser} keymaster.password=${anonymousKey} server.port=9091 -service.discovery.address=http://localhost:9090/syncope-enduser/ +service.discovery.address=http://localhost:9091/syncope-enduser/ logging.config=file://${project.build.testOutputDirectory}/log4j2.xml