-
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: Fix permissions for space notes node - EXO-68358
Prior to this change , note images was not accessible for space members , this issue was due to the incorrect permissions set on the space notes node during the creation process , This change is going to update the notes node permission
- Loading branch information
Showing
4 changed files
with
298 additions
and
0 deletions.
There are no files selected for viewing
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
133 changes: 133 additions & 0 deletions
133
...-wiki/src/main/java/org/exoplatform/wiki/upgrade/NotesFolderPermissionsUpgradePlugin.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,133 @@ | ||
package org.exoplatform.wiki.upgrade; | ||
|
||
import java.text.SimpleDateFormat; | ||
import java.util.Date; | ||
|
||
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.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.jcr.impl.core.query.QueryImpl; | ||
import org.exoplatform.services.log.ExoLogger; | ||
import org.exoplatform.services.log.Log; | ||
|
||
public class NotesFolderPermissionsUpgradePlugin extends UpgradeProductPlugin { | ||
|
||
private static final Log LOG = ExoLogger.getLogger(NotesFolderPermissionsUpgradePlugin.class); | ||
|
||
private final RepositoryService repositoryService; | ||
|
||
private final SessionProviderService sessionProviderService; | ||
|
||
private int notesCount; | ||
|
||
public NotesFolderPermissionsUpgradePlugin(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 space notes node 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 nt:folder WHERE jcr:path LIKE '/Groups/spaces/%/notes'"; | ||
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 notesNode = nodeIterator.nextNode(); | ||
updateNotesNodePermissions(notesNode); | ||
} | ||
if (nodeIterator.getSize() < limit) { | ||
// no more elements | ||
hasMoreElements = false; | ||
} else { | ||
offset += limit; | ||
} | ||
} | ||
} | ||
LOG.info("End updating of '{}' space notes node permissions. It took {} ms.", | ||
notesCount, | ||
(System.currentTimeMillis() - startupTime)); | ||
|
||
} catch (Exception e) { | ||
if (LOG.isErrorEnabled()) { | ||
LOG.error("An unexpected error occurs when updating notes jcr node permissions:", e); | ||
} | ||
} finally { | ||
if (sessionProvider != null) { | ||
sessionProvider.close(); | ||
} | ||
} | ||
} | ||
|
||
private void updateNotesNodePermissions(Node node) { | ||
try { | ||
String nodePath = node.getPath(); | ||
String groupId = nodePath.substring(nodePath.indexOf("/spaces/"), nodePath.indexOf("/notes")); | ||
if (node.canAddMixin("exo:privilegeable")) { | ||
node.addMixin("exo:privilegeable"); | ||
} | ||
// check if the permission is equal to the group id without the *: | ||
boolean isWrongPermission = ((ExtendedNode) node).getACL() | ||
.getPermissionEntries() | ||
.stream() | ||
.anyMatch(accessControlEntry -> accessControlEntry.getIdentity() | ||
.equals(groupId)); | ||
if (isWrongPermission) { | ||
// remove the wrong permission | ||
((ExtendedNode) node).removePermission(groupId); | ||
// add the correct space permission | ||
((ExtendedNode) node).setPermission("*:" | ||
+ groupId, new String[] { PermissionType.READ, PermissionType.ADD_NODE, PermissionType.SET_PROPERTY }); | ||
node.save(); | ||
this.notesCount += 1; | ||
NodeIterator nodeIterator = node.getNodes(); | ||
if (nodeIterator.hasNext()) { | ||
updateNotesNodePermissions(nodeIterator.nextNode()); | ||
} | ||
} | ||
} catch (RepositoryException e) { | ||
if (LOG.isErrorEnabled()) { | ||
LOG.error("An unexpected error occurs when updating notes jcr node permissions:", e); | ||
} | ||
} | ||
} | ||
} |
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
126 changes: 126 additions & 0 deletions
126
...i/src/test/java/org/exoplatform/wiki/upgrade/NotesFolderPermissionsUpgradePluginTest.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,126 @@ | ||
package org.exoplatform.wiki.upgrade; | ||
|
||
import static org.exoplatform.services.jcr.impl.Constants.EXO_PRIVILEGEABLE; | ||
import static org.mockito.ArgumentMatchers.any; | ||
import static org.mockito.ArgumentMatchers.anyString; | ||
import static org.mockito.Mockito.*; | ||
|
||
import java.util.List; | ||
|
||
import javax.jcr.NodeIterator; | ||
import javax.jcr.Session; | ||
import javax.jcr.Workspace; | ||
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.AccessControlEntry; | ||
import org.exoplatform.services.jcr.access.AccessControlList; | ||
import org.exoplatform.services.jcr.access.PermissionType; | ||
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 NotesFolderPermissionsUpgradePluginTest { | ||
|
||
@Mock | ||
RepositoryService repositoryService; | ||
|
||
@Mock | ||
ManageableRepository repository; | ||
|
||
@Mock | ||
RepositoryEntry repositoryEntry; | ||
|
||
@Mock | ||
Session session; | ||
|
||
@Mock | ||
SessionProviderService sessionProviderService; | ||
|
||
@Mock | ||
SessionProvider sessionProvider; | ||
|
||
@Test | ||
public void NotesFolderPermissionsUpgradePluginTest() 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); | ||
ExtendedNode notesNode = mock(ExtendedNode.class); | ||
when(notesNode.getPath()).thenReturn("Group/spaces/test/notes"); | ||
when(nodeIterator.nextNode()).thenReturn(notesNode); | ||
AccessControlList accessControlList = mock(AccessControlList.class); | ||
when(notesNode.getACL()).thenReturn(accessControlList); | ||
AccessControlEntry accessControlEntry = new AccessControlEntry("/spaces/test", "read"); | ||
when(accessControlList.getPermissionEntries()).thenReturn(List.of(accessControlEntry)); | ||
NodeIterator imagesNodeIterator = mock(NodeIterator.class); | ||
when(notesNode.getNodes()).thenReturn(imagesNodeIterator); | ||
when(imagesNodeIterator.hasNext()).thenReturn(true, false); | ||
ExtendedNode imagesNode = mock(ExtendedNode.class); | ||
when(imagesNodeIterator.nextNode()).thenReturn(imagesNode); | ||
when(imagesNode.getPath()).thenReturn("Group/spaces/test/notes/images"); | ||
when(imagesNode.getNodes()).thenReturn(imagesNodeIterator); | ||
when(imagesNode.getACL()).thenReturn(accessControlList); | ||
|
||
// when | ||
NotesFolderPermissionsUpgradePlugin notesFolderPermissionsUpgradePlugin = | ||
new NotesFolderPermissionsUpgradePlugin(initParams, | ||
repositoryService, | ||
sessionProviderService); | ||
notesFolderPermissionsUpgradePlugin.processUpgrade(null, null); | ||
// then | ||
verify(notesNode, times(1)).removePermission("/spaces/test"); | ||
verify(notesNode, | ||
times(1)).setPermission("*:/spaces/test", | ||
new String[] { PermissionType.READ, PermissionType.ADD_NODE, PermissionType.SET_PROPERTY }); | ||
verify(notesNode, times(1)).save(); | ||
|
||
verify(imagesNode, times(1)).removePermission("/spaces/test"); | ||
verify(imagesNode, | ||
times(1)).setPermission("*:/spaces/test", | ||
new String[] { PermissionType.READ, PermissionType.ADD_NODE, PermissionType.SET_PROPERTY }); | ||
verify(imagesNode, times(1)).save(); | ||
// | ||
accessControlEntry = new AccessControlEntry("*:/spaces/test", "read"); | ||
when(accessControlList.getPermissionEntries()).thenReturn(List.of(accessControlEntry)); | ||
when(nodeIterator.hasNext()).thenReturn(true, false); | ||
notesFolderPermissionsUpgradePlugin.processUpgrade(null, null); | ||
// then | ||
// no invocation with the correct permission | ||
verify(notesNode, | ||
atLeast(0)).setPermission("*:/spaces/test", | ||
new String[] { PermissionType.READ, PermissionType.ADD_NODE, PermissionType.SET_PROPERTY }); | ||
verify(notesNode, atLeast(0)).save(); | ||
|
||
|
||
} | ||
} |