From 34cf805637496f780d5517d9a3a33e7ab8c6c7ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Fri, 20 Mar 2026 17:35:55 +0100 Subject: [PATCH] [SYNCOPE-1956] Ensure to build empty multivalue attrs --- .../any/LinkedAccountPlainAttrsPanel.java | 54 +++--- .../markup/html/form/AjaxPalettePanel.java | 6 +- .../client/console/PreferenceManager.java | 9 +- .../client/console/layout/AnyLayoutUtils.java | 6 +- .../panels/AbstractDisplayModalPanel.java | 2 +- .../console/panels/AnyDirectoryPanel.java | 2 +- .../console/panels/RealmDirectoryPanel.java | 2 +- .../wizards/any/AbstractAttrsWizardStep.java | 29 ++- .../client/console/wizards/any/DerAttrs.java | 8 +- .../console/wizards/any/PlainAttrs.java | 17 +- .../client/console/wizards/any/Roles.java | 13 -- .../client/console/wizards/any/Roles.html | 13 +- .../console/wizards/any/Roles.properties | 1 - .../wizards/any/Roles_fr_CA.properties | 3 +- .../console/wizards/any/Roles_it.properties | 1 - .../console/wizards/any/Roles_ja.properties | 1 - .../wizards/any/Roles_pt_BR.properties | 1 - .../console/wizards/any/Roles_ru.properties | 4 +- .../client/enduser/PreferenceManager.java | 175 ------------------ .../apache/syncope/common/lib/to/UserTO.java | 8 - .../fit/console/AjaxPalettePanelITCase.java | 15 +- pom.xml | 2 +- 22 files changed, 73 insertions(+), 299 deletions(-) delete mode 100644 client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/PreferenceManager.java diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountPlainAttrsPanel.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountPlainAttrsPanel.java index 29facf423ca..c926f94b4cc 100644 --- a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountPlainAttrsPanel.java +++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountPlainAttrsPanel.java @@ -25,8 +25,10 @@ import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; +import org.apache.commons.lang3.StringUtils; import org.apache.syncope.client.console.commons.LinkedAccountPlainAttrProperty; import org.apache.syncope.client.ui.commons.Constants; import org.apache.syncope.client.ui.commons.ajax.form.IndicatorAjaxFormComponentUpdatingBehavior; @@ -42,6 +44,7 @@ import org.apache.syncope.common.lib.to.LinkedAccountTO; import org.apache.syncope.common.lib.to.PlainSchemaTO; import org.apache.syncope.common.lib.to.UserTO; +import org.apache.syncope.common.lib.types.AttrSchemaType; import org.apache.syncope.common.lib.types.SchemaType; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.extensions.markup.html.tabs.AbstractTab; @@ -81,8 +84,8 @@ public LinkedAccountPlainAttrsPanel( this.linkedAccountTO = modelObject.getInnerObject(); this.fixedAttrs.addAll(this.linkedAccountTO.getPlainAttrs().stream(). - filter(attrTO -> checkIsReadonlyAttr(attrTO.getSchema())). - toList()); + filter(attr -> isReadonly(attr.getSchema())). + toList()); this.userTO = userTO; add(new Accordion("plainSchemas", List.of(new AbstractTab( @@ -97,6 +100,10 @@ public WebMarkupContainer getPanel(final String panelId) { }), Model.of(0)).setOutputMarkupId(true)); } + private boolean isReadonly(final String schema) { + return schemas.isEmpty() ? true : !schemas.get(schema).isReadonly(); + } + @Override protected FormComponent checkboxToggle( final Attr attrTO, @@ -115,11 +122,10 @@ protected FormComponent checkboxToggle( return newProperty; }); - final BootstrapToggleConfig config = new BootstrapToggleConfig(). + BootstrapToggleConfig config = new BootstrapToggleConfig(). withOnStyle(BootstrapToggleConfig.Style.success). withOffStyle(BootstrapToggleConfig.Style.danger). withSize(BootstrapToggleConfig.Size.mini); - return new BootstrapToggle("externalAction", new PropertyModel<>(property, "overridable"), config) { private static final long serialVersionUID = -875219845189261873L; @@ -166,8 +172,8 @@ protected void onComponentTag(final ComponentTag tag) { private void updateAccountPlainSchemas(final LinkedAccountPlainAttrProperty property, final Boolean modelObject) { Set withoutCurrentSchema = new HashSet<>(linkedAccountTO.getPlainAttrs().stream(). - filter(attrTO -> !attrTO.getSchema().equals(property.getSchema()) - && checkIsReadonlyAttr(attrTO.getSchema())). + filter(attr -> !attr.getSchema().equals(property.getSchema()) + && isReadonly(attr.getSchema())). collect(Collectors.toSet())); linkedAccountTO.getPlainAttrs().clear(); linkedAccountTO.getPlainAttrs().addAll(withoutCurrentSchema); @@ -186,28 +192,28 @@ protected SchemaType getSchemaType() { @Override protected void setAttrs() { - List attrs = new ArrayList<>(); + List plainAttrs = new ArrayList<>(); List notReadonlyValues = schemas.values().stream(). - filter(schema -> checkIsReadonlyAttr(schema.getKey())). - collect(Collectors.toList()); + filter(schema -> !schema.isReadonly()). + toList(); setFixedAttr(notReadonlyValues); Map attrMap = EntityTOUtils.buildAttrMap(fixedAttrs); - attrs.addAll(notReadonlyValues.stream(). - map(schema -> { - Attr attrTO = new Attr(); - attrTO.setSchema(schema.getKey()); - if (attrMap.get(schema.getKey()) == null || attrMap.get(schema.getKey()).getValues().isEmpty()) { - attrTO.getValues().add(""); - } else { - attrTO = attrMap.get(schema.getKey()); - } - return attrTO; - }). - toList()); + plainAttrs.addAll(notReadonlyValues.stream().map(schema -> { + Attr attr = Optional.ofNullable(attrMap.get(schema.getKey())).orElseGet(() -> { + Attr newAttr = new Attr(); + newAttr.setSchema(schema.getKey()); + return newAttr; + }); + if ((schema.getType() != AttrSchemaType.Dropdown || !schema.isMultivalue()) && attr.getValues().isEmpty()) { + attr.getValues().add(StringUtils.EMPTY); + } + + return attr; + }).toList()); fixedAttrs.clear(); - fixedAttrs.addAll(attrs); + fixedAttrs.addAll(plainAttrs); } @Override @@ -221,10 +227,6 @@ private void setFixedAttr(final Collection values) { () -> userTO.getPlainAttr(schema.getKey()).ifPresent(fixedAttrs::add))); } - private boolean checkIsReadonlyAttr(final String schema) { - return schemas.isEmpty() ? true : !schemas.get(schema).isReadonly(); - } - private class PlainSchemasOwn extends PlainSchemas> { private static final long serialVersionUID = -4730563859116024676L; diff --git a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AjaxPalettePanel.java b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AjaxPalettePanel.java index 723d813209d..2dd541b0cba 100644 --- a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AjaxPalettePanel.java +++ b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AjaxPalettePanel.java @@ -220,14 +220,10 @@ public LoadableDetachableModel> getChoicesModel() { @Override public AjaxPalettePanel setModelObject(final List object) { - palette.setDefaultModelObject(object); + palette.setModelObject(object); return this; } - public Collection getModelCollection() { - return palette.getModelCollection(); - } - public void reload(final AjaxRequestTarget target) { target.add(palette); } diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/PreferenceManager.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/PreferenceManager.java index 683c1914c20..43d44718d8e 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/PreferenceManager.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/PreferenceManager.java @@ -28,7 +28,6 @@ import java.util.Map; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.math.NumberUtils; -import org.apache.syncope.common.lib.jackson.SyncopeJsonMapper; import org.apache.wicket.util.cookies.CookieDefaults; import org.apache.wicket.util.cookies.CookieUtils; import org.slf4j.Logger; @@ -46,7 +45,7 @@ public final class PreferenceManager implements Serializable { private static final int ONE_YEAR_TIME = 60 * 60 * 24 * 365; - private static final JsonMapper MAPPER = new SyncopeJsonMapper(); + private static final JsonMapper MAPPER = JsonMapper.builder().findAndAddModules().build(); private static final TypeReference> MAP_TYPE_REF = new TypeReference<>() { }; @@ -160,14 +159,10 @@ public static void set(final String key, final String value) { } } - public static void setList(final String key, final List values) { + public static void set(final String key, final List values) { set(key, String.join(";", values)); } - public static void setList(final Map> prefs) { - set(prefs); - } - private PreferenceManager() { // private constructor for static utility class } diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/layout/AnyLayoutUtils.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/layout/AnyLayoutUtils.java index 147eacbe054..82ab1de0b57 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/layout/AnyLayoutUtils.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/layout/AnyLayoutUtils.java @@ -22,7 +22,6 @@ import java.util.List; import java.util.function.Function; import java.util.stream.Collectors; -import java.util.stream.Stream; import org.apache.commons.lang3.StringUtils; import org.apache.syncope.client.console.SyncopeConsoleSession; import org.apache.syncope.client.console.rest.AbstractAnyRestClient; @@ -74,10 +73,7 @@ private static AnyLayout empty(final List anyTypes) { } public static AnyLayout fetch(final RoleRestClient roleRestClient, final List anyTypes) { - List ownedRoles = Stream.concat( - SyncopeConsoleSession.get().getSelfTO().getRoles().stream(), - SyncopeConsoleSession.get().getSelfTO().getDynRoles().stream()). - distinct().toList(); + List ownedRoles = SyncopeConsoleSession.get().getSelfTO().getRoles(); try { AnyLayout anyLayout = null; for (int i = 0; i < ownedRoles.size() && anyLayout == null; i++) { diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AbstractDisplayModalPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AbstractDisplayModalPanel.java index 050c3251d63..99973069682 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AbstractDisplayModalPanel.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AbstractDisplayModalPanel.java @@ -118,7 +118,7 @@ public void onSubmit(final AjaxRequestTarget target) { prefs.put(detailsPreferenceKey, selectedDetails); prefs.put(plainAttrsPreferenceKey, selectedPlainSchemas); prefs.put(derAttrsPreferenceKey, selectedDerSchemas); - PreferenceManager.setList(prefs); + PreferenceManager.set(prefs); SyncopeConsoleSession.get().success(getString(Constants.OPERATION_SUCCEEDED)); modal.close(target); diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AnyDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AnyDirectoryPanel.java index 45f5d16e2eb..7f5bedd1c30 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AnyDirectoryPanel.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AnyDirectoryPanel.java @@ -204,7 +204,7 @@ protected List> getColumns() { prefcolumns); } - PreferenceManager.setList( + PreferenceManager.set( AnyDisplayAttributesModalPanel.getPrefDetailView(type), List.of(getDefaultAttributeSelection())); } diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/RealmDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/RealmDirectoryPanel.java index c2b3a3c2b6a..52e639c0bf3 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/RealmDirectoryPanel.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/RealmDirectoryPanel.java @@ -193,7 +193,7 @@ protected List> getColumns() { prefcolumns); } - PreferenceManager.setList( + PreferenceManager.set( IdRepoConstants.PREF_REALM_DETAILS_VIEW, RealmDisplayAttributesModalPanel.DEFAULT_COLUMNS); } diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AbstractAttrsWizardStep.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AbstractAttrsWizardStep.java index 005d9114014..d67689df00d 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AbstractAttrsWizardStep.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AbstractAttrsWizardStep.java @@ -184,7 +184,7 @@ public PageReference getPageReference() { } @SuppressWarnings("unchecked") - protected AbstractFieldPanel getFieldPanel(final PlainSchemaTO plainSchema) { + protected AbstractFieldPanel getFieldPanel(final PlainSchemaTO plainSchema, final ListItem item) { final boolean required; final boolean readOnly; final AttrSchemaType type; @@ -281,8 +281,10 @@ public String getObject( : List.of(); if (plainSchema.isMultivalue()) { panel = new AjaxPalettePanel.Builder(). - setName(plainSchema.getLabel(SyncopeConsoleSession.get().getLocale())). - build("panel", new ListModel<>(), new ListModel<>(dropdownValues)); + setName(plainSchema.getLabel(SyncopeConsoleSession.get().getLocale())).build( + "panel", + new PropertyModel<>(item.getModelObject(), "values"), + new ListModel<>(dropdownValues)); } else { panel = new AjaxDropDownChoicePanel<>("panel", plainSchema.getLabel(SyncopeConsoleSession.get().getLocale()), new Model<>(), true); @@ -432,20 +434,15 @@ protected AbstractFieldPanel setPanel( Attr attr = item.getModelObject(); PlainSchemaTO schema = schemas.get(attr.getSchema()); - AbstractFieldPanel panel = getFieldPanel(schema); - panel.setReadOnly(setReadOnly); - if (mode != AjaxWizard.Mode.TEMPLATE - && schema.isMultivalue() - && schema.getType() != AttrSchemaType.Dropdown) { - + AbstractFieldPanel panel = getFieldPanel(schema, item).setReadOnly(setReadOnly); + if (panel instanceof FieldPanel fieldPanel && mode != AjaxWizard.Mode.TEMPLATE && schema.isMultivalue()) { // SYNCOPE-1476 set form as multipart to properly manage membership attributes - panel = new MultiFieldPanel.Builder<>( - new PropertyModel<>(attr, "values")).build( + panel = new MultiFieldPanel.Builder<>(new PropertyModel<>(attr, "values")).build( "panel", schema.getLabel(SyncopeConsoleSession.get().getLocale()), - FieldPanel.class.cast(panel)).setFormAsMultipart(true); - // SYNCOPE-1215 the entire multifield panel must be readonly, not only its field - MultiFieldPanel.class.cast(panel).setFormReadOnly(setReadOnly); + fieldPanel). + setFormAsMultipart(true). + setFormReadOnly(setReadOnly); } else if (panel instanceof AjaxPalettePanel ajaxPalettePanel) { ajaxPalettePanel.setModelObject(attr.getValues()); } else { @@ -465,8 +462,8 @@ protected void setExternalAction(final Attr attr, final AbstractFieldPanel pa Optional prevAttr = previousObject.getPlainAttr(attr.getSchema()); if (prevAttr.map(a -> !ListUtils.isEqualList( - a.getValues().stream().filter(StringUtils::isNotBlank).collect(Collectors.toList()), - attr.getValues().stream().filter(StringUtils::isNotBlank).collect(Collectors.toList()))). + a.getValues().stream().filter(StringUtils::isNotBlank).toList(), + attr.getValues().stream().filter(StringUtils::isNotBlank).toList())). orElseGet(() -> attr.getValues().stream().anyMatch(StringUtils::isNotBlank))) { List oldValues = prevAttr.map(Attr::getValues).orElseGet(List::of); diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/DerAttrs.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/DerAttrs.java index e41ab711d9a..a907487081a 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/DerAttrs.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/DerAttrs.java @@ -127,13 +127,13 @@ protected void setAttrs() { Map attrMap = EntityTOUtils.buildAttrMap(attributable.getDerAttrs()); schemas.values().forEach(schema -> { - Attr attrTO = new Attr(); - attrTO.setSchema(schema.getKey()); + Attr attr = new Attr(); + attr.setSchema(schema.getKey()); if (attrMap.containsKey(schema.getKey())) { - attrTO.getValues().addAll(attrMap.get(schema.getKey()).getValues()); + attr.getValues().addAll(attrMap.get(schema.getKey()).getValues()); } - derAttrs.add(attrTO); + derAttrs.add(attr); }); attributable.getDerAttrs().clear(); diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/PlainAttrs.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/PlainAttrs.java index f44a5e02349..bbfb9b0f3d6 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/PlainAttrs.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/PlainAttrs.java @@ -21,6 +21,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; @@ -186,15 +187,15 @@ protected void setAttrs() { Map attrMap = EntityTOUtils.buildAttrMap(attributable.getPlainAttrs()); List plainAttrs = schemas.values().stream().map(schema -> { - Attr attr = new Attr(); - attr.setSchema(schema.getKey()); - if (attrMap.get(schema.getKey()) == null || attrMap.get(schema.getKey()).getValues().isEmpty()) { - if (schema.getType() != AttrSchemaType.Dropdown || !schema.isMultivalue()) { - attr.getValues().add(StringUtils.EMPTY); - } - } else { - attr = attrMap.get(schema.getKey()); + Attr attr = Optional.ofNullable(attrMap.get(schema.getKey())).orElseGet(() -> { + Attr newAttr = new Attr(); + newAttr.setSchema(schema.getKey()); + return newAttr; + }); + if ((schema.getType() != AttrSchemaType.Dropdown || !schema.isMultivalue()) && attr.getValues().isEmpty()) { + attr.getValues().add(StringUtils.EMPTY); } + return attr; }).toList(); diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/Roles.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/Roles.java index 4ec12af8cf5..469c5690a8f 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/Roles.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/Roles.java @@ -38,10 +38,8 @@ import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy; import org.apache.wicket.extensions.wizard.WizardModel.ICondition; import org.apache.wicket.extensions.wizard.WizardStep; -import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.model.PropertyModel; -import org.apache.wicket.model.util.ListModel; import org.apache.wicket.spring.injection.annot.SpringBean; public class Roles extends WizardStep implements ICondition { @@ -55,8 +53,6 @@ public class Roles extends WizardStep implements ICondition { protected final UserTO userTO; - protected WebMarkupContainer dynrolesContainer; - public Roles(final UserWrapper modelObject) { if (modelObject.getPreviousUserTO() != null && !modelObject.getInnerObject().getRoles().equals(modelObject.getPreviousUserTO().getRoles())) { @@ -82,15 +78,6 @@ public Roles(final UserWrapper modelObject) { allRoles = getManagedRoles(); add(buildRolesSelector(modelObject)); - - dynrolesContainer = new WebMarkupContainer("dynrolesContainer"); - dynrolesContainer.setOutputMarkupId(true); - dynrolesContainer.setOutputMarkupPlaceholderTag(true); - add(dynrolesContainer); - - dynrolesContainer.add(new AjaxPalettePanel.Builder().build("dynroles", - new PropertyModel<>(userTO, "dynRoles"), - new ListModel<>(allRoles)).hideLabel().setEnabled(false).setOutputMarkupId(true)); } protected List getManagedRoles() { diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles.html b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles.html index 976a73584ea..4810faf137d 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles.html +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles.html @@ -29,16 +29,5 @@

[ROLES] - -
-
-

- [ROLES] -

-
-
- [ROLES] -
-
- \ No newline at end of file + diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles.properties index ac181cb0e22..6c58f15c78c 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles.properties @@ -15,4 +15,3 @@ # specific language governing permissions and limitations # under the License. roles.palette=Roles -dynroles.palette=Dynamic Roles diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles_fr_CA.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles_fr_CA.properties index 2afd540d678..1ec3e29e692 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles_fr_CA.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles_fr_CA.properties @@ -14,5 +14,4 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -roles.palette=Rτles -dynroles.palette=Rτles dynamiques +roles.palette=R\u00f4les diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles_it.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles_it.properties index cad6d2b3a56..b350ed38882 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles_it.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles_it.properties @@ -15,4 +15,3 @@ # specific language governing permissions and limitations # under the License. roles.palette=Ruoli -dynroles.palette=Ruoli Dinamici diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles_ja.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles_ja.properties index fbc21cdd524..71ffa39e8ec 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles_ja.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles_ja.properties @@ -15,4 +15,3 @@ # specific language governing permissions and limitations # under the License. roles.palette=\u30ed\u30fc\u30eb -dynroles.palette=\u52d5\u7684\u30ed\u30fc\u30eb diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles_pt_BR.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles_pt_BR.properties index eb7d07bb6fd..e36fce37211 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles_pt_BR.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles_pt_BR.properties @@ -15,4 +15,3 @@ # specific language governing permissions and limitations # under the License. roles.palette=Fun\u00e7\u00e3o -dynroles.palette=Fun\u00e7\u00e3o Din\u00e2micos diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles_ru.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles_ru.properties index f3affa533d1..41ef2d01770 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles_ru.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles_ru.properties @@ -15,7 +15,5 @@ # specific language governing permissions and limitations # under the License. # -# roles.palette=Π ΠΎΠ»ΠΈ +# roles.palette=\u00d0\u00a0\u00d0\u00be\u00d0\u00bb\u00d0\u00b8 roles.palette=\u0420\u043e\u043b\u0438 -# dynroles.palette=ДинамичСскиС Ρ€ΠΎΠ»ΠΈ -dynroles.palette=\u0414\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0440\u043e\u043b\u0438 diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/PreferenceManager.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/PreferenceManager.java deleted file mode 100644 index 8f5b5b0ea9d..00000000000 --- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/PreferenceManager.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * 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.enduser; - -import java.io.IOException; -import java.io.Serializable; -import java.io.StringWriter; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Base64; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.math.NumberUtils; -import org.apache.syncope.common.lib.jackson.SyncopeJsonMapper; -import org.apache.wicket.util.cookies.CookieDefaults; -import org.apache.wicket.util.cookies.CookieUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import tools.jackson.core.type.TypeReference; -import tools.jackson.databind.json.JsonMapper; - -public final class PreferenceManager implements Serializable { - - private static final long serialVersionUID = 3581434664555284193L; - - private static final Logger LOG = LoggerFactory.getLogger(PreferenceManager.class); - - private static final String COOKIE_NAME = "syncope2EnduserPrefs"; - - private static final int ONE_YEAR_TIME = 60 * 60 * 24 * 365; - - private static final JsonMapper MAPPER = new SyncopeJsonMapper(); - - private static final TypeReference> MAP_TYPE_REF = new TypeReference<>() { - }; - - private static final List PAGINATOR_CHOICES = Arrays.asList(new Integer[] { 10, 25, 50 }); - - private static final CookieUtils COOKIE_UTILS; - - static { - CookieDefaults cookieDefaults = new CookieDefaults(); - cookieDefaults.setMaxAge(ONE_YEAR_TIME); - COOKIE_UTILS = new CookieUtils(cookieDefaults); - } - - public List getPaginatorChoices() { - return PAGINATOR_CHOICES; - } - - private Map getPrefs(final String value) { - Map prefs; - try { - if (StringUtils.isNotBlank(value)) { - prefs = MAPPER.readValue(value, MAP_TYPE_REF); - } else { - throw new Exception("Invalid cookie value '" + value + "'"); - } - } catch (Exception e) { - LOG.debug("No preferences found", e); - prefs = new HashMap<>(); - } - - return prefs; - } - - private String setPrefs(final Map prefs) throws IOException { - StringWriter writer = new StringWriter(); - MAPPER.writeValue(writer, prefs); - - return writer.toString(); - } - - public String get(final String key) { - String result = null; - - String prefString = COOKIE_UTILS.load(COOKIE_NAME); - if (prefString != null) { - Map prefs = getPrefs(new String(Base64.getDecoder().decode(prefString.getBytes()))); - result = prefs.get(key); - } - - return result; - } - - public Integer getPaginatorRows(final String key) { - Integer result = getPaginatorChoices().getFirst(); - - String value = get(key); - if (value != null) { - result = NumberUtils.toInt(value, 10); - } - - return result; - } - - public List getList(final String key) { - List result = new ArrayList<>(); - - String compound = get(key); - - if (StringUtils.isNotBlank(compound)) { - String[] items = compound.split(";"); - result.addAll(Arrays.asList(items)); - } - - return result; - } - - public void set(final Map> prefs) { - Map current = new HashMap<>(); - - String prefString = COOKIE_UTILS.load(COOKIE_NAME); - if (prefString != null) { - current.putAll(getPrefs(new String(Base64.getDecoder().decode(prefString.getBytes())))); - } - - // after retrieved previous setting in order to overwrite the key ... - prefs.forEach((key, values) -> current.put(key, String.join(";", values))); - - try { - COOKIE_UTILS.save(COOKIE_NAME, Base64.getEncoder().encodeToString(setPrefs(current).getBytes())); - } catch (IOException e) { - LOG.error("Could not save {} info: {}", getClass().getSimpleName(), current, e); - } - } - - public void set(final String key, final String value) { - String prefString = COOKIE_UTILS.load(COOKIE_NAME); - - final Map current = new HashMap<>(); - if (prefString != null) { - current.putAll(getPrefs(new String(Base64.getDecoder().decode(prefString.getBytes())))); - } - - // after retrieved previous setting in order to overwrite the key ... - current.put(key, value); - - try { - COOKIE_UTILS.save(COOKIE_NAME, Base64.getEncoder().encodeToString(setPrefs(current).getBytes())); - } catch (IOException e) { - LOG.error("Could not save {} info: {}", getClass().getSimpleName(), current, e); - } - } - - public void setList(final String key, final List values) { - set(key, String.join(";", values)); - } - - public void setList(final Map> prefs) { - set(prefs); - } - - private PreferenceManager() { - // private constructor for static utility class - } -} diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/UserTO.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/UserTO.java index 2b58a9eebe3..8afceec7af5 100644 --- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/UserTO.java +++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/UserTO.java @@ -60,8 +60,6 @@ public class UserTO extends AnyTO implements GroupableRelatableTO { private final List roles = new ArrayList<>(); - private final List dynRoles = new ArrayList<>(); - private final List linkedAccounts = new ArrayList<>(); private final List delegatingDelegations = new ArrayList<>(); @@ -190,10 +188,6 @@ public List getRoles() { return roles; } - public List getDynRoles() { - return dynRoles; - } - public List getLinkedAccounts() { return linkedAccounts; } @@ -214,7 +208,6 @@ public int hashCode() { appendSuper(super.hashCode()). append(username). append(roles). - append(dynRoles). append(token). append(tokenExpireTime). append(lastLoginDate). @@ -247,7 +240,6 @@ public boolean equals(final Object obj) { appendSuper(super.equals(obj)). append(username, other.username). append(roles, other.roles). - append(dynRoles, other.dynRoles). append(token, other.token). append(tokenExpireTime, other.tokenExpireTime). append(lastLoginDate, other.lastLoginDate). diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AjaxPalettePanelITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AjaxPalettePanelITCase.java index 2918c1d9069..f67dffeb3e3 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AjaxPalettePanelITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AjaxPalettePanelITCase.java @@ -24,29 +24,30 @@ import java.util.Iterator; import java.util.List; import org.apache.syncope.client.ui.commons.markup.html.form.AjaxPalettePanel; -import org.apache.wicket.model.IModel; +import org.apache.wicket.extensions.markup.html.form.palette.Palette; import org.apache.wicket.model.util.ListModel; import org.apache.wicket.util.tester.FormTester; import org.junit.jupiter.api.Test; +import org.springframework.test.util.ReflectionTestUtils; public class AjaxPalettePanelITCase extends AbstractConsoleITCase { - private static final IModel> SELECTED = new ListModel<>(List.of("A", "D")); - - private static final ListModel ALL = new ListModel<>(List.of("A", "B", "C", "D")); - @Test public void isRendered() { TestPage> testPage = new TestPage.Builder>().build( new AjaxPalettePanel.Builder().setAllowOrder(true).build( - TestPage.FIELD, SELECTED, ALL)); + TestPage.FIELD, + new ListModel<>(List.of("A", "D")), + new ListModel<>(List.of("A", "B", "C", "D")))); TESTER.startPage(testPage); FormTester formTester = TESTER.newFormTester(testPage.getForm().getId()); formTester.submit(); - Collection list = testPage.getFieldPanel().getModelCollection(); + @SuppressWarnings("unchecked") + Palette palette = (Palette) ReflectionTestUtils.getField(testPage.getFieldPanel(), "palette"); + Collection list = palette.getModelCollection(); assertEquals(2, list.size()); Iterator iterator = list.iterator(); assertEquals("A", iterator.next()); diff --git a/pom.xml b/pom.xml index 0f5d18c7b1a..e961d1851aa 100644 --- a/pom.xml +++ b/pom.xml @@ -523,7 +523,7 @@ under the License. 9805 60000 - 11.0.18 + 11.0.20 39.0.1.Final 7.2026.3 4.1.6