-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix : old published news images not displayed for non members - EXO-6…
…4578 This change will update the permissions for displaying published news images to non-members.
- Loading branch information
Showing
3 changed files
with
291 additions
and
0 deletions.
There are no files selected for viewing
162 changes: 162 additions & 0 deletions
162
...in/java/org/exoplatform/news/upgrade/jcr/PublishedNewsImagesPermissionsUpgradePlugin.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,162 @@ | ||
/* | ||
* Copyright (C) 2023 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 Affero 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 <http://www.gnu.org/licenses/>. | ||
*/ | ||
package org.exoplatform.news.upgrade.jcr; | ||
|
||
import java.util.regex.Matcher; | ||
import java.util.regex.Pattern; | ||
|
||
import javax.jcr.Node; | ||
import javax.jcr.NodeIterator; | ||
import javax.jcr.RepositoryException; | ||
import javax.jcr.Session; | ||
import javax.jcr.query.Query; | ||
import javax.jcr.query.QueryManager; | ||
|
||
import org.exoplatform.commons.upgrade.UpgradePluginExecutionContext; | ||
import org.exoplatform.commons.upgrade.UpgradeProductPlugin; | ||
import org.exoplatform.container.xml.InitParams; | ||
import org.exoplatform.services.jcr.RepositoryService; | ||
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.jcr.impl.core.query.QueryImpl; | ||
import org.exoplatform.services.log.ExoLogger; | ||
import org.exoplatform.services.log.Log; | ||
|
||
public class PublishedNewsImagesPermissionsUpgradePlugin extends UpgradeProductPlugin { | ||
public static final String EXO_PRIVILEGEABLE = "exo:privilegeable"; | ||
|
||
public static final String[] READ_PERMISSIONS = new String[] { "read" }; | ||
|
||
public static final String PLATFORM_USERS_GROUP_IDENTITY = "*:/platform/users"; | ||
|
||
private static final Log LOG = | ||
ExoLogger.getLogger(PublishedNewsImagesPermissionsUpgradePlugin.class.getName()); | ||
|
||
private static final Pattern IMAGE_SRC_PATTERN = Pattern.compile("src=\"/portal/rest/images/?(.+)?\""); | ||
|
||
private final RepositoryService repositoryService; | ||
|
||
private final SessionProviderService sessionProviderService; | ||
|
||
private int imageNewsUpdatedCount; | ||
|
||
private int newsCount; | ||
|
||
public PublishedNewsImagesPermissionsUpgradePlugin(InitParams initParams, | ||
RepositoryService repositoryService, | ||
SessionProviderService sessionProviderService) { | ||
super(initParams); | ||
this.repositoryService = repositoryService; | ||
this.sessionProviderService = sessionProviderService; | ||
} | ||
|
||
@Override | ||
public boolean shouldProceedToUpgrade(String newVersion, | ||
String previousGroupVersion, | ||
UpgradePluginExecutionContext previousUpgradePluginExecution) { | ||
int executionCount = previousUpgradePluginExecution == null ? 0 : previousUpgradePluginExecution.getExecutionCount(); | ||
return !isExecuteOnlyOnce() || executionCount == 0; | ||
} | ||
|
||
@Override | ||
public void processUpgrade(String s, String s1) { | ||
long startupTime = System.currentTimeMillis(); | ||
LOG.info("Start upgrade of published news images permission"); | ||
SessionProvider sessionProvider = null; | ||
try { | ||
sessionProvider = sessionProviderService.getSystemSessionProvider(null); | ||
Session session = sessionProvider.getSession( | ||
repositoryService.getCurrentRepository() | ||
.getConfiguration() | ||
.getDefaultWorkspaceName(), | ||
repositoryService.getCurrentRepository()); | ||
QueryManager qm = session.getWorkspace().getQueryManager(); | ||
int limit = 10, offset = 0; | ||
String stringQuery = | ||
"select * from exo:news WHERE publication:currentState = 'published' AND jcr:path LIKE '/Groups/spaces/%'"; | ||
Query jcrQuery = qm.createQuery(stringQuery, Query.SQL); | ||
boolean hasMoreElements = true; | ||
while (hasMoreElements) { | ||
((QueryImpl) jcrQuery).setOffset(offset); | ||
((QueryImpl) jcrQuery).setLimit(limit); | ||
NodeIterator nodeIterator = jcrQuery.execute().getNodes(); | ||
if (nodeIterator != null) { | ||
while (nodeIterator.hasNext()) { | ||
Node newsNode = nodeIterator.nextNode(); | ||
updateNewsImagesPermissions(newsNode, session); | ||
} | ||
if (nodeIterator.getSize() < limit) { | ||
// no more elements | ||
hasMoreElements = false; | ||
} else { | ||
offset += limit; | ||
} | ||
} | ||
} | ||
LOG.info("End updating of '{}' images for '{}' published news . It took {} ms.", | ||
this.imageNewsUpdatedCount, | ||
this.newsCount, | ||
(System.currentTimeMillis() - startupTime)); | ||
} catch (Exception e) { | ||
LOG.error("An error occurred when upgrading published images news permissions :", e); | ||
} finally { | ||
if (sessionProvider != null) { | ||
sessionProvider.close(); | ||
} | ||
} | ||
} | ||
|
||
private void updateNewsImagesPermissions(Node newsNode, Session session) throws RepositoryException { | ||
Matcher matcher = IMAGE_SRC_PATTERN.matcher(getStringProperty(newsNode, "exo:body")); | ||
int imagesCount = 0; | ||
while (matcher.find()) { | ||
String match = matcher.group(1); | ||
String imageUUID = match.substring(match.lastIndexOf("/") + 1); | ||
ExtendedNode image = (ExtendedNode) session.getNodeByUUID(imageUUID); | ||
if (image != null) { | ||
if (image.canAddMixin(EXO_PRIVILEGEABLE)) { | ||
image.addMixin(EXO_PRIVILEGEABLE); | ||
} | ||
boolean isPublicImage = image.getACL() | ||
.getPermissionEntries() | ||
.stream() | ||
.filter(accessControlEntry -> accessControlEntry.getIdentity() | ||
.equals(PLATFORM_USERS_GROUP_IDENTITY)) | ||
.toList() | ||
.size() > 0; | ||
if (!isPublicImage) { | ||
// make news images public | ||
image.setPermission(PLATFORM_USERS_GROUP_IDENTITY, READ_PERMISSIONS); | ||
image.save(); | ||
imagesCount += 1; | ||
} | ||
} | ||
} | ||
if (imagesCount > 0) { | ||
this.newsCount += 1; | ||
this.imageNewsUpdatedCount += imagesCount; | ||
} | ||
} | ||
|
||
private String getStringProperty(Node node, String propertyName) throws RepositoryException { | ||
if (node.hasProperty(propertyName)) { | ||
return node.getProperty(propertyName).getString(); | ||
} | ||
return ""; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
95 changes: 95 additions & 0 deletions
95
...ava/org/exoplatform/news/upgrade/jcr/PublishedNewsImagesPermissionsUpgradePluginTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
package org.exoplatform.news.upgrade.jcr; | ||
|
||
import static org.exoplatform.news.upgrade.jcr.PublishedNewsImagesPermissionsUpgradePlugin.EXO_PRIVILEGEABLE; | ||
import static org.mockito.ArgumentMatchers.anyString; | ||
import static org.mockito.Mockito.*; | ||
|
||
import java.util.ArrayList; | ||
|
||
import javax.jcr.*; | ||
import javax.jcr.query.Query; | ||
import javax.jcr.query.QueryManager; | ||
import javax.jcr.query.QueryResult; | ||
|
||
import org.junit.Test; | ||
import org.junit.runner.RunWith; | ||
import org.mockito.Mock; | ||
import org.mockito.junit.MockitoJUnitRunner; | ||
|
||
import org.exoplatform.container.xml.InitParams; | ||
import org.exoplatform.container.xml.ValueParam; | ||
import org.exoplatform.services.jcr.RepositoryService; | ||
import org.exoplatform.services.jcr.access.AccessControlList; | ||
import org.exoplatform.services.jcr.config.RepositoryEntry; | ||
import org.exoplatform.services.jcr.core.ExtendedNode; | ||
import org.exoplatform.services.jcr.core.ManageableRepository; | ||
import org.exoplatform.services.jcr.ext.app.SessionProviderService; | ||
import org.exoplatform.services.jcr.ext.common.SessionProvider; | ||
import org.exoplatform.services.jcr.impl.core.query.QueryImpl; | ||
|
||
@RunWith(MockitoJUnitRunner.class) | ||
public class PublishedNewsImagesPermissionsUpgradePluginTest { | ||
|
||
@Mock | ||
RepositoryService repositoryService; | ||
|
||
@Mock | ||
ManageableRepository repository; | ||
|
||
@Mock | ||
RepositoryEntry repositoryEntry; | ||
|
||
@Mock | ||
Session session; | ||
|
||
@Mock | ||
SessionProviderService sessionProviderService; | ||
|
||
@Mock | ||
SessionProvider sessionProvider; | ||
|
||
@Test | ||
public void publishedNewsImagesPermissionsUpgradePluginTest() throws Exception { | ||
InitParams initParams = new InitParams(); | ||
ValueParam valueParam = new ValueParam(); | ||
valueParam.setName("product.group.id"); | ||
valueParam.setValue("org.exoplatform.news"); | ||
|
||
when(sessionProviderService.getSystemSessionProvider(any())).thenReturn(sessionProvider); | ||
when(repositoryService.getCurrentRepository()).thenReturn(repository); | ||
when(repository.getConfiguration()).thenReturn(repositoryEntry); | ||
when(sessionProvider.getSession(any(), any())).thenReturn(session); | ||
QueryManager qm = mock(QueryManager.class); | ||
Workspace workSpace = mock(Workspace.class); | ||
when(session.getWorkspace()).thenReturn(workSpace); | ||
when(workSpace.getQueryManager()).thenReturn(qm); | ||
Query query = mock(QueryImpl.class); | ||
when(qm.createQuery(anyString(), anyString())).thenReturn(query); | ||
QueryResult queryResult = mock(QueryResult.class); | ||
when(query.execute()).thenReturn(queryResult); | ||
NodeIterator nodeIterator = mock(NodeIterator.class); | ||
when(queryResult.getNodes()).thenReturn(nodeIterator); | ||
when(nodeIterator.hasNext()).thenReturn(true, false); | ||
Node newsNode = mock(Node.class); | ||
Property property = mock(Property.class); | ||
when(nodeIterator.nextNode()).thenReturn(newsNode); | ||
when(newsNode.hasProperty("exo:body")).thenReturn(true); | ||
when(newsNode.getProperty("exo:body")).thenReturn(property); | ||
when(property.getString()).thenReturn("news body with image src=\"/portal/rest/images/repository/collaboration/123\""); | ||
ExtendedNode imageNode = mock(ExtendedNode.class); | ||
when(session.getNodeByUUID("123")).thenReturn(imageNode); | ||
when(imageNode.canAddMixin(EXO_PRIVILEGEABLE)).thenReturn(true); | ||
AccessControlList accessControlList = mock(AccessControlList.class); | ||
when(imageNode.getACL()).thenReturn(accessControlList); | ||
when(accessControlList.getPermissionEntries()).thenReturn(new ArrayList<>()); | ||
// when | ||
PublishedNewsImagesPermissionsUpgradePlugin publishedNewsImagesPermissionsUpgradePlugin = | ||
new PublishedNewsImagesPermissionsUpgradePlugin(initParams, | ||
repositoryService, | ||
sessionProviderService); | ||
publishedNewsImagesPermissionsUpgradePlugin.processUpgrade(null, null); | ||
// then | ||
verify(imageNode, times(1)).setPermission("*:/platform/users", new String[] { "read" }); | ||
verify(imageNode, times(1)).save(); | ||
} | ||
} |