From 49701987815c6596d5221583d74b9c3c320aef15 Mon Sep 17 00:00:00 2001 From: Boubaker Khanfir Date: Fri, 7 Feb 2025 11:27:29 +0100 Subject: [PATCH] fix: Fix Impersonating Addon Containers - MEED-8349 - Meeds-io/meeds#2894 (#342) Prior to this change, when creating a site **from a template** where we have an `addon container` defined into it with a declared application, then the impersonation process of created site will consider container's children and will attempt to store in database its preferences. This change will ensure to **ignore** `addon container` children which doesn't have a dedicated `StorageId` where to store preferences. --- .../layout/service/PageLayoutService.java | 12 +++++--- .../service/PortletInstanceService.java | 28 +++++++++++-------- .../layout/service/PageLayoutServiceTest.java | 4 +++ 3 files changed, 29 insertions(+), 15 deletions(-) diff --git a/layout-service/src/main/java/io/meeds/layout/service/PageLayoutService.java b/layout-service/src/main/java/io/meeds/layout/service/PageLayoutService.java index e4f4337c6..2d21338ad 100644 --- a/layout-service/src/main/java/io/meeds/layout/service/PageLayoutService.java +++ b/layout-service/src/main/java/io/meeds/layout/service/PageLayoutService.java @@ -69,6 +69,8 @@ @Service public class PageLayoutService { + private static final String ADDON_CONTAINER_FACTORY_ID = "addonContainer"; + private static final Log LOG = ExoLogger.getLogger(PageLayoutService.class); private static final Pattern GENERIC_STYLE_MATCHER_VALIDATOR = Pattern.compile("[#0-9a-zA-Z\\(\\),\\./\"'\\-%_ ]+"); @@ -427,7 +429,7 @@ private PageType getPageType(String pageType) { } private void expandAddonContainerChildren(Container container) { - if (StringUtils.equals(container.getFactoryId(), "addonContainer")) { + if (StringUtils.equals(container.getFactoryId(), ADDON_CONTAINER_FACTORY_ID)) { List applications = addOnService.getApplications(container.getName()); if (CollectionUtils.isNotEmpty(applications)) { container.setChildren(new ArrayList<>(applications)); @@ -451,7 +453,7 @@ private void replaceAddonContainerChildren(Container container) { for (int i = subContainers.size() - 1; i >= 0; i--) { ModelObject modelObject = subContainers.get(i); if (modelObject instanceof Container subContainer) { - if (StringUtils.equals(subContainer.getFactoryId(), "addonContainer")) { + if (StringUtils.equals(subContainer.getFactoryId(), ADDON_CONTAINER_FACTORY_ID)) { List applications = addOnService.getApplications(subContainer.getName()); if (CollectionUtils.isNotEmpty(applications)) { addonContainerChildren.put(i, applications); @@ -529,7 +531,9 @@ private ModelObject filterByPermission(ModelObject modelObject, String username) } private void impersonateModel(ModelObject object, Page page) { - if (object instanceof Container container) { + if (object instanceof Container container + // Keep the addonContainer reference instead of storing its children + && !StringUtils.equals(container.getFactoryId(), ADDON_CONTAINER_FACTORY_ID)) { ArrayList children = container.getChildren(); try { containerLayoutService.impersonateContainer(container, page); @@ -544,7 +548,7 @@ private void impersonateModel(ModelObject object, Page page) { } } else if (object instanceof Application application) { Portlet preferences = portletInstanceService.getApplicationPortletPreferences(application); - if (preferences != null) { + if (preferences != null && StringUtils.isNotBlank(application.getStorageId())) { layoutService.save(application.getState(), preferences); } } diff --git a/layout-service/src/main/java/io/meeds/layout/service/PortletInstanceService.java b/layout-service/src/main/java/io/meeds/layout/service/PortletInstanceService.java index 823d4da43..4f219197c 100644 --- a/layout-service/src/main/java/io/meeds/layout/service/PortletInstanceService.java +++ b/layout-service/src/main/java/io/meeds/layout/service/PortletInstanceService.java @@ -18,7 +18,6 @@ */ package io.meeds.layout.service; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -26,6 +25,7 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; +import java.util.stream.StreamSupport; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.MapUtils; @@ -445,18 +445,24 @@ private List getPortletInstancePreferences(PortletIns private List getApplicationPreferences(Application application) { String portletName = portletInstanceLayoutStorage.getApplicationPortletName(application); - Portlet preferences = portletInstanceLayoutStorage.getApplicationPreferences(Long.parseLong(application.getStorageId())); - PortletInstancePreferencePlugin plugin = preferencePlugins.get(portletName); - if (plugin == null) { - if (preferences == null) { - return Collections.emptyList(); - } else { - List instancePreferences = new ArrayList<>(); - preferences.forEach(p -> instancePreferences.add(new PortletInstancePreference(p.getName(), p.getValue()))); - return instancePreferences; - } + Portlet preferences; + if (StringUtils.isNumeric(application.getStorageId())) { + preferences = portletInstanceLayoutStorage.getApplicationPreferences(Long.parseLong(application.getStorageId())); + } else if (application.getState() instanceof TransientApplicationState transientState) { + // Can happen when application is coming from AddonContainer + preferences = transientState.getContentState(); } else { + preferences = null; + } + PortletInstancePreferencePlugin plugin = preferencePlugins.get(portletName); + if (plugin == null && preferences == null) { + return Collections.emptyList(); + } else if (plugin != null) { return plugin.generatePreferences(application, preferences); + } else { + return StreamSupport.stream(preferences.spliterator(), false) + .map(p -> new PortletInstancePreference(p.getName(), p.getValue())) + .toList(); } } diff --git a/layout-service/src/test/java/io/meeds/layout/service/PageLayoutServiceTest.java b/layout-service/src/test/java/io/meeds/layout/service/PageLayoutServiceTest.java index 4e06e1422..86d04583f 100644 --- a/layout-service/src/test/java/io/meeds/layout/service/PageLayoutServiceTest.java +++ b/layout-service/src/test/java/io/meeds/layout/service/PageLayoutServiceTest.java @@ -184,6 +184,10 @@ public void impersonateSite() { pageLayoutService.impersonateSite(SITE_KEY); verify(containerLayoutService).impersonateContainer(container, page); + verify(layoutService, never()).save(state, preferences); + + when(application.getStorageId()).thenReturn("2"); + pageLayoutService.impersonateSite(SITE_KEY); verify(layoutService).save(state, preferences); }