diff --git a/data-upgrade-recordings-permissions/pom.xml b/data-upgrade-recordings-permissions/pom.xml
new file mode 100644
index 00000000..d5f8d55c
--- /dev/null
+++ b/data-upgrade-recordings-permissions/pom.xml
@@ -0,0 +1,43 @@
+
+
+
+ 4.0.0
+
+ org.exoplatform.addons.upgrade
+ upgrade
+ 7.0.x-SNAPSHOT
+
+
+ data-upgrade-recordings-permissions
+ jar
+ eXo Add-on:: Data Upgrade Add-on - Recordings permissions
+
+
+
+ io.meeds.commons
+ commons-component-upgrade
+ provided
+
+
+ org.exoplatform.jcr
+ exo.jcr.component.core
+ provided
+
+
+ org.exoplatform.jcr
+ exo.jcr.component.ext
+ provided
+
+
+
diff --git a/data-upgrade-recordings-permissions/src/main/java/org/exoplatform/jcr/upgrade/RecordingsPermissionsUpgradePlugin.java b/data-upgrade-recordings-permissions/src/main/java/org/exoplatform/jcr/upgrade/RecordingsPermissionsUpgradePlugin.java
new file mode 100644
index 00000000..03c99f92
--- /dev/null
+++ b/data-upgrade-recordings-permissions/src/main/java/org/exoplatform/jcr/upgrade/RecordingsPermissionsUpgradePlugin.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2003-2024 eXo Platform SAS
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+package org.exoplatform.jcr.upgrade;
+
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.Session;
+import javax.jcr.query.Query;
+import javax.jcr.query.QueryResult;
+
+import org.exoplatform.commons.upgrade.UpgradeProductPlugin;
+import org.exoplatform.container.PortalContainer;
+import org.exoplatform.container.component.RequestLifeCycle;
+import org.exoplatform.container.xml.InitParams;
+import org.exoplatform.services.jcr.RepositoryService;
+import org.exoplatform.services.jcr.access.PermissionType;
+import org.exoplatform.services.jcr.core.ExtendedNode;
+import org.exoplatform.services.jcr.ext.app.SessionProviderService;
+import org.exoplatform.services.jcr.ext.common.SessionProvider;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
+import org.exoplatform.services.organization.OrganizationService;
+import org.exoplatform.services.organization.User;
+
+/**
+ * plugin will be executed in order to update recordings existing in users drive by adding delete permission
+ */
+public class RecordingsPermissionsUpgradePlugin extends UpgradeProductPlugin {
+
+ private static final Log log = ExoLogger.getLogger(RecordingsPermissionsUpgradePlugin.class.getName());
+
+ private OrganizationService organizationService;
+
+ private RepositoryService repositoryService;
+
+ private SessionProviderService sessionProviderService;
+
+ public RecordingsPermissionsUpgradePlugin(InitParams initParams,
+ OrganizationService organizationService,
+ RepositoryService repositoryService,
+ SessionProviderService sessionProviderService) {
+ super(initParams);
+ this.organizationService = organizationService;
+ this.repositoryService = repositoryService;
+ this.sessionProviderService = sessionProviderService;
+ }
+
+ @Override
+ public void processUpgrade(String oldVersion, String newVersion) {
+ long startupTime = System.currentTimeMillis();
+ int updatedRecordingsCount = 0;
+ long totalRecordingsCount = 0;
+ int totalBadPermissionRecordingsCount = 0;
+ log.info("Start upgrade : Updating recordings permissions");
+
+ SessionProvider sessionProvider = null;
+ RequestLifeCycle.begin(PortalContainer.getInstance());
+ try {
+ sessionProvider = sessionProviderService.getSystemSessionProvider(null);
+ Session session = sessionProvider.getSession(
+ repositoryService.getCurrentRepository()
+ .getConfiguration()
+ .getDefaultWorkspaceName(),
+ repositoryService.getCurrentRepository());
+ Node users = (Node) session.getItem("/Users");
+ String statement =
+ "SELECT * FROM nt:base WHERE jcr:path LIKE '%/Private/recordings/%' AND (jcr:primaryType='exo:symlink' OR jcr:primaryType='nt:file')";
+ Query jcrQuery = users.getSession().getWorkspace().getQueryManager().createQuery(statement, Query.SQL);
+ QueryResult queryResult = jcrQuery.execute();
+ NodeIterator nodeIterator = queryResult.getNodes();
+ totalRecordingsCount = nodeIterator.getSize();
+ log.info("Total number of recordings: {}", totalRecordingsCount);
+ while (nodeIterator.hasNext()) {
+ Node node = nodeIterator.nextNode();
+ String nodePath = node.getPath();
+ String[] pathParts = nodePath.substring(0, nodePath.indexOf("/Private")).split("/");
+ String userName = pathParts[pathParts.length - 1];
+ User user = organizationService.getUserHandler().findUserByName(userName);
+ if (user != null) {
+ boolean haveDeletePermission = ((ExtendedNode) node).getACL()
+ .getPermissionEntries()
+ .stream()
+ .anyMatch(accessControlEntry -> accessControlEntry.getIdentity()
+ .equals(userName)
+ && accessControlEntry.getPermission().equals("remove"));
+ if (!haveDeletePermission) {
+ totalBadPermissionRecordingsCount += 1;
+ try {
+ if (node.canAddMixin("exo:privilegeable")) {
+ node.addMixin("exo:privilegeable");
+ }
+ ((ExtendedNode) node).setPermission(userName,
+ new String[]{PermissionType.READ, PermissionType.ADD_NODE,
+ PermissionType.SET_PROPERTY, PermissionType.REMOVE});
+ node.save();
+ updatedRecordingsCount += 1;
+ log.info("{} Recording permissions" +
+ " updated.",
+ updatedRecordingsCount);
+ } catch (Exception e) {
+ if (log.isErrorEnabled()) {
+ log.error("An unexpected error occurs when updating recording {} permissions:", node.getPath(), e);
+ }
+ }
+ }
+ }
+ }
+ log.info("End updating permissions of {}/{} recordings with bad permissions, total number of checked records = {}. It took {} ms",
+ updatedRecordingsCount,
+ totalBadPermissionRecordingsCount,
+ totalRecordingsCount,
+ (System.currentTimeMillis() - startupTime));
+ } catch (Exception e) {
+ if (log.isErrorEnabled()) {
+ log.error("An unexpected error occurs when updating recordings permissions:", e);
+ }
+ } finally {
+ if (sessionProvider != null) {
+ sessionProvider.close();
+ }
+ RequestLifeCycle.end();
+ }
+ }
+
+}
diff --git a/data-upgrade-recordings-permissions/src/main/resources/conf/portal/configuration.xml b/data-upgrade-recordings-permissions/src/main/resources/conf/portal/configuration.xml
new file mode 100644
index 00000000..35950288
--- /dev/null
+++ b/data-upgrade-recordings-permissions/src/main/resources/conf/portal/configuration.xml
@@ -0,0 +1,60 @@
+
+
+
+
+
+ org.exoplatform.commons.upgrade.UpgradeProductService
+
+ RecordingsPermissionsUpgradePlugin
+ addUpgradePlugin
+ org.exoplatform.jcr.upgrade.RecordingsPermissionsUpgradePlugin
+ upgrade personal recordings to add delete permissions
+
+
+ product.group.id
+ The groupId of the product
+ org.exoplatform.platform
+
+
+ plugin.upgrade.target.version
+ The plugin target version of selected groupId
+ 7.0.0
+
+
+ plugin.execution.order
+ The plugin execution order
+ 10
+
+
+ plugin.upgrade.execute.once
+ The plugin must be executed only once
+ true
+
+
+ plugin.upgrade.async.execution
+ The plugin will be executed in an asynchronous mode
+ true
+
+
+
+
+
diff --git a/pom.xml b/pom.xml
index 2c5b98ca..49b49804 100644
--- a/pom.xml
+++ b/pom.xml
@@ -29,6 +29,7 @@
data-upgrade-notifications
data-upgrade-processes-permissions
data-upgrade-move-folders
+ data-upgrade-recordings-permissions
data-upgrade-packaging