CVE-2025-43743
Description
Liferay Portal 7.4.0 through 7.4.3.132, and Liferay DXP 2025.Q1.0 through 2025.Q1.5, 2024.Q4.0 through 2024.Q4.7, 2024.Q3.1 through 2024.Q3.13, 2024.Q2.0 through 2024.Q2.13, 2024.Q1.1 through 2024.Q1.15 and 7.4 GA through update 92 allows any authenticated remote user to view other calendars by allowing them to enumerate the names of other users, given an attacker the possibility to send phishing to these users.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
com.liferay.portal:release.portal.bomMaven | >= 7.4.0-ga1, <= 7.4.3.132-ga132 | — |
Affected products
2- Liferay/DXPv5Range: 7.4.13
Patches
91e368205c710LPD-51804 Add playwright test
1 file changed · +132 −1
modules/test/playwright/tests/calendar-web/calendarEvent.spec.ts+132 −1 modified@@ -7,22 +7,28 @@ import {expect, mergeTests} from '@playwright/test'; import {apiHelpersTest} from '../../fixtures/apiHelpersTest'; import {calendarPagesTest} from '../../fixtures/calendarPagesTest'; +import {collectionsPagesTest} from '../../fixtures/collectionsPagesTest'; +import {dataApiHelpersTest} from '../../fixtures/dataApiHelpersTest'; import {featureFlagsTest} from '../../fixtures/featureFlagsTest'; import {isolatedSiteTest} from '../../fixtures/isolatedSiteTest'; import {loginTest} from '../../fixtures/loginTest'; import {pageEditorPagesTest} from '../../fixtures/pageEditorPagesTest'; import {getRandomInt} from '../../utils/getRandomInt'; import getRandomString from '../../utils/getRandomString'; +import performLogin, {performLogout, userData} from '../../utils/performLogin'; +import {journalPagesTest} from '../journal-web/fixtures/journalPagesTest'; import getPageDefinition from '../layout-content-page-editor-web/utils/getPageDefinition'; import getWidgetDefinition from '../layout-content-page-editor-web/utils/getWidgetDefinition'; import {toLocalDateTimeFormatted} from './utils/toLocalDateTimeFormatted'; - export const test = mergeTests( apiHelpersTest, calendarPagesTest, + collectionsPagesTest, + dataApiHelpersTest, featureFlagsTest({ 'LPS-178052': {enabled: true}, }), + journalPagesTest, isolatedSiteTest, loginTest(), pageEditorPagesTest @@ -90,6 +96,131 @@ test('assert that past events have respective within the click more dropdown', a ).toHaveClass(/scheduler-event-past/); }); +test('assert that unprivileged users are denied access to calendar URLs', async ({ + apiHelpers, + calendarWidgetPage, + collectionsPage, + page, + pageEditorPage, + site, +}) => { + + // Add calendar event + + const title = getRandomString(); + + await calendarWidgetPage.addEvent({ + allDay: true, + publishEvent: true, + title, + }); + + // Add calendar event dynamic collection + + await collectionsPage.goto(site.friendlyUrlPath); + + const calendarEventDynamicCollection = getRandomString(); + + await collectionsPage.addNewDynamicCollection( + calendarEventDynamicCollection + ); + + await page.getByLabel('Item Type').selectOption({label: 'Calendar Event'}); + + await page.getByRole('button', {name: 'Save'}).click(); + + // Add collection display + + const layout = await apiHelpers.jsonWebServicesLayout.addLayout({ + groupId: site.id, + options: {type: 'content'}, + title: getRandomString(), + }); + + await pageEditorPage.goto(layout, site.friendlyUrlPath); + + await pageEditorPage.addFragment('Content Display', 'Collection Display'); + + await pageEditorPage.selectFragment( + await pageEditorPage.getFragmentId('Collection Display') + ); + + await pageEditorPage.chooseCollectionDisplayOption( + 'Collections', + calendarEventDynamicCollection + ); + + await pageEditorPage.waitForChangesSaved(); + + // Add heading fragment + + await pageEditorPage.addFragment( + 'Basic Components', + 'Heading', + page.locator('.page-editor__collection-item.empty').first() + ); + + // Map heading fragment to event URL field + + await pageEditorPage.goToSidebarTab('Browser'); + + await page.getByLabel('Select element-text').click(); + + await page.getByLabel('Field').selectOption('Event URL'); + + await pageEditorPage.waitForChangesSaved(); + + // Access calendar event URL + + const eventURL = await page + .getByText('/calendar/shared/-/calendar/') + .textContent(); + + await page.goto(eventURL); + + await expect(page.getByText(site.key)).toBeVisible(); + await expect(page.getByText(title)).toBeVisible(); + + // Add new user + + const user = await apiHelpers.headlessAdminUser.postUserAccount(); + + apiHelpers.data.push({ + id: user.id, + type: 'userAccount', + }); + + userData[user.alternateName] = { + name: user.givenName, + password: 'test', + surname: user.familyName, + }; + + await performLogout(page); + await performLogin(page, user.alternateName); + + // Access event URL as new user + + await page.goto(eventURL); + + await expect(page.getByText(site.key)).not.toBeVisible(); + await expect(page.getByText(title)).not.toBeVisible(); + + // Access calendar portlet as new user + + await page.goto( + `/group/guest/~/control_panel/manage?p_p_id=com_liferay_calendar_web_portlet_CalendarPortlet&p_p_lifecycle=0&p_p_state=maximized&p_p_auth=obAWFnzM` + ); + + await expect( + page + .getByText( + 'You do not have the roles required to access this portlet.' + ) + .first() + ).toBeVisible(); +}); + test('can create all-day calendar event with different time zone', async ({ calendarWidgetPage, }) => {
025281476644LPD-51804 Add unit test
1 file changed · +42 −0
modules/apps/calendar/calendar-web/src/test/java/com/liferay/calendar/web/internal/info/item/provider/CalendarBookingInfoItemFieldValuesProviderTest.java+42 −0 modified@@ -16,8 +16,11 @@ import com.liferay.portal.kernel.service.CompanyLocalService; import com.liferay.portal.kernel.service.GroupLocalService; import com.liferay.portal.kernel.service.LayoutLocalService; +import com.liferay.portal.kernel.service.ServiceContext; +import com.liferay.portal.kernel.service.ServiceContextThreadLocal; import com.liferay.portal.kernel.test.ReflectionTestUtil; import com.liferay.portal.kernel.test.util.RandomTestUtil; +import com.liferay.portal.kernel.theme.ThemeDisplay; import com.liferay.portal.kernel.util.Portal; import com.liferay.portal.kernel.util.PortalUtil; import com.liferay.portal.test.rule.LiferayUnitTestRule; @@ -64,6 +67,42 @@ public void testGetCalendarBookingURL() throws Exception { _getCalendarBookingURL(_GUEST_LAYOUT_ACTUAL_URL), _calendarBookingInfoItemFieldValuesProvider.getCalendarBookingURL( _calendarBooking)); + + ServiceContext serviceContext = Mockito.mock(ServiceContext.class); + + ThemeDisplay themeDisplay = Mockito.mock(ThemeDisplay.class); + + Mockito.when( + themeDisplay.getPathFriendlyURLPublic() + ).thenReturn( + _PATH_FRIENDLY_URL_PUBLIC + ); + + Mockito.when( + themeDisplay.getPortalURL() + ).thenReturn( + _PORTAL_URL + ); + + Mockito.when( + serviceContext.getThemeDisplay() + ).thenReturn( + themeDisplay + ); + + try { + ServiceContextThreadLocal.pushServiceContext(serviceContext); + + Assert.assertEquals( + StringBundler.concat( + _PORTAL_URL, _PATH_FRIENDLY_URL_PUBLIC, + "/calendar/shared/-/calendar/", _CALENDAR_BOOKING_ID), + _calendarBookingInfoItemFieldValuesProvider. + getCalendarBookingURL(_calendarBooking)); + } + finally { + ServiceContextThreadLocal.popServiceContext(); + } } private String _getCalendarBookingURL(String layoutActualURL) { @@ -229,6 +268,9 @@ private void _setUpPortal() throws Exception { private static final String _LAYOUT_ACTUAL_URL = RandomTestUtil.randomString(); + private static final String _PATH_FRIENDLY_URL_PUBLIC = + RandomTestUtil.randomString(); + private static final String _PORTAL_URL = RandomTestUtil.randomString(); private static final String _PORTLET_NAMESPACE =
bd89933cc902LPD-51804 Generate new URL to view calendar booking
2 files changed · +28 −0
modules/apps/calendar/calendar-service/src/main/java/com/liferay/calendar/internal/notification/NotificationTemplateContextFactory.java+17 −0 modified@@ -28,6 +28,8 @@ import com.liferay.portal.kernel.service.GroupLocalService; import com.liferay.portal.kernel.service.LayoutLocalService; import com.liferay.portal.kernel.service.ServiceContext; +import com.liferay.portal.kernel.service.ServiceContextThreadLocal; +import com.liferay.portal.kernel.theme.ThemeDisplay; import com.liferay.portal.kernel.util.CalendarUtil; import com.liferay.portal.kernel.util.FastDateFormatFactoryUtil; import com.liferay.portal.kernel.util.FileUtil; @@ -217,6 +219,21 @@ private static String _getCalendarBookingURL( User user) throws Exception { + ServiceContext serviceContext = + ServiceContextThreadLocal.getServiceContext(); + + if (serviceContext != null) { + ThemeDisplay themeDisplay = serviceContext.getThemeDisplay(); + + if (themeDisplay != null) { + return StringBundler.concat( + themeDisplay.getPortalURL(), + themeDisplay.getPathFriendlyURLPublic(), + "/calendar/shared/-/calendar/", + calendarBooking.getCalendarBookingId()); + } + } + String url = layoutURL; if (layoutURL == null) {
modules/apps/calendar/calendar-web/src/main/java/com/liferay/calendar/web/internal/info/item/provider/CalendarBookingInfoItemFieldValuesProvider.java+11 −0 modified@@ -18,6 +18,7 @@ import com.liferay.info.item.provider.InfoItemFieldValuesProvider; import com.liferay.info.localized.InfoLocalizedValue; import com.liferay.layout.page.template.info.item.provider.DisplayPageInfoItemFieldSetProvider; +import com.liferay.petra.string.StringBundler; import com.liferay.petra.string.StringPool; import com.liferay.portal.kernel.exception.PortalException; import com.liferay.portal.kernel.language.Language; @@ -92,6 +93,16 @@ calendarBooking, _getThemeDisplay()) * User, long)} */ protected String getCalendarBookingURL(CalendarBooking calendarBooking) { + ThemeDisplay themeDisplay = _getThemeDisplay(); + + if (themeDisplay != null) { + return StringBundler.concat( + themeDisplay.getPortalURL(), + themeDisplay.getPathFriendlyURLPublic(), + "/calendar/shared/-/calendar/", + calendarBooking.getCalendarBookingId()); + } + try { Company company = _companyLocalService.getCompany( calendarBooking.getCompanyId());
9a88f7fa98f9LPD-51804 Add new route pattern
1 file changed · +6 −0
modules/apps/calendar/calendar-web/src/main/resources/META-INF/friendly-url-routes/routes.xml+6 −0 modified@@ -6,6 +6,12 @@ <pattern></pattern> <implicit-parameter name="mvcRenderCommandName">/calendar</implicit-parameter> </route> + <route> + <pattern>/{calendarBookingId:\d+}</pattern> + <implicit-parameter name="mvcPath">/view_calendar_booking.jsp</implicit-parameter> + <implicit-parameter name="p_p_id">com_liferay_calendar_web_portlet_CalendarPortlet</implicit-parameter> + <implicit-parameter name="shared">true</implicit-parameter> + </route> <route> <pattern>/{instanceId}/event/{calendarBookingId}</pattern> <implicit-parameter name="mvcPath">/view_calendar_booking.jsp</implicit-parameter>
1513ed29f830LPD-51804 Implement CalendarPortletLayoutTypeAccessPolicy similar to DDMFormPortletLayoutTypeAccessPolicy
1 file changed · +64 −0
modules/apps/calendar/calendar-web/src/main/java/com/liferay/calendar/web/internal/model/CalendarPortletLayoutTypeAccessPolicy.java+64 −0 added@@ -0,0 +1,64 @@ +/** + * SPDX-FileCopyrightText: (c) 2025 Liferay, Inc. https://liferay.com + * SPDX-License-Identifier: LGPL-2.1-or-later OR LicenseRef-Liferay-DXP-EULA-2.0.0-2023-06 + */ + +package com.liferay.calendar.web.internal.model; + +import com.liferay.calendar.constants.CalendarPortletKeys; +import com.liferay.portal.kernel.model.Layout; +import com.liferay.portal.kernel.model.LayoutTypeAccessPolicy; +import com.liferay.portal.kernel.model.Portlet; +import com.liferay.portal.kernel.model.impl.DefaultLayoutTypeAccessPolicyImpl; +import com.liferay.portal.kernel.security.permission.PermissionChecker; +import com.liferay.portal.kernel.util.StringUtil; + +import org.osgi.service.component.annotations.Component; + +/** + * @author Carolina Barbosa + */ +@Component( + property = "layout.type=" + CalendarPortletKeys.CALENDAR, + service = LayoutTypeAccessPolicy.class +) +public class CalendarPortletLayoutTypeAccessPolicy + extends DefaultLayoutTypeAccessPolicyImpl { + + @Override + public boolean isAddLayoutAllowed( + PermissionChecker permissionChecker, Layout layout) { + + return false; + } + + @Override + public boolean isCustomizeLayoutAllowed( + PermissionChecker permissionChecker, Layout layout) { + + return false; + } + + @Override + public boolean isDeleteLayoutAllowed( + PermissionChecker permissionChecker, Layout layout) { + + return false; + } + + @Override + public boolean isUpdateLayoutAllowed( + PermissionChecker permissionChecker, Layout layout) { + + return false; + } + + @Override + protected boolean isAccessGrantedByPortletOnPage( + Layout layout, Portlet portlet) { + + return StringUtil.equalsIgnoreCase( + portlet.getPortletId(), CalendarPortletKeys.CALENDAR); + } + +} \ No newline at end of file
144e4a276e45LPD-51804 Implement CalendarPortletLayoutTypeController similar to DDMFormPortletLayoutTypeController
7 files changed · +186 −0
modules/apps/calendar/calendar-web/build.gradle+1 −0 modified@@ -23,6 +23,7 @@ dependencies { compileOnly project(":apps:info:info-api") compileOnly project(":apps:layout:layout-display-page-api") compileOnly project(":apps:layout:layout-page-template-api") + compileOnly project(":apps:layout:layout-taglib") compileOnly project(":apps:layout:layout-type-controller:layout-type-controller-api") compileOnly project(":apps:portal-workflow:portal-workflow-taglib") compileOnly project(":apps:portal:portal-dao-orm-custom-sql-api")
modules/apps/calendar/calendar-web/src/main/java/com/liferay/calendar/web/internal/layout/display/page/type/controller/CalendarPortletLayoutTypeController.java+112 −0 added@@ -0,0 +1,112 @@ +/** + * SPDX-FileCopyrightText: (c) 2025 Liferay, Inc. https://liferay.com + * SPDX-License-Identifier: LGPL-2.1-or-later OR LicenseRef-Liferay-DXP-EULA-2.0.0-2023-06 + */ + +package com.liferay.calendar.web.internal.layout.display.page.type.controller; + +import com.liferay.calendar.constants.CalendarPortletKeys; +import com.liferay.layout.type.controller.BaseLayoutTypeControllerImpl; +import com.liferay.petra.io.unsync.UnsyncStringWriter; +import com.liferay.portal.kernel.model.LayoutConstants; +import com.liferay.portal.kernel.model.LayoutTypeController; +import com.liferay.portal.kernel.servlet.PipingServletResponse; + +import javax.servlet.ServletContext; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletResponse; + +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; + +/** + * @author Carolina Barbosa + */ +@Component( + property = "layout.type=" + CalendarPortletKeys.CALENDAR, + service = LayoutTypeController.class +) +public class CalendarPortletLayoutTypeController + extends BaseLayoutTypeControllerImpl { + + @Override + public String getType() { + return LayoutConstants.TYPE_PORTLET; + } + + @Override + public String getURL() { + return _URL; + } + + @Override + public boolean isBrowsable() { + return false; + } + + @Override + public boolean isFirstPageable() { + return true; + } + + @Override + public boolean isFullPageDisplayable() { + return false; + } + + @Override + public boolean isInstanceable() { + return false; + } + + @Override + public boolean isParentable() { + return false; + } + + @Override + public boolean isSitemapable() { + return false; + } + + @Override + public boolean isURLFriendliable() { + return true; + } + + @Override + protected ServletResponse createServletResponse( + HttpServletResponse httpServletResponse, + UnsyncStringWriter unsyncStringWriter) { + + return new PipingServletResponse( + httpServletResponse, unsyncStringWriter); + } + + @Override + protected String getEditPage() { + return _EDIT_PAGE; + } + + @Override + protected ServletContext getServletContext() { + return _servletContext; + } + + @Override + protected String getViewPage() { + return _VIEW_PAGE; + } + + private static final String _EDIT_PAGE = "/layout/edit/portlet.jsp"; + + private static final String _URL = + "${liferay:mainPath}/portal/layout?p_l_id=${liferay:plid}" + + "&p_p_state=pop_up&p_v_l_s_g_id=${liferay:pvlsgid}"; + + private static final String _VIEW_PAGE = "/layout/view/portlet.jsp"; + + @Reference(target = "(osgi.web.symbolicname=com.liferay.calendar.web)") + private ServletContext _servletContext; + +} \ No newline at end of file
modules/apps/calendar/calendar-web/src/main/resources/META-INF/resources/layout/edit/init.jsp+8 −0 added@@ -0,0 +1,8 @@ +<%-- +/** + * SPDX-FileCopyrightText: (c) 2025 Liferay, Inc. https://liferay.com + * SPDX-License-Identifier: LGPL-2.1-or-later OR LicenseRef-Liferay-DXP-EULA-2.0.0-2023-06 + */ +--%> + +<%@ include file="/layout/init.jsp" %> \ No newline at end of file
modules/apps/calendar/calendar-web/src/main/resources/META-INF/resources/layout/edit/portlet.jsp+8 −0 added@@ -0,0 +1,8 @@ +<%-- +/** + * SPDX-FileCopyrightText: (c) 2025 Liferay, Inc. https://liferay.com + * SPDX-License-Identifier: LGPL-2.1-or-later OR LicenseRef-Liferay-DXP-EULA-2.0.0-2023-06 + */ +--%> + +<%@ include file="/layout/edit/init.jsp" %> \ No newline at end of file
modules/apps/calendar/calendar-web/src/main/resources/META-INF/resources/layout/init.jsp+6 −0 added@@ -0,0 +1,6 @@ +<%-- +/** + * SPDX-FileCopyrightText: (c) 2025 Liferay, Inc. https://liferay.com + * SPDX-License-Identifier: LGPL-2.1-or-later OR LicenseRef-Liferay-DXP-EULA-2.0.0-2023-06 + */ +--%> \ No newline at end of file
modules/apps/calendar/calendar-web/src/main/resources/META-INF/resources/layout/view/init.jsp+33 −0 added@@ -0,0 +1,33 @@ +<%-- +/** + * SPDX-FileCopyrightText: (c) 2025 Liferay, Inc. https://liferay.com + * SPDX-License-Identifier: LGPL-2.1-or-later OR LicenseRef-Liferay-DXP-EULA-2.0.0-2023-06 + */ +--%> + +<%@ include file="/layout/init.jsp" %> + +<%@ taglib uri="http://liferay.com/tld/aui" prefix="aui" %><%@ +taglib uri="http://liferay.com/tld/layout" prefix="liferay-layout" %><%@ +taglib uri="http://liferay.com/tld/theme" prefix="liferay-theme" %><%@ +taglib uri="http://liferay.com/tld/util" prefix="liferay-util" %> + +<%@ page import="com.liferay.portal.kernel.model.LayoutTemplateConstants" %><%@ +page import="com.liferay.portal.kernel.service.LayoutTemplateLocalServiceUtil" %><%@ +page import="com.liferay.portal.kernel.util.ParamUtil" %><%@ +page import="com.liferay.portal.kernel.util.Validator" %><%@ +page import="com.liferay.portal.layoutconfiguration.util.RuntimePageUtil" %> + +<liferay-theme:defineObjects /> + +<liferay-util:html-top> + <meta content="initial-scale=1.0, width=device-width" name="viewport" /> +</liferay-util:html-top> + +<aui:script> + var buttonHolder = document.querySelector('.button-holder'); + + if (buttonHolder) { + buttonHolder.classList.remove('dialog-footer'); + } +</aui:script> \ No newline at end of file
modules/apps/calendar/calendar-web/src/main/resources/META-INF/resources/layout/view/portlet.jsp+18 −0 added@@ -0,0 +1,18 @@ +<%-- +/** + * SPDX-FileCopyrightText: (c) 2025 Liferay, Inc. https://liferay.com + * SPDX-License-Identifier: LGPL-2.1-or-later OR LicenseRef-Liferay-DXP-EULA-2.0.0-2023-06 + */ +--%> + +<%@ include file="/layout/view/init.jsp" %> + +<% +String velocityTemplateContent = LayoutTemplateLocalServiceUtil.getContent("pop_up", true, theme.getThemeId()); + +if (Validator.isNotNull(velocityTemplateContent)) { + RuntimePageUtil.processTemplate(request, response, ParamUtil.getString(request, "p_p_id"), theme.getThemeId() + LayoutTemplateConstants.STANDARD_SEPARATOR + "pop_up", velocityTemplateContent); +} +%> + +<liferay-layout:layout-common /> \ No newline at end of file
7d6e1bccb62aLPD-51804 Implement AddDefaultSharedCalendarLayoutPortalInstanceLifecycleListener similar to AddDefaultSharedFormLayoutPortalInstanceLifecycleListener
2 files changed · +118 −0
modules/apps/calendar/calendar-web/build.gradle+4 −0 modified@@ -15,21 +15,25 @@ dependencies { compileOnly project(":apps:change-tracking:change-tracking-spi") compileOnly project(":apps:comment:comment-taglib") compileOnly project(":apps:expando:expando-taglib") + compileOnly project(":apps:fragment:fragment-api") compileOnly project(":apps:friendly-url:friendly-url-api") compileOnly project(":apps:frontend-editor:frontend-editor-taglib") compileOnly project(":apps:frontend-taglib:frontend-taglib") compileOnly project(":apps:frontend-taglib:frontend-taglib-clay") compileOnly project(":apps:info:info-api") compileOnly project(":apps:layout:layout-display-page-api") compileOnly project(":apps:layout:layout-page-template-api") + compileOnly project(":apps:layout:layout-type-controller:layout-type-controller-api") compileOnly project(":apps:portal-workflow:portal-workflow-taglib") compileOnly project(":apps:portal:portal-dao-orm-custom-sql-api") + compileOnly project(":apps:portal:portal-instance-lifecycle-api") compileOnly project(":apps:ratings:ratings-taglib") compileOnly project(":apps:rss:rss-api") compileOnly project(":apps:rss:rss-taglib") compileOnly project(":apps:static:portal:portal-upgrade-api") compileOnly project(":apps:template:template-api") compileOnly project(":core:petra:petra-function") + compileOnly project(":core:petra:petra-io") compileOnly project(":core:petra:petra-lang") compileOnly project(":core:petra:petra-sql-dsl-api") compileOnly project(":core:petra:petra-string")
modules/apps/calendar/calendar-web/src/main/java/com/liferay/calendar/web/internal/instance/lifecycle/AddDefaultSharedCalendarLayoutPortalInstanceLifecycleListener.java+114 −0 added@@ -0,0 +1,114 @@ +/** + * SPDX-FileCopyrightText: (c) 2025 Liferay, Inc. https://liferay.com + * SPDX-License-Identifier: LGPL-2.1-or-later OR LicenseRef-Liferay-DXP-EULA-2.0.0-2023-06 + */ + +package com.liferay.calendar.web.internal.instance.lifecycle; + +import com.liferay.calendar.constants.CalendarPortletKeys; +import com.liferay.petra.string.StringPool; +import com.liferay.portal.instance.lifecycle.BasePortalInstanceLifecycleListener; +import com.liferay.portal.instance.lifecycle.PortalInstanceLifecycleListener; +import com.liferay.portal.kernel.model.Company; +import com.liferay.portal.kernel.model.Group; +import com.liferay.portal.kernel.model.GroupConstants; +import com.liferay.portal.kernel.model.Layout; +import com.liferay.portal.kernel.model.LayoutConstants; +import com.liferay.portal.kernel.service.GroupLocalService; +import com.liferay.portal.kernel.service.LayoutLocalService; +import com.liferay.portal.kernel.service.ServiceContext; +import com.liferay.portal.kernel.service.UserLocalService; +import com.liferay.portal.kernel.util.HashMapBuilder; +import com.liferay.portal.kernel.util.LocaleUtil; +import com.liferay.portal.kernel.util.StringUtil; + +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; + +/** + * @author Carolina Barbosa + */ +@Component(service = PortalInstanceLifecycleListener.class) +public class AddDefaultSharedCalendarLayoutPortalInstanceLifecycleListener + extends BasePortalInstanceLifecycleListener { + + @Override + public void portalInstanceRegistered(Company company) throws Exception { + Group group = _groupLocalService.fetchFriendlyURLGroup( + company.getCompanyId(), GroupConstants.CALENDAR_FRIENDLY_URL); + + if (group == null) { + group = _groupLocalService.addGroup( + _userLocalService.getGuestUserId(company.getCompanyId()), + GroupConstants.DEFAULT_PARENT_GROUP_ID, null, 0, + GroupConstants.DEFAULT_LIVE_GROUP_ID, + HashMapBuilder.put( + LocaleUtil.getDefault(), GroupConstants.CALENDAR + ).build(), + null, GroupConstants.TYPE_SITE_PRIVATE, true, + GroupConstants.DEFAULT_MEMBERSHIP_RESTRICTION, + GroupConstants.CALENDAR_FRIENDLY_URL, false, false, true, null); + } + + Layout privateLayout = _getLayout( + company.getCompanyId(), group.getGroupId(), true); + + _updateLayout(privateLayout); + + Layout publicLayout = _getLayout( + company.getCompanyId(), group.getGroupId(), false); + + _updateLayout(publicLayout); + } + + private Layout _getLayout( + long companyId, long groupId, boolean privateLayout) + throws Exception { + + Layout layout = _layoutLocalService.fetchLayoutByFriendlyURL( + groupId, privateLayout, "/shared"); + + if (layout != null) { + return layout; + } + + ServiceContext serviceContext = new ServiceContext(); + + serviceContext.setAddGroupPermissions(true); + serviceContext.setAddGuestPermissions(true); + serviceContext.setAttribute( + "layout.instanceable.allowed", Boolean.TRUE); + serviceContext.setAttribute("layoutUpdateable", Boolean.FALSE); + serviceContext.setScopeGroupId(groupId); + + long guestUserId = _userLocalService.getGuestUserId(companyId); + + serviceContext.setUserId(guestUserId); + + return _layoutLocalService.addLayout( + null, guestUserId, groupId, privateLayout, + LayoutConstants.DEFAULT_PARENT_LAYOUT_ID, "Shared", + StringPool.BLANK, StringPool.BLANK, CalendarPortletKeys.CALENDAR, + true, "/shared", serviceContext); + } + + private void _updateLayout(Layout layout) throws Exception { + if (StringUtil.equals(layout.getType(), CalendarPortletKeys.CALENDAR)) { + return; + } + + layout.setType(CalendarPortletKeys.CALENDAR); + + _layoutLocalService.updateLayout(layout); + } + + @Reference + private GroupLocalService _groupLocalService; + + @Reference + private LayoutLocalService _layoutLocalService; + + @Reference + private UserLocalService _userLocalService; + +} \ No newline at end of file
9aba859a6956LPD-51804 Add new system group for Calendar
2 files changed · +13 −2
portal-impl/src/com/liferay/portal/service/impl/GroupLocalServiceImpl.java+7 −1 modified@@ -451,6 +451,7 @@ else if ((type != GroupConstants.TYPE_DEPOT) && if (className.equals(Group.class.getName())) { if (!site && (liveGroupId == 0) && !(StringUtil.startsWith(groupKey, GroupConstants.APP) || + groupKey.equals(GroupConstants.CALENDAR) || groupKey.equals(GroupConstants.CMS) || groupKey.equals(GroupConstants.CONTROL_PANEL) || groupKey.equals(GroupConstants.FORMS))) { @@ -868,7 +869,12 @@ public void checkSystemGroups(long companyId) throws PortalException { boolean site = true; UnicodeProperties typeSettingsUnicodeProperties = null; - if (groupKey.equals(GroupConstants.CMS)) { + if (groupKey.equals(GroupConstants.CALENDAR)) { + type = GroupConstants.TYPE_SITE_PRIVATE; + friendlyURL = GroupConstants.CALENDAR_FRIENDLY_URL; + site = false; + } + else if (groupKey.equals(GroupConstants.CMS)) { type = GroupConstants.TYPE_SITE_PRIVATE; friendlyURL = GroupConstants.CMS_FRIENDLY_URL; site = false;
portal-kernel/src/com/liferay/portal/kernel/model/GroupConstants.java+6 −1 modified@@ -14,6 +14,10 @@ public class GroupConstants { public static final String APP = "App"; + public static final String CALENDAR = "Calendar"; + + public static final String CALENDAR_FRIENDLY_URL = "/calendar"; + public static final String CMS = "CMS"; public static final String CMS_FRIENDLY_URL = "/cms"; @@ -43,7 +47,8 @@ public class GroupConstants { public static final int MEMBERSHIP_RESTRICTION_TO_PARENT_SITE_MEMBERS = 1; public static final String[] SYSTEM_GROUPS = { - CMS, CONTROL_PANEL, FORMS, GUEST, GroupConstants.USER_PERSONAL_SITE + CALENDAR, CMS, CONTROL_PANEL, FORMS, GUEST, + GroupConstants.USER_PERSONAL_SITE }; public static final int TYPE_DEPOT = 5;
d999a8e1902eLPD-51804 Remove CalendarPortlet from whitelist
1 file changed · +0 −1
portal-impl/src/portal.properties+0 −1 modified@@ -359,7 +359,6 @@ # Env: LIFERAY_PORTLET_PERIOD_ADD_PERIOD_DEFAULT_PERIOD_RESOURCE_PERIOD_CHECK_PERIOD_WHITELIST # portlet.add.default.resource.check.whitelist=\ - com_liferay_calendar_web_portlet_CalendarPortlet,\ com_liferay_login_web_portlet_FastLoginPortlet,\ com_liferay_login_web_portlet_LoginPortlet,\ com_liferay_portlet_configuration_css_web_portlet_PortletConfigurationCSSPortlet,\
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
13- github.com/advisories/GHSA-g4vp-4gqr-7v8cghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2025-43743ghsaADVISORY
- github.com/liferay/liferay-portal/commit/02528147664475cd9f7205cd8bc05dfd43832201ghsaWEB
- github.com/liferay/liferay-portal/commit/144e4a276e456c4b7a0831ff038241f82a9181dbghsaWEB
- github.com/liferay/liferay-portal/commit/1513ed29f830c9119ee6be623ae783e545da4845ghsaWEB
- github.com/liferay/liferay-portal/commit/1e368205c710403e76749e38127419780acdda9dghsaWEB
- github.com/liferay/liferay-portal/commit/7d6e1bccb62a41e944e0459d2c4b1eb9fdb31b8eghsaWEB
- github.com/liferay/liferay-portal/commit/9a88f7fa98f9fc11a9eab444a256204cccc82b77ghsaWEB
- github.com/liferay/liferay-portal/commit/9aba859a6956786bcd8ce434ef063eed01b5ec6eghsaWEB
- github.com/liferay/liferay-portal/commit/bd89933cc9022a98fc34b562ce3573a58f14cf38ghsaWEB
- github.com/liferay/liferay-portal/commit/d999a8e1902e88fdd7a26758f137925d969a639dghsaWEB
- liferay.atlassian.net/browse/LPE-18206ghsaWEB
- liferay.dev/portal/security/known-vulnerabilities/-/asset_publisher/jekt/content/CVE-2025-43743ghsaWEB
News mentions
0No linked articles in our index yet.