This is an automated email from the ASF dual-hosted git repository.
enapps-enorman pushed a commit to branch master
in repository
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-jcr-mock.git
The following commit(s) were added to refs/heads/master by this push:
new f576fb0 SLING-13177 MockGroup declaredMembers state is lost for new
session (#43)
f576fb0 is described below
commit f576fb07e8bb7f374aab7ddcf3d79f2d15329f00
Author: Eric Norman <[email protected]>
AuthorDate: Thu Apr 23 10:48:18 2026 -0700
SLING-13177 MockGroup declaredMembers state is lost for new session (#43)
---
.../apache/sling/testing/mock/jcr/MockGroup.java | 74 ++++++++++++++++------
.../sling/testing/mock/jcr/MockGroupTest.java | 10 +++
2 files changed, 63 insertions(+), 21 deletions(-)
diff --git a/src/main/java/org/apache/sling/testing/mock/jcr/MockGroup.java
b/src/main/java/org/apache/sling/testing/mock/jcr/MockGroup.java
index f7d51c7..c3e71e8 100644
--- a/src/main/java/org/apache/sling/testing/mock/jcr/MockGroup.java
+++ b/src/main/java/org/apache/sling/testing/mock/jcr/MockGroup.java
@@ -20,16 +20,19 @@ package org.apache.sling.testing.mock.jcr;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
+import javax.jcr.Value;
import java.security.Principal;
-import java.util.HashMap;
+import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
-import java.util.Map;
+import java.util.LinkedHashSet;
+import java.util.List;
import java.util.Set;
import org.apache.jackrabbit.api.security.user.Authorizable;
import org.apache.jackrabbit.api.security.user.Group;
+import org.apache.jackrabbit.oak.spi.security.user.UserConstants;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -37,7 +40,6 @@ import org.jetbrains.annotations.Nullable;
* Mock {@link Group} implementation.
*/
class MockGroup extends MockAuthorizable implements Group {
- private Map<String, Authorizable> declaredMembers = new HashMap<>();
public MockGroup(
@Nullable String id,
@@ -47,9 +49,29 @@ class MockGroup extends MockAuthorizable implements Group {
super(id, principal, homeNode, mockUserMgr);
}
+ /**
+ * Convert the declared members property value to a set of ids
+ * @return set of declared member ids (if any)
+ */
+ protected @NotNull Set<String> getDeclaredMembersIds() throws
RepositoryException {
+ Set<String> memberIds = new LinkedHashSet<>();
+ if (homeNode.hasProperty(UserConstants.REP_MEMBERS)) {
+ for (Value value :
homeNode.getProperty(UserConstants.REP_MEMBERS).getValues()) {
+ final String id = value.getString();
+ memberIds.add(id);
+ }
+ }
+ return memberIds;
+ }
+
@Override
public @NotNull Iterator<Authorizable> getDeclaredMembers() throws
RepositoryException {
- return declaredMembers.values().iterator();
+ List<Authorizable> declaredMembers = new ArrayList<>();
+ for (String id : getDeclaredMembersIds()) {
+ final @Nullable Authorizable authorizable =
mockUserMgr.getAuthorizable(id);
+ declaredMembers.add(authorizable);
+ }
+ return declaredMembers.iterator();
}
@Override
@@ -88,16 +110,21 @@ class MockGroup extends MockAuthorizable implements Group {
@Override
public boolean isDeclaredMember(@NotNull Authorizable authorizable) throws
RepositoryException {
- return declaredMembers.containsValue(authorizable);
+ final Set<String> declaredMembersIds = getDeclaredMembersIds();
+ final @NotNull String authorizableId = authorizable.getID();
+ return declaredMembersIds.contains(authorizableId);
}
@Override
public boolean isMember(@NotNull Authorizable authorizable) throws
RepositoryException {
- boolean value = declaredMembers.containsValue(authorizable);
+ final @NotNull String authorizableId = authorizable.getID();
+ final Set<String> declaredMembersIds = getDeclaredMembersIds();
+ boolean value = declaredMembersIds.contains(authorizableId);
if (!value) {
// groups
- for (Authorizable m : declaredMembers.values()) {
- if (m.isGroup()) {
+ for (String id : declaredMembersIds) {
+ final @Nullable Authorizable m =
mockUserMgr.getAuthorizable(id);
+ if (m != null && m.isGroup()) {
value = ((Group) m).isDeclaredMember(authorizable);
}
if (value) {
@@ -110,42 +137,47 @@ class MockGroup extends MockAuthorizable implements Group
{
@Override
public boolean addMember(@NotNull Authorizable authorizable) throws
RepositoryException {
- boolean added = false;
- if (!isMember(authorizable)) {
- declaredMembers.put(authorizable.getID(), authorizable);
- added = true;
- }
+ final Set<String> declaredMembersIds = getDeclaredMembersIds();
+ final @NotNull String authorizableId = authorizable.getID();
+ boolean added = declaredMembersIds.add(authorizableId);
+ homeNode.setProperty(UserConstants.REP_MEMBERS,
declaredMembersIds.toArray(String[]::new));
return added;
}
@Override
public @NotNull Set<String> addMembers(@NotNull String... memberIds)
throws RepositoryException {
Set<String> added = new HashSet<>();
+ final Set<String> declaredMembersIds = getDeclaredMembersIds();
for (String id : memberIds) {
- if (!declaredMembers.containsKey(id)) {
- @Nullable Authorizable authorizable =
mockUserMgr.getAuthorizable(id);
- if (authorizable != null) {
- addMember(authorizable);
- added.add(id);
- }
+ final @Nullable Authorizable m = mockUserMgr.getAuthorizable(id);
+ if (m != null && declaredMembersIds.add(id)) {
+ added.add(id);
}
}
+ homeNode.setProperty(UserConstants.REP_MEMBERS,
declaredMembersIds.toArray(String[]::new));
return added;
}
@Override
public boolean removeMember(@NotNull Authorizable authorizable) throws
RepositoryException {
- return declaredMembers.remove(authorizable.getID(), authorizable);
+ final Set<String> declaredMembersIds = getDeclaredMembersIds();
+ final @NotNull String authorizableId = authorizable.getID();
+ boolean removed = declaredMembersIds.remove(authorizableId);
+ homeNode.setProperty(UserConstants.REP_MEMBERS,
declaredMembersIds.toArray(String[]::new));
+ return removed;
}
@Override
public @NotNull Set<String> removeMembers(@NotNull String... memberIds)
throws RepositoryException {
Set<String> removed = new HashSet<>();
+ final Set<String> declaredMembersIds = getDeclaredMembersIds();
for (String id : memberIds) {
- if (declaredMembers.remove(id) != null) {
+ if (declaredMembersIds.remove(id)) {
removed.add(id);
}
}
+ homeNode.setProperty(UserConstants.REP_MEMBERS,
declaredMembersIds.toArray(String[]::new));
+
return removed;
}
diff --git a/src/test/java/org/apache/sling/testing/mock/jcr/MockGroupTest.java
b/src/test/java/org/apache/sling/testing/mock/jcr/MockGroupTest.java
index b7af412..30d7be8 100644
--- a/src/test/java/org/apache/sling/testing/mock/jcr/MockGroupTest.java
+++ b/src/test/java/org/apache/sling/testing/mock/jcr/MockGroupTest.java
@@ -166,6 +166,16 @@ public class MockGroupTest extends
MockAuthorizableTest<Group> {
authorizable.addMember(member1);
assertTrue(authorizable.isMember(member2));
+
+ // member of subgroup
+ @NotNull Group member4 = userManager.createGroup("member4");
+ assertFalse(authorizable.isMember(member4));
+ member1.addMember(member4);
+ assertTrue(authorizable.isMember(member4));
+
+ // memberOf contains item that resolves to null authorizable
+ member1.remove();
+ assertFalse(authorizable.isMember(member4));
}
/**