SLING-9814 Add canDisable and canChangePassword methods to
AuthorizablePrivilegesInfo
diff --git a/pom.xml b/pom.xml
index 828c719..d12d347 100644
--- a/pom.xml
+++ b/pom.xml
@@ -128,8 +128,8 @@
</dependency>
<dependency>
<groupId>org.apache.jackrabbit</groupId>
- <artifactId>jackrabbit-api</artifactId>
- <version>2.3.0</version>
+ <artifactId>oak-jackrabbit-api</artifactId>
+ <version>1.18.0</version>
<scope>provided</scope>
</dependency>
<dependency>
diff --git a/src/main/java/org/apache/sling/jackrabbit/usermanager/AuthorizablePrivilegesInfo.java b/src/main/java/org/apache/sling/jackrabbit/usermanager/AuthorizablePrivilegesInfo.java
index af86136..b3db3f9 100644
--- a/src/main/java/org/apache/sling/jackrabbit/usermanager/AuthorizablePrivilegesInfo.java
+++ b/src/main/java/org/apache/sling/jackrabbit/usermanager/AuthorizablePrivilegesInfo.java
@@ -96,4 +96,30 @@
boolean canUpdateGroupMembers(Session jcrSession,
String groupId);
+ /**
+ * Checks whether the current user has been granted privileges
+ * to disable the specified user.
+ *
+ * @param jcrSession the JCR session of the current user
+ * @param userId the user id to check
+ * @return true if the current user has the privileges, false otherwise
+ */
+ default boolean canDisable(Session jcrSession,
+ String userId) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Checks whether the current user has been granted privileges
+ * to change the password of the specified user.
+ *
+ * @param jcrSession the JCR session of the current user
+ * @param userId the user id to check
+ * @return true if the current user has the privileges, false otherwise
+ */
+ default boolean canChangePassword(Session jcrSession,
+ String userId) {
+ throw new UnsupportedOperationException();
+ }
+
}
\ No newline at end of file
diff --git a/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/AuthorizablePrivilegesInfoImpl.java b/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/AuthorizablePrivilegesInfoImpl.java
index e7da94c..e91c31e 100644
--- a/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/AuthorizablePrivilegesInfoImpl.java
+++ b/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/AuthorizablePrivilegesInfoImpl.java
@@ -36,6 +36,7 @@
import org.apache.jackrabbit.oak.spi.security.user.UserConstants;
import org.apache.sling.commons.osgi.OsgiUtil;
import org.apache.sling.jackrabbit.usermanager.AuthorizablePrivilegesInfo;
+import org.apache.sling.jackrabbit.usermanager.ChangeUserPassword;
import org.apache.sling.jackrabbit.usermanager.CreateUser;
import org.apache.sling.jcr.base.util.AccessControlUtil;
import org.osgi.framework.BundleContext;
@@ -98,6 +99,16 @@
private String usersPath;
private String groupsPath;
private boolean selfRegistrationEnabled;
+ private boolean alwaysAllowSelfChangePassword = false;
+
+ @Reference(cardinality=ReferenceCardinality.OPTIONAL, policy = ReferencePolicy.DYNAMIC)
+ private void bindChangeUserPassword(ChangeUserPassword changeUserPassword, Map<String, Object> properties) {
+ alwaysAllowSelfChangePassword = OsgiUtil.toBoolean(properties.get("alwaysAllowSelfChangePassword"), false);
+ }
+ @SuppressWarnings("unused")
+ private void unbindChangeUserPassword(ChangeUserPassword changeUserPassword, Map<String, Object> properties) {
+ alwaysAllowSelfChangePassword = false;
+ }
@Reference(cardinality=ReferenceCardinality.OPTIONAL, policy = ReferencePolicy.DYNAMIC)
private void bindUserConfiguration(UserConfiguration userConfig, Map<String, Object> properties) {
@@ -266,19 +277,12 @@
PropertyUpdateTypes... propertyUpdateTypes) {
boolean hasRights = false;
try {
- if (jcrSession.getUserID().equals(principalId)) {
- //user is allowed to update it's own properties
- hasRights = true;
+ UserManager userManager = AccessControlUtil.getUserManager(jcrSession);
+ Authorizable currentUser = userManager.getAuthorizable(jcrSession.getUserID());
+
+ if (currentUser instanceof User && ((User)currentUser).isAdmin()) {
+ hasRights = true; //admin user has full control
} else {
- UserManager userManager = AccessControlUtil.getUserManager(jcrSession);
- Authorizable currentUser = userManager.getAuthorizable(jcrSession.getUserID());
-
- if (currentUser instanceof User) {
- if (((User)currentUser).isAdmin()) {
- return true; //admin user has full control
- }
- }
-
Authorizable authorizable = userManager.getAuthorizable(principalId);
if (authorizable == null) {
log.debug("Failed to find authorizable: {}", principalId);
@@ -322,10 +326,85 @@
return hasRights;
}
+ /* (non-Javadoc)
+ * @see org.apache.sling.jackrabbit.usermanager.AuthorizablePrivilegesInfo#canDisable(javax.jcr.Session, java.lang.String)
+ */
+ @Override
+ public boolean canDisable(Session jcrSession, String userId) {
+ boolean hasRights = false;
+ try {
+ UserManager userManager = AccessControlUtil.getUserManager(jcrSession);
+ Authorizable currentUser = userManager.getAuthorizable(jcrSession.getUserID());
+
+ if (currentUser instanceof User && ((User)currentUser).isAdmin()) {
+ hasRights = true; //admin user has full control
+ } else {
+ Authorizable authorizable = userManager.getAuthorizable(userId);
+ if (!(authorizable instanceof User)) {
+ log.debug("Failed to find user: {}", userId);
+ } else {
+ String path = authorizable.getPath();
+ if (path != null) {
+ //check if the non-admin user has sufficient rights on the home folder
+ AccessControlManager acm = jcrSession.getAccessControlManager();
+ Set<Privilege> requiredPrivileges = new HashSet<>();
+ requiredPrivileges.add(acm.privilegeFromName(Privilege.JCR_READ));
+ requiredPrivileges.add(acm.privilegeFromName(PrivilegeConstants.REP_USER_MANAGEMENT));
+ hasRights = acm.hasPrivileges(path, requiredPrivileges.toArray(new Privilege[requiredPrivileges.size()]));
+ }
+ }
+ }
+ } catch (RepositoryException e) {
+ log.warn("Failed to determine if {} can disable user {}", jcrSession.getUserID(), userId);
+ }
+ return hasRights;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.sling.jackrabbit.usermanager.AuthorizablePrivilegesInfo#canChangePassword(javax.jcr.Session, java.lang.String)
+ */
+ @Override
+ public boolean canChangePassword(Session jcrSession, String userId) {
+ boolean hasRights = false;
+ try {
+ UserManager userManager = AccessControlUtil.getUserManager(jcrSession);
+ Authorizable currentUser = userManager.getAuthorizable(jcrSession.getUserID());
+
+ Authorizable authorizable = userManager.getAuthorizable(userId);
+ if (!(authorizable instanceof User)) {
+ log.debug("Failed to find user: {}", userId);
+ } else {
+ if (((User)authorizable).isSystemUser() || "anonymous".equals(authorizable.getID())) {
+ hasRights = false; //system users and anonymous have no passwords
+ } else if (currentUser instanceof User && ((User)currentUser).isAdmin()) {
+ hasRights = true; //admin user has full control
+ } else {
+ // otherwise let's check the granted privileges
+ String path = authorizable.getPath();
+ if (path != null) {
+ //check if the non-admin user has sufficient rights on the home folder
+ AccessControlManager acm = jcrSession.getAccessControlManager();
+ Set<Privilege> requiredPrivileges = new HashSet<>();
+ requiredPrivileges.add(acm.privilegeFromName(Privilege.JCR_READ));
+ requiredPrivileges.add(acm.privilegeFromName(PrivilegeConstants.REP_USER_MANAGEMENT));
+ hasRights = acm.hasPrivileges(path, requiredPrivileges.toArray(new Privilege[requiredPrivileges.size()]));
+ }
+
+ if (!hasRights && jcrSession.getUserID().equals(userId)) {
+ // check if the ChangeUserPassword service is configured to always allow
+ // a user to change their own password.
+ hasRights = alwaysAllowSelfChangePassword;
+ }
+ }
+ }
+ } catch (RepositoryException e) {
+ log.warn("Failed to determine if {} can change the password of user {}", jcrSession.getUserID(), userId);
+ }
+ return hasRights;
+ }
// ---------- SCR Integration ----------------------------------------------
-
@Activate
protected void activate(BundleContext bundleContext, Map<String, Object> properties)
throws InvalidKeyException, NoSuchAlgorithmException,
diff --git a/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/AuthorizablePrivilegesInfoIT.java b/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/AuthorizablePrivilegesInfoIT.java
index 939a4d0..fbc2347 100644
--- a/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/AuthorizablePrivilegesInfoIT.java
+++ b/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/AuthorizablePrivilegesInfoIT.java
@@ -45,6 +45,7 @@
import org.apache.jackrabbit.oak.spi.security.user.UserConfiguration;
import org.apache.sling.jackrabbit.usermanager.AuthorizablePrivilegesInfo;
import org.apache.sling.jackrabbit.usermanager.AuthorizablePrivilegesInfo.PropertyUpdateTypes;
+import org.apache.sling.jackrabbit.usermanager.ChangeUserPassword;
import org.apache.sling.jackrabbit.usermanager.CreateGroup;
import org.apache.sling.jackrabbit.usermanager.CreateUser;
import org.apache.sling.jackrabbit.usermanager.DeleteGroup;
@@ -53,6 +54,7 @@
import org.apache.sling.jackrabbit.usermanager.UpdateUser;
import org.apache.sling.jcr.api.SlingRepository;
import org.apache.sling.jcr.base.util.AccessControlUtil;
+import org.apache.sling.jcr.jackrabbit.accessmanager.DeleteAces;
import org.apache.sling.jcr.jackrabbit.accessmanager.ModifyAce;
import org.apache.sling.servlets.post.Modification;
import org.junit.After;
@@ -76,95 +78,101 @@
@RunWith(PaxExam.class)
@ExamReactorStrategy(PerClass.class)
public class AuthorizablePrivilegesInfoIT extends UserManagerTestSupport {
- private static AtomicLong counter = new AtomicLong(0);
+ private static AtomicLong counter = new AtomicLong(0);
private final Logger logger = LoggerFactory.getLogger(getClass());
@Inject
protected BundleContext bundleContext;
-
+
@Inject
protected SlingRepository repository;
- @Inject
- private AuthorizablePrivilegesInfo privilegesInfo;
-
- @Inject
- private UserConfiguration userConfig;
-
- @Inject
- private CreateUser createUser;
+ @Inject
+ private AuthorizablePrivilegesInfo privilegesInfo;
- @Inject
- private CreateGroup createGroup;
+ @Inject
+ private UserConfiguration userConfig;
- @Inject
- private UpdateUser updateUser;
+ @Inject
+ private CreateUser createUser;
- @Inject
- private UpdateGroup updateGroup;
+ @Inject
+ private CreateGroup createGroup;
- @Inject
- private DeleteUser deleteUser;
+ @Inject
+ private UpdateUser updateUser;
- @Inject
- private DeleteGroup deleteGroup;
+ @Inject
+ private UpdateGroup updateGroup;
- @Inject
- private ModifyAce modifyAce;
+ @Inject
+ private DeleteUser deleteUser;
- @Rule
- public TestName testName = new TestName();
+ @Inject
+ private DeleteGroup deleteGroup;
+
+ @Inject
+ private ModifyAce modifyAce;
+
+ @Inject
+ private DeleteAces deleteAces;
+
+ @Inject
+ private ChangeUserPassword changeUserPassword;
+
+ @Rule
+ public TestName testName = new TestName();
protected Session adminSession;
protected User user1;
protected Session user1Session;
- @Configuration
- public Option[] configuration() {
- return options(
- baseConfiguration()
- );
- }
+ @Configuration
+ public Option[] configuration() {
+ return options(
+ baseConfiguration()
+ );
+ }
@Before
public void setup() throws Exception {
adminSession = repository.login(new SimpleCredentials("admin", "admin".toCharArray()));
- assertNotNull("Expected adminSession to not be null", adminSession);
+ assertNotNull("Expected adminSession to not be null", adminSession);
- user1 = createUser.createUser(adminSession, createUniqueName("user"), "testPwd", "testPwd",
- Collections.emptyMap(), new ArrayList<Modification>());
- assertNotNull("Expected user1 to not be null", user1);
-
- if (adminSession.hasPendingChanges()) {
- adminSession.save();
- }
-
- user1Session = repository.login(new SimpleCredentials(user1.getID(), "testPwd".toCharArray()));
- assertNotNull("Expected user1Session to not be null", user1Session);
+ user1 = createUser.createUser(adminSession, createUniqueName("user"), "testPwd", "testPwd",
+ Collections.emptyMap(), new ArrayList<Modification>());
+ assertNotNull("Expected user1 to not be null", user1);
+
+ if (adminSession.hasPendingChanges()) {
+ adminSession.save();
+ }
+
+ user1Session = repository.login(new SimpleCredentials(user1.getID(), "testPwd".toCharArray()));
+ assertNotNull("Expected user1Session to not be null", user1Session);
}
@After
public void teardown() {
- try {
- adminSession.refresh(false);
- if (user1 != null) {
- deleteUser.deleteUser(adminSession, user1.getID(), new ArrayList<>());
- }
+ try {
+ adminSession.refresh(false);
+ if (user1 != null) {
+ deleteUser.deleteUser(adminSession, user1.getID(), new ArrayList<>());
+ }
- if (adminSession.hasPendingChanges()) {
- adminSession.save();
- }
- } catch (RepositoryException e) {
- logger.warn("Failed to delete user: " + e.getMessage(), e);
- }
+ if (adminSession.hasPendingChanges()) {
+ adminSession.save();
+ }
+ } catch (RepositoryException e) {
+ logger.warn("Failed to delete user: " + e.getMessage(), e);
+ }
- user1Session.logout();
+ user1Session.logout();
adminSession.logout();
}
- protected String createUniqueName(String prefix) {
- return String.format("%s_%s%d", prefix, testName.getMethodName(), counter.incrementAndGet());
- }
+ protected String createUniqueName(String prefix) {
+ return String.format("%s_%s%d", prefix, testName.getMethodName(), counter.incrementAndGet());
+ }
/**
* Checks whether the current user has been granted privileges
@@ -172,49 +180,49 @@
*/
@Test
public void canAddUser() throws Exception {
- assertNotNull("Expected privilegesInfo to not be null", privilegesInfo);
-
- User user2 = null;
- try {
- // initially user can't do the operations
- assertFalse("Should not be allowed to add user",
- privilegesInfo.canAddUser(user1Session));
-
- String usersPath = userConfig.getParameters().getConfigValue("usersPath", (String)null);
- assertNotNull("Users Path should not be null", usersPath);
- assertTrue("Users Path should exist",
- adminSession.itemExists(usersPath));
+ assertNotNull("Expected privilegesInfo to not be null", privilegesInfo);
- // grant user1 rights
- Map<String, String> privileges = new HashMap<>();
- privileges.put(String.format("privilege@%s", Privilege.JCR_READ), "granted");
- privileges.put(String.format("privilege@%s", Privilege.JCR_READ_ACCESS_CONTROL), "granted");
- privileges.put(String.format("privilege@%s", Privilege.JCR_MODIFY_ACCESS_CONTROL), "granted");
- privileges.put(String.format("privilege@%s", PrivilegeConstants.REP_WRITE), "granted");
- privileges.put(String.format("privilege@%s", PrivilegeConstants.REP_USER_MANAGEMENT), "granted");
- modifyAce.modifyAce(adminSession, usersPath, user1.getID(),
- privileges,
- "first");
- assertTrue("Should be allowed to add user",
- privilegesInfo.canAddUser(user1Session));
+ User user2 = null;
+ try {
+ // initially user can't do the operations
+ assertFalse("Should not be allowed to add user",
+ privilegesInfo.canAddUser(user1Session));
- // verify that the user can actually add the user
- try {
- Map<String, String> propMap = new HashMap<>();
- propMap.put("prop1", "value1");
- propMap.put("nested/prop2", "value2");
- user2 = createUser.createUser(user1Session, createUniqueName("user"), "testPwd", "testPwd",
- propMap, new ArrayList<Modification>());
- assertNotNull("Expected user2 to not be null", user2);
- } catch (RepositoryException e) {
- logger.error("Did not expect RepositoryException when adding user: " + e.getMessage(), e);
- fail("Did not expect RepositoryException when adding user: " + e.getMessage());
- }
- } finally {
- if (user2 != null) {
- deleteUser.deleteUser(adminSession, user2.getID(), new ArrayList<>());
- }
- }
+ String usersPath = userConfig.getParameters().getConfigValue("usersPath", (String)null);
+ assertNotNull("Users Path should not be null", usersPath);
+ assertTrue("Users Path should exist",
+ adminSession.itemExists(usersPath));
+
+ // grant user1 rights
+ Map<String, String> privileges = new HashMap<>();
+ privileges.put(String.format("privilege@%s", Privilege.JCR_READ), "granted");
+ privileges.put(String.format("privilege@%s", Privilege.JCR_READ_ACCESS_CONTROL), "granted");
+ privileges.put(String.format("privilege@%s", Privilege.JCR_MODIFY_ACCESS_CONTROL), "granted");
+ privileges.put(String.format("privilege@%s", PrivilegeConstants.REP_WRITE), "granted");
+ privileges.put(String.format("privilege@%s", PrivilegeConstants.REP_USER_MANAGEMENT), "granted");
+ modifyAce.modifyAce(adminSession, usersPath, user1.getID(),
+ privileges,
+ "first");
+ assertTrue("Should be allowed to add user",
+ privilegesInfo.canAddUser(user1Session));
+
+ // verify that the user can actually add the user
+ try {
+ Map<String, String> propMap = new HashMap<>();
+ propMap.put("prop1", "value1");
+ propMap.put("nested/prop2", "value2");
+ user2 = createUser.createUser(user1Session, createUniqueName("user"), "testPwd", "testPwd",
+ propMap, new ArrayList<Modification>());
+ assertNotNull("Expected user2 to not be null", user2);
+ } catch (RepositoryException e) {
+ logger.error("Did not expect RepositoryException when adding user: " + e.getMessage(), e);
+ fail("Did not expect RepositoryException when adding user: " + e.getMessage());
+ }
+ } finally {
+ if (user2 != null) {
+ deleteUser.deleteUser(adminSession, user2.getID(), new ArrayList<>());
+ }
+ }
}
/**
@@ -223,71 +231,71 @@
*/
@Test
public void canAddGroup() throws Exception {
- assertNotNull("Expected privilegesInfo to not be null", privilegesInfo);
-
- workaroundMissingGroupsPath();
+ assertNotNull("Expected privilegesInfo to not be null", privilegesInfo);
- Group group1 = null;
- try {
- // initially user can't do the operations
- assertFalse("Should not be allowed to add group",
- privilegesInfo.canAddGroup(user1Session));
-
- String groupsPath = userConfig.getParameters().getConfigValue("groupsPath", (String)null);
- assertNotNull("Groups Path should not be null", groupsPath);
- assertTrue("Groups Path should exist",
- adminSession.itemExists(groupsPath));
-
- // grant user1 rights
- Map<String, String> privileges = new HashMap<>();
- privileges.put(String.format("privilege@%s", Privilege.JCR_READ), "granted");
- privileges.put(String.format("privilege@%s", Privilege.JCR_READ_ACCESS_CONTROL), "granted");
- privileges.put(String.format("privilege@%s", Privilege.JCR_MODIFY_ACCESS_CONTROL), "granted");
- privileges.put(String.format("privilege@%s", PrivilegeConstants.REP_WRITE), "granted");
- privileges.put(String.format("privilege@%s", PrivilegeConstants.REP_USER_MANAGEMENT), "granted");
- modifyAce.modifyAce(adminSession, groupsPath, user1.getID(),
- privileges,
- "first");
- assertTrue("Should be allowed to add group",
- privilegesInfo.canAddGroup(user1Session));
+ workaroundMissingGroupsPath();
- // verify that the user can actually add the user
- try {
- Map<String, String> propMap = new HashMap<>();
- propMap.put("prop1", "value1");
- propMap.put("nested/prop2", "value2");
- group1 = createGroup.createGroup(user1Session, createUniqueName("group"),
- propMap, new ArrayList<Modification>());
- assertNotNull("Expected group1 to not be null", group1);
- } catch (RepositoryException e) {
- logger.error("Did not expect RepositoryException when adding group: " + e.getMessage(), e);
- fail("Did not expect RepositoryException when adding group: " + e.getMessage());
- }
- } finally {
- if (group1 != null) {
- deleteGroup.deleteGroup(user1Session, group1.getID(), new ArrayList<>());
- }
- }
+ Group group1 = null;
+ try {
+ // initially user can't do the operations
+ assertFalse("Should not be allowed to add group",
+ privilegesInfo.canAddGroup(user1Session));
+
+ String groupsPath = userConfig.getParameters().getConfigValue("groupsPath", (String)null);
+ assertNotNull("Groups Path should not be null", groupsPath);
+ assertTrue("Groups Path should exist",
+ adminSession.itemExists(groupsPath));
+
+ // grant user1 rights
+ Map<String, String> privileges = new HashMap<>();
+ privileges.put(String.format("privilege@%s", Privilege.JCR_READ), "granted");
+ privileges.put(String.format("privilege@%s", Privilege.JCR_READ_ACCESS_CONTROL), "granted");
+ privileges.put(String.format("privilege@%s", Privilege.JCR_MODIFY_ACCESS_CONTROL), "granted");
+ privileges.put(String.format("privilege@%s", PrivilegeConstants.REP_WRITE), "granted");
+ privileges.put(String.format("privilege@%s", PrivilegeConstants.REP_USER_MANAGEMENT), "granted");
+ modifyAce.modifyAce(adminSession, groupsPath, user1.getID(),
+ privileges,
+ "first");
+ assertTrue("Should be allowed to add group",
+ privilegesInfo.canAddGroup(user1Session));
+
+ // verify that the user can actually add the user
+ try {
+ Map<String, String> propMap = new HashMap<>();
+ propMap.put("prop1", "value1");
+ propMap.put("nested/prop2", "value2");
+ group1 = createGroup.createGroup(user1Session, createUniqueName("group"),
+ propMap, new ArrayList<Modification>());
+ assertNotNull("Expected group1 to not be null", group1);
+ } catch (RepositoryException e) {
+ logger.error("Did not expect RepositoryException when adding group: " + e.getMessage(), e);
+ fail("Did not expect RepositoryException when adding group: " + e.getMessage());
+ }
+ } finally {
+ if (group1 != null) {
+ deleteGroup.deleteGroup(user1Session, group1.getID(), new ArrayList<>());
+ }
+ }
}
- /**
- * The oak groupsPath appears to be missing until the first group is created.
- * So create a group as the admin user to get it bootstrapped. This makes it
- * possible for non-admin users to create groups without requiring extra access
- * rights to the intermediate parents of the groupsPath folder.
- */
- protected void workaroundMissingGroupsPath() throws RepositoryException {
- String groupsPath = userConfig.getParameters().getConfigValue("groupsPath", (String)null);
- assertNotNull("Groups Path should not be null", groupsPath);
- if (!adminSession.itemExists(groupsPath)) {
- // create a group and the remove it
- Group tempGroup = createGroup.createGroup(adminSession, createUniqueName("group"),
- Collections.emptyMap(), new ArrayList<Modification>());
- deleteGroup.deleteGroup(adminSession, tempGroup.getID(), new ArrayList<>());
- }
- assertTrue("Groups Path should exist",
- adminSession.itemExists(groupsPath));
- }
+ /**
+ * The oak groupsPath appears to be missing until the first group is created.
+ * So create a group as the admin user to get it bootstrapped. This makes it
+ * possible for non-admin users to create groups without requiring extra access
+ * rights to the intermediate parents of the groupsPath folder.
+ */
+ protected void workaroundMissingGroupsPath() throws RepositoryException {
+ String groupsPath = userConfig.getParameters().getConfigValue("groupsPath", (String)null);
+ assertNotNull("Groups Path should not be null", groupsPath);
+ if (!adminSession.itemExists(groupsPath)) {
+ // create a group and the remove it
+ Group tempGroup = createGroup.createGroup(adminSession, createUniqueName("group"),
+ Collections.emptyMap(), new ArrayList<Modification>());
+ deleteGroup.deleteGroup(adminSession, tempGroup.getID(), new ArrayList<>());
+ }
+ assertTrue("Groups Path should exist",
+ adminSession.itemExists(groupsPath));
+ }
/**
* Checks whether the current user has been granted privileges
@@ -295,297 +303,297 @@
*/
@Test
public void canUpdateProperties() throws Exception {
- assertNotNull("Expected privilegesInfo to not be null", privilegesInfo);
+ assertNotNull("Expected privilegesInfo to not be null", privilegesInfo);
- workaroundMissingGroupsPath();
+ workaroundMissingGroupsPath();
- User user2 = null;
- Group group1 = null;
+ User user2 = null;
+ Group group1 = null;
- try {
- // create a couple of test users
- user2 = createUser.createUser(adminSession, createUniqueName("group"), "testPwd", "testPwd",
- Collections.singletonMap("prop1", "value1"), new ArrayList<Modification>());
- assertNotNull("Expected user2 to not be null", user2);
+ try {
+ // create a couple of test users
+ user2 = createUser.createUser(adminSession, createUniqueName("user"), "testPwd", "testPwd",
+ Collections.singletonMap("prop1", "value1"), new ArrayList<Modification>());
+ assertNotNull("Expected user2 to not be null", user2);
- group1 = createGroup.createGroup(adminSession, createUniqueName("group"),
- Collections.singletonMap("prop1", "value1"), new ArrayList<Modification>());
- assertNotNull("Expected group1 to not be null", group1);
+ group1 = createGroup.createGroup(adminSession, createUniqueName("group"),
+ Collections.singletonMap("prop1", "value1"), new ArrayList<Modification>());
+ assertNotNull("Expected group1 to not be null", group1);
- String [] principalIds = new String[] { user2.getID(), group1.getID() };
+ String [] principalIds = new String[] { user2.getID(), group1.getID() };
- // initially user can't do the operation
- for (String pid : principalIds) {
- assertFalse("Should not be allowed to update properties for: " + pid,
- privilegesInfo.canUpdateProperties(user1Session, pid));
- }
-
- // start with only read rights
- Map<String, String> privileges = new HashMap<>();
- privileges.put(String.format("privilege@%s", Privilege.JCR_READ), "granted");
- modifyAce.modifyAce(adminSession, user2.getPath(), user1.getID(),
- privileges,
- "first");
- modifyAce.modifyAce(adminSession, group1.getPath(), user1.getID(),
- privileges,
- "first");
- for (String pid : principalIds) {
- assertFalse("Should not be allowed to update properties for: " + pid,
- privilegesInfo.canUpdateProperties(user1Session, pid));
- assertFalse("Should not be allowed to update properties for: " + pid,
- privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addProperty, PropertyUpdateTypes.addNestedProperty, PropertyUpdateTypes.removeProperty));
- assertFalse("Should not be allowed to update properties for: " + pid,
- privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addProperty, PropertyUpdateTypes.addNestedProperty));
- assertFalse("Should not be allowed to update properties for: " + pid,
- privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addProperty, PropertyUpdateTypes.removeProperty));
- assertFalse("Should not be allowed to update properties for: " + pid,
- privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addProperty));
- assertFalse("Should not be allowed to update properties for: " + pid,
- privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addNestedProperty, PropertyUpdateTypes.removeProperty));
- assertFalse("Should not be allowed to update properties for: " + pid,
- privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addNestedProperty));
- assertFalse("Should not be allowed to update properties for: " + pid,
- privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.removeProperty));
- }
+ // initially user can't do the operation
+ for (String pid : principalIds) {
+ assertFalse("Should not be allowed to update properties for: " + pid,
+ privilegesInfo.canUpdateProperties(user1Session, pid));
+ }
- // + grant user management rights
- privileges.put(String.format("privilege@%s", PrivilegeConstants.REP_USER_MANAGEMENT), "granted");
- modifyAce.modifyAce(adminSession, user2.getPath(), user1.getID(),
- privileges,
- "first");
- modifyAce.modifyAce(adminSession, group1.getPath(), user1.getID(),
- privileges,
- "first");
- for (String pid : principalIds) {
- assertFalse("Should not be allowed to update properties for: " + pid,
- privilegesInfo.canUpdateProperties(user1Session, pid));
- assertFalse("Should not be allowed to update properties for: " + pid,
- privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addProperty, PropertyUpdateTypes.addNestedProperty, PropertyUpdateTypes.removeProperty));
- assertFalse("Should not be allowed to update properties for: " + pid,
- privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addProperty, PropertyUpdateTypes.addNestedProperty));
- assertFalse("Should not be allowed to update properties for: " + pid,
- privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addProperty, PropertyUpdateTypes.removeProperty));
- assertFalse("Should not be allowed to update properties for: " + pid,
- privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addProperty));
- assertFalse("Should not be allowed to update properties for: " + pid,
- privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addNestedProperty, PropertyUpdateTypes.removeProperty));
- assertFalse("Should not be allowed to update properties for: " + pid,
- privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addNestedProperty));
- assertFalse("Should not be allowed to update properties for: " + pid,
- privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.removeProperty));
- }
+ // start with only read rights
+ Map<String, String> privileges = new HashMap<>();
+ privileges.put(String.format("privilege@%s", Privilege.JCR_READ), "granted");
+ modifyAce.modifyAce(adminSession, user2.getPath(), user1.getID(),
+ privileges,
+ "first");
+ modifyAce.modifyAce(adminSession, group1.getPath(), user1.getID(),
+ privileges,
+ "first");
+ for (String pid : principalIds) {
+ assertFalse("Should not be allowed to update properties for: " + pid,
+ privilegesInfo.canUpdateProperties(user1Session, pid));
+ assertFalse("Should not be allowed to update properties for: " + pid,
+ privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addProperty, PropertyUpdateTypes.addNestedProperty, PropertyUpdateTypes.removeProperty));
+ assertFalse("Should not be allowed to update properties for: " + pid,
+ privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addProperty, PropertyUpdateTypes.addNestedProperty));
+ assertFalse("Should not be allowed to update properties for: " + pid,
+ privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addProperty, PropertyUpdateTypes.removeProperty));
+ assertFalse("Should not be allowed to update properties for: " + pid,
+ privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addProperty));
+ assertFalse("Should not be allowed to update properties for: " + pid,
+ privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addNestedProperty, PropertyUpdateTypes.removeProperty));
+ assertFalse("Should not be allowed to update properties for: " + pid,
+ privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addNestedProperty));
+ assertFalse("Should not be allowed to update properties for: " + pid,
+ privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.removeProperty));
+ }
-
- // grant rights to only remove properties
- privileges.put(String.format("privilege@%s", PrivilegeConstants.REP_ADD_PROPERTIES), "none");
- privileges.put(String.format("privilege@%s", PrivilegeConstants.REP_ALTER_PROPERTIES), "none");
- privileges.put(String.format("privilege@%s", Privilege.JCR_ADD_CHILD_NODES), "none");
- privileges.put(String.format("privilege@%s", PrivilegeConstants.REP_REMOVE_PROPERTIES), "granted");
- modifyAce.modifyAce(adminSession, user2.getPath(), user1.getID(),
- privileges,
- "first");
- modifyAce.modifyAce(adminSession, group1.getPath(), user1.getID(),
- privileges,
- "first");
- for (String pid : principalIds) {
- assertFalse("Should not be allowed to update properties for: " + pid,
- privilegesInfo.canUpdateProperties(user1Session, pid));
- assertFalse("Should not be allowed to update properties for: " + pid,
- privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addProperty, PropertyUpdateTypes.addNestedProperty, PropertyUpdateTypes.removeProperty));
- assertFalse("Should not be allowed to update properties for: " + pid,
- privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addProperty, PropertyUpdateTypes.addNestedProperty));
- assertFalse("Should not be allowed to update properties for: " + pid,
- privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addProperty, PropertyUpdateTypes.removeProperty));
- assertFalse("Should not be allowed to update properties for: " + pid,
- privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addProperty));
- assertFalse("Should not be allowed to update properties for: " + pid,
- privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addNestedProperty, PropertyUpdateTypes.removeProperty));
- assertFalse("Should not be allowed to update properties for: " + pid,
- privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addNestedProperty));
- assertTrue("Should be allowed to update properties for: " + pid,
- privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.removeProperty));
- }
-
- // verify that the user can actually delete property
- Map<String, Object> propsMap = new HashMap<>();
- propsMap.put("prop1@Delete", "value1");
- try {
- updateUser.updateUser(user1Session, user2.getID(), propsMap, new ArrayList<>());
- updateGroup.updateGroup(user1Session, group1.getID(), propsMap, new ArrayList<>());
- assertTrue("Expected pending changes in the jcr session", user1Session.hasPendingChanges());
- user1Session.save();
- } catch (RepositoryException e) {
- logger.error("Did not expect RepositoryException when deleting property: " + e.getMessage(), e);
- fail("Did not expect RepositoryException when deleting property: " + e.getMessage());
- }
- // verify that the user can not add nested property
- propsMap = new HashMap<>();
- propsMap.put("nested/prop2", "value2");
- updateUser.updateUser(user1Session, user2.getID(), propsMap, new ArrayList<>());
- updateGroup.updateGroup(user1Session, group1.getID(), propsMap, new ArrayList<>());
- assertTrue("Expected pending changes in the jcr session", user1Session.hasPendingChanges());
- try {
- user1Session.save();
- fail("Expected AccessDeniedException when adding nested property");
- } catch (AccessDeniedException e) {
- // expected
- user1Session.refresh(false);
- }
-
-
-
- // grant rights to only alter (non-nested) properties
- privileges.put(String.format("privilege@%s", PrivilegeConstants.REP_ADD_PROPERTIES), "granted");
- privileges.put(String.format("privilege@%s", Privilege.JCR_ADD_CHILD_NODES), "none");
- privileges.put(String.format("privilege@%s", PrivilegeConstants.REP_REMOVE_PROPERTIES), "none");
- modifyAce.modifyAce(adminSession, user2.getPath(), user1.getID(),
- privileges,
- "first");
- modifyAce.modifyAce(adminSession, group1.getPath(), user1.getID(),
- privileges,
- "first");
- for (String pid : principalIds) {
- assertFalse("Should not be allowed to update properties for: " + pid,
- privilegesInfo.canUpdateProperties(user1Session, pid));
- assertFalse("Should not be allowed to update properties for: " + pid,
- privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addProperty, PropertyUpdateTypes.addNestedProperty, PropertyUpdateTypes.removeProperty));
- assertFalse("Should not be allowed to update properties for: " + pid,
- privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addProperty, PropertyUpdateTypes.addNestedProperty));
- assertFalse("Should not be allowed to update properties for: " + pid,
- privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addProperty, PropertyUpdateTypes.removeProperty));
- assertTrue("Should be allowed to update properties for: " + pid,
- privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addProperty));
- assertFalse("Should not be allowed to update properties for: " + pid,
- privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addNestedProperty, PropertyUpdateTypes.removeProperty));
- assertFalse("Should not be allowed to update properties for: " + pid,
- privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addNestedProperty));
- assertFalse("Should not be allowed to update properties for: " + pid,
- privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.removeProperty));
- }
-
- // verify that the user can actually add property
- propsMap = new HashMap<>();
- propsMap.put("prop1", "value1");
- try {
- updateUser.updateUser(user1Session, user2.getID(), propsMap, new ArrayList<>());
- updateGroup.updateGroup(user1Session, group1.getID(), propsMap, new ArrayList<>());
- assertTrue("Expected pending changes in the jcr session", user1Session.hasPendingChanges());
- user1Session.save();
- } catch (RepositoryException e) {
- logger.error("Did not expect RepositoryException when adding property: " + e.getMessage(), e);
- fail("Did not expect RepositoryException when adding property: " + e.getMessage());
- }
- // verify that the user can not add nested property
- propsMap.put("nested/prop2", "value2");
- updateUser.updateUser(user1Session, user2.getID(), propsMap, new ArrayList<>());
- updateGroup.updateGroup(user1Session, group1.getID(), propsMap, new ArrayList<>());
- assertTrue("Expected pending changes in the jcr session", user1Session.hasPendingChanges());
- try {
- user1Session.save();
- fail("Expected AccessDeniedException when adding nested property");
- } catch (AccessDeniedException e) {
- // expected
- user1Session.refresh(false);
- }
-
-
-
- // grant rights to alter (non-nested or nested) properties
- privileges.put(String.format("privilege@%s", PrivilegeConstants.REP_ADD_PROPERTIES), "granted");
- privileges.put(String.format("privilege@%s", PrivilegeConstants.REP_ALTER_PROPERTIES), "granted");
- privileges.put(String.format("privilege@%s", Privilege.JCR_ADD_CHILD_NODES), "granted");
- privileges.put(String.format("privilege@%s", PrivilegeConstants.REP_REMOVE_PROPERTIES), "none");
- modifyAce.modifyAce(adminSession, user2.getPath(), user1.getID(),
- privileges,
- "first");
- modifyAce.modifyAce(adminSession, group1.getPath(), user1.getID(),
- privileges,
- "first");
- for (String pid : principalIds) {
- assertFalse("Should not be allowed to update properties for: " + pid,
- privilegesInfo.canUpdateProperties(user1Session, pid));
- assertFalse("Should not be allowed to update properties for: " + pid,
- privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addProperty, PropertyUpdateTypes.addNestedProperty, PropertyUpdateTypes.removeProperty));
- assertTrue("Should be allowed to update properties for: " + pid,
- privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addProperty, PropertyUpdateTypes.addNestedProperty));
- assertFalse("Should not be allowed to update properties for: " + pid,
- privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addProperty, PropertyUpdateTypes.removeProperty));
- assertTrue("Should be allowed to update properties for: " + pid,
- privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addProperty));
- assertFalse("Should not be allowed to update properties for: " + pid,
- privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addNestedProperty, PropertyUpdateTypes.removeProperty));
- assertTrue("Should be allowed to update properties for: " + pid,
- privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addNestedProperty));
- assertFalse("Should not be allowed to update properties for: " + pid,
- privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.removeProperty));
- }
-
- // verify that the user can actually add property and nested property
- propsMap = new HashMap<>();
- propsMap.put("prop1", "value1");
- propsMap.put("nested/prop2", "value2");
- try {
- updateUser.updateUser(user1Session, user2.getID(), propsMap, new ArrayList<>());
- updateGroup.updateGroup(user1Session, group1.getID(), propsMap, new ArrayList<>());
- assertTrue("Expected pending changes in the jcr session", user1Session.hasPendingChanges());
- user1Session.save();
- } catch (RepositoryException e) {
- logger.error("Did not expect RepositoryException when adding properties: " + e.getMessage(), e);
- fail("Did not expect RepositoryException when adding properties: " + e.getMessage());
- }
-
-
-
- // grant rights to alter (non-nested or nested) properties and remove properties
- privileges.put(String.format("privilege@%s", PrivilegeConstants.REP_ADD_PROPERTIES), "granted");
- privileges.put(String.format("privilege@%s", PrivilegeConstants.REP_ALTER_PROPERTIES), "granted");
- privileges.put(String.format("privilege@%s", Privilege.JCR_ADD_CHILD_NODES), "granted");
- privileges.put(String.format("privilege@%s", PrivilegeConstants.REP_REMOVE_PROPERTIES), "granted");
- modifyAce.modifyAce(adminSession, user2.getPath(), user1.getID(),
- privileges,
- "first");
- modifyAce.modifyAce(adminSession, group1.getPath(), user1.getID(),
- privileges,
- "first");
- for (String pid : principalIds) {
- assertTrue("Should be allowed to update properties for: " + pid,
- privilegesInfo.canUpdateProperties(user1Session, pid));
- assertTrue("Should be allowed to update properties for: " + pid,
- privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addProperty, PropertyUpdateTypes.addNestedProperty, PropertyUpdateTypes.removeProperty));
- assertTrue("Should be allowed to update properties for: " + pid,
- privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addProperty, PropertyUpdateTypes.addNestedProperty));
- assertTrue("Should be allowed to update properties for: " + pid,
- privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addProperty, PropertyUpdateTypes.removeProperty));
- assertTrue("Should be allowed to update properties for: " + pid,
- privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addProperty));
- assertTrue("Should be allowed to update properties for: " + pid,
- privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addNestedProperty, PropertyUpdateTypes.removeProperty));
- assertTrue("Should be allowed to update properties for: " + pid,
- privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addNestedProperty));
- assertTrue("Should be allowed to update properties for: " + pid,
- privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.removeProperty));
- }
-
- // verify that the user can actually add property and nested property
- propsMap = new HashMap<>();
- propsMap.put("prop3", "value3");
- propsMap.put("nested/prop4", "value4");
- propsMap.put("prop1@Delete", "value1");
- propsMap.put("nested/prop2@Delete", "value1");
- try {
- updateUser.updateUser(user1Session, user2.getID(), propsMap, new ArrayList<>());
- updateGroup.updateGroup(user1Session, group1.getID(), propsMap, new ArrayList<>());
- assertTrue("Expected pending changes in the jcr session", user1Session.hasPendingChanges());
- user1Session.save();
- } catch (RepositoryException e) {
- logger.error("Did not expect RepositoryException when adding or deleting properties: " + e.getMessage(), e);
- fail("Did not expect RepositoryException when adding or deleting properties: " + e.getMessage());
- }
- } finally {
- if (user2 != null) {
- deleteUser.deleteUser(adminSession, user2.getID(), new ArrayList<>());
- }
- }
+ // + grant user management rights
+ privileges.put(String.format("privilege@%s", PrivilegeConstants.REP_USER_MANAGEMENT), "granted");
+ modifyAce.modifyAce(adminSession, user2.getPath(), user1.getID(),
+ privileges,
+ "first");
+ modifyAce.modifyAce(adminSession, group1.getPath(), user1.getID(),
+ privileges,
+ "first");
+ for (String pid : principalIds) {
+ assertFalse("Should not be allowed to update properties for: " + pid,
+ privilegesInfo.canUpdateProperties(user1Session, pid));
+ assertFalse("Should not be allowed to update properties for: " + pid,
+ privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addProperty, PropertyUpdateTypes.addNestedProperty, PropertyUpdateTypes.removeProperty));
+ assertFalse("Should not be allowed to update properties for: " + pid,
+ privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addProperty, PropertyUpdateTypes.addNestedProperty));
+ assertFalse("Should not be allowed to update properties for: " + pid,
+ privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addProperty, PropertyUpdateTypes.removeProperty));
+ assertFalse("Should not be allowed to update properties for: " + pid,
+ privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addProperty));
+ assertFalse("Should not be allowed to update properties for: " + pid,
+ privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addNestedProperty, PropertyUpdateTypes.removeProperty));
+ assertFalse("Should not be allowed to update properties for: " + pid,
+ privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addNestedProperty));
+ assertFalse("Should not be allowed to update properties for: " + pid,
+ privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.removeProperty));
+ }
+
+
+ // grant rights to only remove properties
+ privileges.put(String.format("privilege@%s", PrivilegeConstants.REP_ADD_PROPERTIES), "none");
+ privileges.put(String.format("privilege@%s", PrivilegeConstants.REP_ALTER_PROPERTIES), "none");
+ privileges.put(String.format("privilege@%s", Privilege.JCR_ADD_CHILD_NODES), "none");
+ privileges.put(String.format("privilege@%s", PrivilegeConstants.REP_REMOVE_PROPERTIES), "granted");
+ modifyAce.modifyAce(adminSession, user2.getPath(), user1.getID(),
+ privileges,
+ "first");
+ modifyAce.modifyAce(adminSession, group1.getPath(), user1.getID(),
+ privileges,
+ "first");
+ for (String pid : principalIds) {
+ assertFalse("Should not be allowed to update properties for: " + pid,
+ privilegesInfo.canUpdateProperties(user1Session, pid));
+ assertFalse("Should not be allowed to update properties for: " + pid,
+ privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addProperty, PropertyUpdateTypes.addNestedProperty, PropertyUpdateTypes.removeProperty));
+ assertFalse("Should not be allowed to update properties for: " + pid,
+ privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addProperty, PropertyUpdateTypes.addNestedProperty));
+ assertFalse("Should not be allowed to update properties for: " + pid,
+ privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addProperty, PropertyUpdateTypes.removeProperty));
+ assertFalse("Should not be allowed to update properties for: " + pid,
+ privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addProperty));
+ assertFalse("Should not be allowed to update properties for: " + pid,
+ privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addNestedProperty, PropertyUpdateTypes.removeProperty));
+ assertFalse("Should not be allowed to update properties for: " + pid,
+ privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addNestedProperty));
+ assertTrue("Should be allowed to update properties for: " + pid,
+ privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.removeProperty));
+ }
+
+ // verify that the user can actually delete property
+ Map<String, Object> propsMap = new HashMap<>();
+ propsMap.put("prop1@Delete", "value1");
+ try {
+ updateUser.updateUser(user1Session, user2.getID(), propsMap, new ArrayList<>());
+ updateGroup.updateGroup(user1Session, group1.getID(), propsMap, new ArrayList<>());
+ assertTrue("Expected pending changes in the jcr session", user1Session.hasPendingChanges());
+ user1Session.save();
+ } catch (RepositoryException e) {
+ logger.error("Did not expect RepositoryException when deleting property: " + e.getMessage(), e);
+ fail("Did not expect RepositoryException when deleting property: " + e.getMessage());
+ }
+ // verify that the user can not add nested property
+ propsMap = new HashMap<>();
+ propsMap.put("nested/prop2", "value2");
+ updateUser.updateUser(user1Session, user2.getID(), propsMap, new ArrayList<>());
+ updateGroup.updateGroup(user1Session, group1.getID(), propsMap, new ArrayList<>());
+ assertTrue("Expected pending changes in the jcr session", user1Session.hasPendingChanges());
+ try {
+ user1Session.save();
+ fail("Expected AccessDeniedException when adding nested property");
+ } catch (AccessDeniedException e) {
+ // expected
+ user1Session.refresh(false);
+ }
+
+
+
+ // grant rights to only alter (non-nested) properties
+ privileges.put(String.format("privilege@%s", PrivilegeConstants.REP_ADD_PROPERTIES), "granted");
+ privileges.put(String.format("privilege@%s", Privilege.JCR_ADD_CHILD_NODES), "none");
+ privileges.put(String.format("privilege@%s", PrivilegeConstants.REP_REMOVE_PROPERTIES), "none");
+ modifyAce.modifyAce(adminSession, user2.getPath(), user1.getID(),
+ privileges,
+ "first");
+ modifyAce.modifyAce(adminSession, group1.getPath(), user1.getID(),
+ privileges,
+ "first");
+ for (String pid : principalIds) {
+ assertFalse("Should not be allowed to update properties for: " + pid,
+ privilegesInfo.canUpdateProperties(user1Session, pid));
+ assertFalse("Should not be allowed to update properties for: " + pid,
+ privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addProperty, PropertyUpdateTypes.addNestedProperty, PropertyUpdateTypes.removeProperty));
+ assertFalse("Should not be allowed to update properties for: " + pid,
+ privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addProperty, PropertyUpdateTypes.addNestedProperty));
+ assertFalse("Should not be allowed to update properties for: " + pid,
+ privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addProperty, PropertyUpdateTypes.removeProperty));
+ assertTrue("Should be allowed to update properties for: " + pid,
+ privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addProperty));
+ assertFalse("Should not be allowed to update properties for: " + pid,
+ privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addNestedProperty, PropertyUpdateTypes.removeProperty));
+ assertFalse("Should not be allowed to update properties for: " + pid,
+ privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addNestedProperty));
+ assertFalse("Should not be allowed to update properties for: " + pid,
+ privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.removeProperty));
+ }
+
+ // verify that the user can actually add property
+ propsMap = new HashMap<>();
+ propsMap.put("prop1", "value1");
+ try {
+ updateUser.updateUser(user1Session, user2.getID(), propsMap, new ArrayList<>());
+ updateGroup.updateGroup(user1Session, group1.getID(), propsMap, new ArrayList<>());
+ assertTrue("Expected pending changes in the jcr session", user1Session.hasPendingChanges());
+ user1Session.save();
+ } catch (RepositoryException e) {
+ logger.error("Did not expect RepositoryException when adding property: " + e.getMessage(), e);
+ fail("Did not expect RepositoryException when adding property: " + e.getMessage());
+ }
+ // verify that the user can not add nested property
+ propsMap.put("nested/prop2", "value2");
+ updateUser.updateUser(user1Session, user2.getID(), propsMap, new ArrayList<>());
+ updateGroup.updateGroup(user1Session, group1.getID(), propsMap, new ArrayList<>());
+ assertTrue("Expected pending changes in the jcr session", user1Session.hasPendingChanges());
+ try {
+ user1Session.save();
+ fail("Expected AccessDeniedException when adding nested property");
+ } catch (AccessDeniedException e) {
+ // expected
+ user1Session.refresh(false);
+ }
+
+
+
+ // grant rights to alter (non-nested or nested) properties
+ privileges.put(String.format("privilege@%s", PrivilegeConstants.REP_ADD_PROPERTIES), "granted");
+ privileges.put(String.format("privilege@%s", PrivilegeConstants.REP_ALTER_PROPERTIES), "granted");
+ privileges.put(String.format("privilege@%s", Privilege.JCR_ADD_CHILD_NODES), "granted");
+ privileges.put(String.format("privilege@%s", PrivilegeConstants.REP_REMOVE_PROPERTIES), "none");
+ modifyAce.modifyAce(adminSession, user2.getPath(), user1.getID(),
+ privileges,
+ "first");
+ modifyAce.modifyAce(adminSession, group1.getPath(), user1.getID(),
+ privileges,
+ "first");
+ for (String pid : principalIds) {
+ assertFalse("Should not be allowed to update properties for: " + pid,
+ privilegesInfo.canUpdateProperties(user1Session, pid));
+ assertFalse("Should not be allowed to update properties for: " + pid,
+ privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addProperty, PropertyUpdateTypes.addNestedProperty, PropertyUpdateTypes.removeProperty));
+ assertTrue("Should be allowed to update properties for: " + pid,
+ privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addProperty, PropertyUpdateTypes.addNestedProperty));
+ assertFalse("Should not be allowed to update properties for: " + pid,
+ privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addProperty, PropertyUpdateTypes.removeProperty));
+ assertTrue("Should be allowed to update properties for: " + pid,
+ privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addProperty));
+ assertFalse("Should not be allowed to update properties for: " + pid,
+ privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addNestedProperty, PropertyUpdateTypes.removeProperty));
+ assertTrue("Should be allowed to update properties for: " + pid,
+ privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addNestedProperty));
+ assertFalse("Should not be allowed to update properties for: " + pid,
+ privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.removeProperty));
+ }
+
+ // verify that the user can actually add property and nested property
+ propsMap = new HashMap<>();
+ propsMap.put("prop1", "value1");
+ propsMap.put("nested/prop2", "value2");
+ try {
+ updateUser.updateUser(user1Session, user2.getID(), propsMap, new ArrayList<>());
+ updateGroup.updateGroup(user1Session, group1.getID(), propsMap, new ArrayList<>());
+ assertTrue("Expected pending changes in the jcr session", user1Session.hasPendingChanges());
+ user1Session.save();
+ } catch (RepositoryException e) {
+ logger.error("Did not expect RepositoryException when adding properties: " + e.getMessage(), e);
+ fail("Did not expect RepositoryException when adding properties: " + e.getMessage());
+ }
+
+
+
+ // grant rights to alter (non-nested or nested) properties and remove properties
+ privileges.put(String.format("privilege@%s", PrivilegeConstants.REP_ADD_PROPERTIES), "granted");
+ privileges.put(String.format("privilege@%s", PrivilegeConstants.REP_ALTER_PROPERTIES), "granted");
+ privileges.put(String.format("privilege@%s", Privilege.JCR_ADD_CHILD_NODES), "granted");
+ privileges.put(String.format("privilege@%s", PrivilegeConstants.REP_REMOVE_PROPERTIES), "granted");
+ modifyAce.modifyAce(adminSession, user2.getPath(), user1.getID(),
+ privileges,
+ "first");
+ modifyAce.modifyAce(adminSession, group1.getPath(), user1.getID(),
+ privileges,
+ "first");
+ for (String pid : principalIds) {
+ assertTrue("Should be allowed to update properties for: " + pid,
+ privilegesInfo.canUpdateProperties(user1Session, pid));
+ assertTrue("Should be allowed to update properties for: " + pid,
+ privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addProperty, PropertyUpdateTypes.addNestedProperty, PropertyUpdateTypes.removeProperty));
+ assertTrue("Should be allowed to update properties for: " + pid,
+ privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addProperty, PropertyUpdateTypes.addNestedProperty));
+ assertTrue("Should be allowed to update properties for: " + pid,
+ privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addProperty, PropertyUpdateTypes.removeProperty));
+ assertTrue("Should be allowed to update properties for: " + pid,
+ privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addProperty));
+ assertTrue("Should be allowed to update properties for: " + pid,
+ privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addNestedProperty, PropertyUpdateTypes.removeProperty));
+ assertTrue("Should be allowed to update properties for: " + pid,
+ privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.addNestedProperty));
+ assertTrue("Should be allowed to update properties for: " + pid,
+ privilegesInfo.canUpdateProperties(user1Session, pid, PropertyUpdateTypes.removeProperty));
+ }
+
+ // verify that the user can actually add property and nested property
+ propsMap = new HashMap<>();
+ propsMap.put("prop3", "value3");
+ propsMap.put("nested/prop4", "value4");
+ propsMap.put("prop1@Delete", "value1");
+ propsMap.put("nested/prop2@Delete", "value1");
+ try {
+ updateUser.updateUser(user1Session, user2.getID(), propsMap, new ArrayList<>());
+ updateGroup.updateGroup(user1Session, group1.getID(), propsMap, new ArrayList<>());
+ assertTrue("Expected pending changes in the jcr session", user1Session.hasPendingChanges());
+ user1Session.save();
+ } catch (RepositoryException e) {
+ logger.error("Did not expect RepositoryException when adding or deleting properties: " + e.getMessage(), e);
+ fail("Did not expect RepositoryException when adding or deleting properties: " + e.getMessage());
+ }
+ } finally {
+ if (user2 != null) {
+ deleteUser.deleteUser(adminSession, user2.getID(), new ArrayList<>());
+ }
+ }
}
/**
@@ -594,74 +602,74 @@
*/
@Test
public void canRemove() throws Exception {
- assertNotNull("Expected privilegesInfo to not be null", privilegesInfo);
-
- workaroundMissingGroupsPath();
-
- User user2 = null;
- Group group1 = null;
- try {
- user2 = createUser.createUser(adminSession, createUniqueName("user"), "testPwd", "testPwd",
- Collections.singletonMap("prop1", "value1"), new ArrayList<Modification>());
- assertNotNull("Expected user2 to not be null", user2);
+ assertNotNull("Expected privilegesInfo to not be null", privilegesInfo);
- group1 = createGroup.createGroup(adminSession, createUniqueName("group"),
- Collections.singletonMap("prop1", "value1"), new ArrayList<Modification>());
- assertNotNull("Expected group1 to not be null", group1);
+ workaroundMissingGroupsPath();
- // initially user can't do the operations
- assertFalse("Should not be allowed to remove user",
- privilegesInfo.canRemove(user1Session, user2.getID()));
- assertFalse("Should not be allowed to remove group",
- privilegesInfo.canRemove(user1Session, group1.getID()));
-
- // grant user1 rights to user2 profile
- Map<String, String> privileges = new HashMap<>();
- privileges.put(String.format("privilege@%s", Privilege.JCR_READ), "granted");
- modifyAce.modifyAce(adminSession, user2.getPath(), user1.getID(),
- privileges,
- "first");
- modifyAce.modifyAce(adminSession, group1.getPath(), user1.getID(),
- privileges,
- "first");
- assertFalse("Should not be allowed to remove user",
- privilegesInfo.canRemove(user1Session, user2.getID()));
- assertFalse("Should not be allowed to remove group",
- privilegesInfo.canRemove(user1Session, group1.getID()));
+ User user2 = null;
+ Group group1 = null;
+ try {
+ user2 = createUser.createUser(adminSession, createUniqueName("user"), "testPwd", "testPwd",
+ Collections.singletonMap("prop1", "value1"), new ArrayList<Modification>());
+ assertNotNull("Expected user2 to not be null", user2);
- privileges.put(String.format("privilege@%s", PrivilegeConstants.REP_USER_MANAGEMENT), "granted");
- modifyAce.modifyAce(adminSession, user2.getPath(), user1.getID(),
- privileges,
- "first");
- modifyAce.modifyAce(adminSession, group1.getPath(), user1.getID(),
- privileges,
- "first");
- assertTrue("Should be allowed to remove user",
- privilegesInfo.canRemove(user1Session, user2.getID()));
- assertTrue("Should be allowed to remove group",
- privilegesInfo.canRemove(user1Session, group1.getID()));
+ group1 = createGroup.createGroup(adminSession, createUniqueName("group"),
+ Collections.singletonMap("prop1", "value1"), new ArrayList<Modification>());
+ assertNotNull("Expected group1 to not be null", group1);
- // verify that the user can actually delete the user
- String user2Id = user2.getID();
- deleteUser.deleteUser(user1Session, user2Id, new ArrayList<>());
- user2 = null;
- // verify the user is no longer there
- UserManager um = AccessControlUtil.getUserManager(user1Session);
- assertNull("Expected user to be gone: " + user2Id, um.getAuthorizable(user2Id));
-
- // verify that the user can actually delete the group
- String group1Id = group1.getID();
- deleteGroup.deleteGroup(user1Session, group1Id, new ArrayList<>());
- group1 = null;
- assertNull("Expected group to be gone: " + group1Id, um.getAuthorizable(group1Id));
- } finally {
- if (user2 != null) {
- deleteUser.deleteUser(adminSession, user2.getID(), new ArrayList<>());
- }
- if (group1 != null) {
- deleteGroup.deleteGroup(adminSession, group1.getID(), new ArrayList<>());
- }
- }
+ // initially user can't do the operations
+ assertFalse("Should not be allowed to remove user",
+ privilegesInfo.canRemove(user1Session, user2.getID()));
+ assertFalse("Should not be allowed to remove group",
+ privilegesInfo.canRemove(user1Session, group1.getID()));
+
+ // grant user1 rights to user2 profile
+ Map<String, String> privileges = new HashMap<>();
+ privileges.put(String.format("privilege@%s", Privilege.JCR_READ), "granted");
+ modifyAce.modifyAce(adminSession, user2.getPath(), user1.getID(),
+ privileges,
+ "first");
+ modifyAce.modifyAce(adminSession, group1.getPath(), user1.getID(),
+ privileges,
+ "first");
+ assertFalse("Should not be allowed to remove user",
+ privilegesInfo.canRemove(user1Session, user2.getID()));
+ assertFalse("Should not be allowed to remove group",
+ privilegesInfo.canRemove(user1Session, group1.getID()));
+
+ privileges.put(String.format("privilege@%s", PrivilegeConstants.REP_USER_MANAGEMENT), "granted");
+ modifyAce.modifyAce(adminSession, user2.getPath(), user1.getID(),
+ privileges,
+ "first");
+ modifyAce.modifyAce(adminSession, group1.getPath(), user1.getID(),
+ privileges,
+ "first");
+ assertTrue("Should be allowed to remove user",
+ privilegesInfo.canRemove(user1Session, user2.getID()));
+ assertTrue("Should be allowed to remove group",
+ privilegesInfo.canRemove(user1Session, group1.getID()));
+
+ // verify that the user can actually delete the user
+ String user2Id = user2.getID();
+ deleteUser.deleteUser(user1Session, user2Id, new ArrayList<>());
+ user2 = null;
+ // verify the user is no longer there
+ UserManager um = AccessControlUtil.getUserManager(user1Session);
+ assertNull("Expected user to be gone: " + user2Id, um.getAuthorizable(user2Id));
+
+ // verify that the user can actually delete the group
+ String group1Id = group1.getID();
+ deleteGroup.deleteGroup(user1Session, group1Id, new ArrayList<>());
+ group1 = null;
+ assertNull("Expected group to be gone: " + group1Id, um.getAuthorizable(group1Id));
+ } finally {
+ if (user2 != null) {
+ deleteUser.deleteUser(adminSession, user2.getID(), new ArrayList<>());
+ }
+ if (group1 != null) {
+ deleteGroup.deleteGroup(adminSession, group1.getID(), new ArrayList<>());
+ }
+ }
}
/**
@@ -670,52 +678,197 @@
*/
@Test
public void canUpdateGroupMembers() throws Exception {
- assertNotNull("Expected privilegesInfo to not be null", privilegesInfo);
-
- workaroundMissingGroupsPath();
-
- Group group1 = null;
- try {
- group1 = createGroup.createGroup(adminSession, createUniqueName("group"),
- Collections.singletonMap("prop1", "value1"), new ArrayList<Modification>());
- assertNotNull("Expected group1 to not be null", group1);
+ assertNotNull("Expected privilegesInfo to not be null", privilegesInfo);
- // initially user can't do the operations
- assertFalse("Should not be allowed to update group members",
- privilegesInfo.canUpdateGroupMembers(user1Session, group1.getID()));
-
- // grant user1 rights to group1 profile
- Map<String, String> privileges = new HashMap<>();
- privileges.put(String.format("privilege@%s", Privilege.JCR_READ), "granted");
- modifyAce.modifyAce(adminSession, group1.getPath(), user1.getID(),
- privileges,
- "first");
- assertFalse("Should not be allowed to update group members",
- privilegesInfo.canUpdateGroupMembers(user1Session, group1.getID()));
+ workaroundMissingGroupsPath();
- privileges.put(String.format("privilege@%s", PrivilegeConstants.REP_USER_MANAGEMENT), "granted");
- modifyAce.modifyAce(adminSession, group1.getPath(), user1.getID(),
- privileges,
- "first");
- assertTrue("Should be allowed to update group members",
- privilegesInfo.canUpdateGroupMembers(user1Session, group1.getID()));
+ Group group1 = null;
+ try {
+ group1 = createGroup.createGroup(adminSession, createUniqueName("group"),
+ Collections.singletonMap("prop1", "value1"), new ArrayList<Modification>());
+ assertNotNull("Expected group1 to not be null", group1);
- // verify that the user can actually change the group members
- try {
- Map<String, Object> propsMap = new HashMap<>();
- propsMap.put(":member", user1.getID());
- updateGroup.updateGroup(user1Session, group1.getID(), propsMap, new ArrayList<>());
- assertTrue("Expected pending changes in the jcr session", user1Session.hasPendingChanges());
- user1Session.save();
- } catch (RepositoryException e) {
- logger.error("Did not expect RepositoryException when adding member to group: " + e.getMessage(), e);
- fail("Did not expect RepositoryException when adding member to group: " + e.getMessage());
- }
- } finally {
- if (group1 != null) {
- deleteGroup.deleteGroup(adminSession, group1.getID(), new ArrayList<>());
- }
- }
+ // initially user can't do the operations
+ assertFalse("Should not be allowed to update group members",
+ privilegesInfo.canUpdateGroupMembers(user1Session, group1.getID()));
+
+ // grant user1 rights to group1 profile
+ Map<String, String> privileges = new HashMap<>();
+ privileges.put(String.format("privilege@%s", Privilege.JCR_READ), "granted");
+ modifyAce.modifyAce(adminSession, group1.getPath(), user1.getID(),
+ privileges,
+ "first");
+ assertFalse("Should not be allowed to update group members",
+ privilegesInfo.canUpdateGroupMembers(user1Session, group1.getID()));
+
+ privileges.put(String.format("privilege@%s", PrivilegeConstants.REP_USER_MANAGEMENT), "granted");
+ modifyAce.modifyAce(adminSession, group1.getPath(), user1.getID(),
+ privileges,
+ "first");
+ assertTrue("Should be allowed to update group members",
+ privilegesInfo.canUpdateGroupMembers(user1Session, group1.getID()));
+
+ // verify that the user can actually change the group members
+ try {
+ Map<String, Object> propsMap = new HashMap<>();
+ propsMap.put(":member", user1.getID());
+ updateGroup.updateGroup(user1Session, group1.getID(), propsMap, new ArrayList<>());
+ assertTrue("Expected pending changes in the jcr session", user1Session.hasPendingChanges());
+ user1Session.save();
+ } catch (RepositoryException e) {
+ logger.error("Did not expect RepositoryException when adding member to group: " + e.getMessage(), e);
+ fail("Did not expect RepositoryException when adding member to group: " + e.getMessage());
+ }
+ } finally {
+ if (group1 != null) {
+ deleteGroup.deleteGroup(adminSession, group1.getID(), new ArrayList<>());
+ }
+ }
}
-
+
+ protected void configMinimumUserPrivileges(User user) throws RepositoryException {
+ //change the ACE for the user home folder to the minimum privileges
+ // and without rep:userManagement
+ deleteAces.deleteAces(adminSession, user.getPath(), new String[] {user.getID()});
+ Map<String, String> privileges = new HashMap<>();
+ privileges.put(String.format("privilege@%s", Privilege.JCR_READ), "granted");
+ privileges.put(String.format("privilege@%s", PrivilegeConstants.REP_ALTER_PROPERTIES), "granted");
+ modifyAce.modifyAce(adminSession, user.getPath(), user.getID(),
+ privileges,
+ "first");
+ if (adminSession.hasPendingChanges()) {
+ adminSession.save();
+ }
+ }
+
+ /**
+ * SLING-9814 Checks whether the current user has been granted privileges
+ * to disable a user.
+ */
+ @Test
+ public void canDisableUser() throws Exception {
+ assertNotNull("Expected privilegesInfo to not be null", privilegesInfo);
+
+ User user2 = null;
+ try {
+ // setup the user privileges
+ configMinimumUserPrivileges(user1);
+
+ // create another test user
+ user2 = createUser.createUser(adminSession, createUniqueName("user"), "testPwd", "testPwd",
+ Collections.singletonMap("prop1", "value1"), new ArrayList<Modification>());
+ assertNotNull("Expected user2 to not be null", user2);
+ // setup the user privileges
+ configMinimumUserPrivileges(user2);
+
+ // initially user can't do the operations
+ assertFalse("Should not be allowed to disable yourself",
+ privilegesInfo.canDisable(user1Session, user1.getID()));
+ assertFalse("Should not be allowed to disable user",
+ privilegesInfo.canDisable(user1Session, user2.getID()));
+
+ // grant user1 rights to user2 profile
+ Map<String, String> privileges = new HashMap<>();
+ privileges.put(String.format("privilege@%s", Privilege.JCR_READ), "granted");
+ privileges.put(String.format("privilege@%s", PrivilegeConstants.REP_USER_MANAGEMENT), "granted");
+ modifyAce.modifyAce(adminSession, user2.getPath(), user1.getID(),
+ privileges,
+ "first");
+ assertTrue("Should be allowed to disable user",
+ privilegesInfo.canDisable(user1Session, user2.getID()));
+
+ // verify that the user can actually disable the other user
+ Map<String, Object> propsMap = new HashMap<>();
+ propsMap.put(":disabled", "true");
+ propsMap.put(":disabledReason", "Just a test");
+ try {
+ updateUser.updateUser(user1Session, user2.getID(), propsMap, new ArrayList<>());
+ assertTrue("Expected pending changes in the jcr session", user1Session.hasPendingChanges());
+ user1Session.save();
+ } catch (RepositoryException e) {
+ logger.error("Did not expect RepositoryException when disabling the user: " + e.getMessage(), e);
+ fail("Did not expect RepositoryException when disabling the user: " + e.getMessage());
+ }
+ } finally {
+ if (user2 != null) {
+ deleteUser.deleteUser(adminSession, user2.getID(), new ArrayList<>());
+ }
+ }
+ }
+
+ /**
+ * SLING-9814 Checks whether the current user has been granted privileges
+ * to change a user's password.
+ */
+ @Test
+ public void canChangePassword() throws Exception {
+ assertNotNull("Expected privilegesInfo to not be null", privilegesInfo);
+
+ User user2 = null;
+ try {
+ // create another test user
+ user2 = createUser.createUser(adminSession, createUniqueName("user"), "testPwd", "testPwd",
+ Collections.singletonMap("prop1", "value1"), new ArrayList<Modification>());
+ assertNotNull("Expected user2 to not be null", user2);
+
+ // initially user can't do the operations
+ assertFalse("Should not be allowed to change the user password",
+ privilegesInfo.canChangePassword(user1Session, user2.getID()));
+
+ // grant user1 rights to user2 profile
+ Map<String, String> privileges = new HashMap<>();
+ privileges.put(String.format("privilege@%s", Privilege.JCR_READ), "granted");
+ privileges.put(String.format("privilege@%s", PrivilegeConstants.REP_USER_MANAGEMENT), "granted");
+ modifyAce.modifyAce(adminSession, user2.getPath(), user1.getID(),
+ privileges,
+ "first");
+ assertTrue("Should be allowed to change the user password user",
+ privilegesInfo.canChangePassword(user1Session, user2.getID()));
+
+ // verify that the user can actually change the password of the other user
+ try {
+ changeUserPassword.changePassword(user1Session, user2.getID(), "testPwd", "newPassword", "newPassword", new ArrayList<>());
+ assertTrue("Expected pending changes in the jcr session", user1Session.hasPendingChanges());
+ user1Session.save();
+ } catch (RepositoryException e) {
+ logger.error("Did not expect RepositoryException when changing the user password: " + e.getMessage(), e);
+ fail("Did not expect RepositoryException when changing the user password: " + e.getMessage());
+ }
+ } finally {
+ if (user2 != null) {
+ deleteUser.deleteUser(adminSession, user2.getID(), new ArrayList<>());
+ }
+ }
+ }
+
+ /**
+ * SLING-9814 Checks whether the current user has been granted privileges
+ * to change the anonymous user's password.
+ */
+ @Test
+ public void cannotChangePassword_for_anonymous() throws Exception {
+ assertNotNull("Expected privilegesInfo to not be null", privilegesInfo);
+
+ // anonymous user has no password to change
+ assertFalse("Should not be allowed to change the user password",
+ privilegesInfo.canChangePassword(user1Session, "anonymous"));
+ assertFalse("Should not be allowed to change the user password",
+ privilegesInfo.canChangePassword(adminSession, "anonymous"));
+ }
+
+ /**
+ * SLING-9814 Checks whether the current user has been granted privileges
+ * to change the anonymous user's password.
+ */
+ @Test
+ public void cannotChangePassword_for_service_user() throws Exception {
+ assertNotNull("Expected privilegesInfo to not be null", privilegesInfo);
+
+ // service user has no password to change
+ assertFalse("Should not be allowed to change the user password",
+ privilegesInfo.canChangePassword(user1Session, "sling-jcr-usermanager"));
+ assertFalse("Should not be allowed to change the user password",
+ privilegesInfo.canChangePassword(adminSession, "sling-jcr-usermanager"));
+ }
+
}
diff --git a/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/post/ChangeUserPasswordIT.java b/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/post/ChangeUserPasswordIT.java
index 007575f..782d683 100644
--- a/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/post/ChangeUserPasswordIT.java
+++ b/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/post/ChangeUserPasswordIT.java
@@ -19,6 +19,7 @@
package org.apache.sling.jcr.jackrabbit.usermanager.it.post;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -41,7 +42,9 @@
import org.apache.jackrabbit.api.security.user.User;
import org.apache.jackrabbit.oak.api.CommitFailedException;
import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants;
+import org.apache.sling.jackrabbit.usermanager.AuthorizablePrivilegesInfo;
import org.apache.sling.jackrabbit.usermanager.ChangeUserPassword;
+import org.apache.sling.jackrabbit.usermanager.CreateGroup;
import org.apache.sling.jackrabbit.usermanager.CreateUser;
import org.apache.sling.jackrabbit.usermanager.DeleteUser;
import org.apache.sling.jcr.api.SlingRepository;
@@ -79,17 +82,20 @@
@Inject
protected BundleContext bundleContext;
-
+
@Inject
protected SlingRepository repository;
@Inject
protected ConfigurationAdmin configAdmin;
-
+
@Inject
private CreateUser createUser;
@Inject
+ private CreateGroup createGroup;
+
+ @Inject
private ModifyAce modifyAce;
@Inject
@@ -98,6 +104,9 @@
@Inject
private DeleteUser deleteUser;
+ @Inject
+ private AuthorizablePrivilegesInfo privilegesInfo;
+
@Rule
public TestName testName = new TestName();
@@ -117,40 +126,40 @@
adminSession = repository.login(new SimpleCredentials("admin", "admin".toCharArray()));
assertNotNull("Expected adminSession to not be null", adminSession);
- user1 = createUser.createUser(adminSession, createUniqueName("user"), "testPwd", "testPwd",
+ user1 = createUser.createUser(adminSession, createUniqueName("user"), "testPwd", "testPwd",
Collections.emptyMap(), new ArrayList<Modification>());
assertNotNull("Expected user1 to not be null", user1);
-
+
user1Session = repository.login(new SimpleCredentials(user1.getID(), "testPwd".toCharArray()));
assertNotNull("Expected user1Session to not be null", user1Session);
-
+
//change the ACE for the user home folder to the minimum privileges
// and without rep:userManagement
deleteAces.deleteAces(adminSession, user1.getPath(), new String[] {user1.getID()});
Map<String, String> privileges = new HashMap<>();
privileges.put(String.format("privilege@%s", Privilege.JCR_READ), "granted");
privileges.put(String.format("privilege@%s", PrivilegeConstants.REP_ALTER_PROPERTIES), "granted");
- modifyAce.modifyAce(adminSession, user1.getPath(), user1.getID(),
- privileges,
+ modifyAce.modifyAce(adminSession, user1.getPath(), user1.getID(),
+ privileges,
"first");
if (adminSession.hasPendingChanges()) {
- adminSession.save();
+ adminSession.save();
}
}
@After
public void teardown() {
- try {
- adminSession.refresh(false);
- if (user1 != null) {
- deleteUser.deleteUser(adminSession, user1.getID(), new ArrayList<>());
- }
- if (adminSession.hasPendingChanges()) {
- adminSession.save();
- }
- } catch (RepositoryException e) {
- logger.warn("Failed to delete user: " + e.getMessage(), e);
- }
+ try {
+ adminSession.refresh(false);
+ if (user1 != null) {
+ deleteUser.deleteUser(adminSession, user1.getID(), new ArrayList<>());
+ }
+ if (adminSession.hasPendingChanges()) {
+ adminSession.save();
+ }
+ } catch (RepositoryException e) {
+ logger.warn("Failed to delete user: " + e.getMessage(), e);
+ }
user1Session.logout();
adminSession.logout();
@@ -172,18 +181,23 @@
// update the service configuration to ensure the option is enabled
Dictionary<String, Object> newServiceProps = replaceConfigProp(originalServiceProps, "alwaysAllowSelfChangePassword", Boolean.TRUE);
configuration.update(newServiceProps);
- new WaitForServiceUpdated(5000, 100, bundleContext, ChangeUserPassword.class,
+ new WaitForServiceUpdated(5000, 100, bundleContext, ChangeUserPassword.class,
"alwaysAllowSelfChangePassword", Boolean.TRUE);
-
+
serviceReference = bundleContext.getServiceReference(ChangeUserPassword.class);
assertEquals(Boolean.TRUE, serviceReference.getProperty("alwaysAllowSelfChangePassword"));
ChangeUserPassword changeUserPassword = bundleContext.getService(serviceReference);
assertNotNull(changeUserPassword);
- changeUserPassword.changePassword(user1Session,
- user1.getID(),
- "testPwd",
- "testPwdChanged",
- "testPwdChanged",
+
+ // user can do the operation
+ assertTrue("Should be allowed to change the user password",
+ privilegesInfo.canChangePassword(user1Session, user1.getID()));
+
+ changeUserPassword.changePassword(user1Session,
+ user1.getID(),
+ "testPwd",
+ "testPwdChanged",
+ "testPwdChanged",
new ArrayList<>());
try {
user1Session.save();
@@ -199,7 +213,7 @@
//put the original config back
configuration.update(originalServiceProps);
- new WaitForServiceUpdated(5000, 100, bundleContext, ChangeUserPassword.class, "alwaysAllowSelfChangePassword",
+ new WaitForServiceUpdated(5000, 100, bundleContext, ChangeUserPassword.class, "alwaysAllowSelfChangePassword",
originalServiceProps == null ? null :originalServiceProps.get("alwaysAllowSelfChangePassword"));
}
}
@@ -216,18 +230,23 @@
// update the service configuration to ensure the option is disabled
Dictionary<String, Object> newServiceProps = replaceConfigProp(originalServiceProps, "alwaysAllowSelfChangePassword", Boolean.FALSE);
configuration.update(newServiceProps);
- new WaitForServiceUpdated(5000, 100, bundleContext, ChangeUserPassword.class,
+ new WaitForServiceUpdated(5000, 100, bundleContext, ChangeUserPassword.class,
"alwaysAllowSelfChangePassword", Boolean.FALSE);
-
+
serviceReference = bundleContext.getServiceReference(ChangeUserPassword.class);
assertEquals(Boolean.FALSE, serviceReference.getProperty("alwaysAllowSelfChangePassword"));
ChangeUserPassword changeUserPassword = bundleContext.getService(serviceReference);
assertNotNull(changeUserPassword);
- changeUserPassword.changePassword(user1Session,
- user1.getID(),
- "testPwd",
- "testPwdChanged",
- "testPwdChanged",
+
+ // user can't do the operation
+ assertFalse("Should not be allowed to change the user password",
+ privilegesInfo.canChangePassword(user1Session, user1.getID()));
+
+ changeUserPassword.changePassword(user1Session,
+ user1.getID(),
+ "testPwd",
+ "testPwdChanged",
+ "testPwdChanged",
new ArrayList<>());
assertTrue(user1Session.hasPendingChanges());
try {
@@ -244,12 +263,179 @@
// done with this.
bundleContext.ungetService(serviceReference);
}
-
+
//put the original config back
configuration.update(originalServiceProps);
- new WaitForServiceUpdated(5000, 100, bundleContext, ChangeUserPassword.class, "alwaysAllowSelfChangePassword",
+ new WaitForServiceUpdated(5000, 100, bundleContext, ChangeUserPassword.class, "alwaysAllowSelfChangePassword",
originalServiceProps == null ? null :originalServiceProps.get("alwaysAllowSelfChangePassword"));
}
}
+ /**
+ * test changing your own password without sending the old password is not allowed
+ */
+ @Test
+ public void changePasswordAsSelfWithoutOldPasswordFails() throws Exception {
+ org.osgi.service.cm.Configuration configuration = configAdmin.getConfiguration("org.apache.sling.jackrabbit.usermanager.impl.post.ChangeUserPasswordServlet", null);
+ Dictionary<String, Object> originalServiceProps = configuration.getProperties();
+ ServiceReference<ChangeUserPassword> serviceReference = null;
+ try {
+ // update the service configuration to ensure the option is enabled
+ Dictionary<String, Object> newServiceProps = replaceConfigProp(originalServiceProps, "alwaysAllowSelfChangePassword", Boolean.TRUE);
+ configuration.update(newServiceProps);
+ new WaitForServiceUpdated(5000, 100, bundleContext, ChangeUserPassword.class,
+ "alwaysAllowSelfChangePassword", Boolean.TRUE);
+
+ serviceReference = bundleContext.getServiceReference(ChangeUserPassword.class);
+ assertEquals(Boolean.TRUE, serviceReference.getProperty("alwaysAllowSelfChangePassword"));
+ ChangeUserPassword changeUserPassword = bundleContext.getService(serviceReference);
+ assertNotNull(changeUserPassword);
+
+ // user can do the operation
+ assertTrue("Should be allowed to change the user password",
+ privilegesInfo.canChangePassword(user1Session, user1.getID()));
+
+ // no oldPassword submitted
+ try {
+ changeUserPassword.changePassword(user1Session,
+ user1.getID(),
+ null,
+ "testPwdChanged",
+ "testPwdChanged",
+ new ArrayList<>());
+ fail("Expected a RepositoryException when changing user passsword.");
+ } catch (RepositoryException e) {
+ assertEquals("Old Password was not submitted", e.getMessage());
+ user1Session.refresh(false);
+ }
+
+ // empty oldPassword submitted
+ try {
+ changeUserPassword.changePassword(user1Session,
+ user1.getID(),
+ "",
+ "testPwdChanged2",
+ "testPwdChanged2",
+ new ArrayList<>());
+ fail("Expected a RepositoryException when changing user passsword.");
+ } catch (RepositoryException e) {
+ assertEquals("Old Password was not submitted", e.getMessage());
+ user1Session.refresh(false);
+ }
+
+ } finally {
+ if (serviceReference != null) {
+ // done with this.
+ bundleContext.ungetService(serviceReference);
+ }
+
+ //put the original config back
+ configuration.update(originalServiceProps);
+ new WaitForServiceUpdated(5000, 100, bundleContext, ChangeUserPassword.class, "alwaysAllowSelfChangePassword",
+ originalServiceProps == null ? null :originalServiceProps.get("alwaysAllowSelfChangePassword"));
+ }
+ }
+
+ /**
+ * test changing a user's password without sending the old password is allowed if the current
+ * user is a member of the UserAdmin group.
+ */
+ @Test
+ public void changePasswordAsUserAdminMemberWithoutOldPassword() throws Exception {
+ User user2 = null;
+ ServiceReference<ChangeUserPassword> serviceReference = null;
+ try {
+ // create a second user to attempt the change password on
+ user2 = createUser.createUser(adminSession, createUniqueName("user"), "testPwd", "testPwd",
+ Collections.emptyMap(), new ArrayList<Modification>());
+ if (adminSession.hasPendingChanges()) {
+ adminSession.save();
+ }
+
+ // figure out what the user admin group name has been configured as
+ serviceReference = bundleContext.getServiceReference(ChangeUserPassword.class);
+ String userAdminGroup = (String)serviceReference.getProperty("user.admin.group.name");
+ if (userAdminGroup == null || userAdminGroup.isEmpty()) {
+ userAdminGroup = "UserAdmin"; // fallback to the default
+ }
+
+ // add user1 to the UserAdmin group
+ createGroup.createGroup(adminSession, userAdminGroup,
+ Collections.singletonMap(":member", user1.getID()), new ArrayList<>());
+ if (adminSession.hasPendingChanges()) {
+ adminSession.save();
+ }
+
+ //make sure the UserAdmin group has the expected privileges granted
+ Map<String, String> privileges = new HashMap<>();
+ privileges.put(String.format("privilege@%s", Privilege.JCR_READ), "granted");
+ privileges.put(String.format("privilege@%s", Privilege.JCR_READ_ACCESS_CONTROL), "granted");
+ privileges.put(String.format("privilege@%s", Privilege.JCR_MODIFY_ACCESS_CONTROL), "granted");
+ privileges.put(String.format("privilege@%s", PrivilegeConstants.REP_WRITE), "granted");
+ privileges.put(String.format("privilege@%s", PrivilegeConstants.REP_USER_MANAGEMENT), "granted");
+ modifyAce.modifyAce(adminSession, user2.getPath(), userAdminGroup,
+ privileges,
+ "first");
+
+
+ // create a fresh session so changes from the adminSession are picked up
+ user1Session.logout();
+ user1Session = repository.login(new SimpleCredentials(user1.getID(), "testPwd".toCharArray()));
+ assertNotNull("Expected user1Session to not be null", user1Session);
+
+ ChangeUserPassword changeUserPassword = bundleContext.getService(serviceReference);
+ assertNotNull(changeUserPassword);
+
+ // user can do the operation
+ assertTrue("Should be allowed to change the user password",
+ privilegesInfo.canChangePassword(user1Session, user2.getID()));
+
+ // no oldPassword submitted
+ try {
+ changeUserPassword.changePassword(user1Session,
+ user2.getID(),
+ null,
+ "testPwdChanged",
+ "testPwdChanged",
+ new ArrayList<>());
+ } catch (RepositoryException e) {
+ fail("Did not expect a RepositoryException when changing user passsword.");
+ }
+ try {
+ user1Session.save();
+ } catch (AccessDeniedException e) {
+ logger.error("Did not expect AccessDeniedException when changing user passsword: " + e.getMessage(), e);
+ fail("Did not expect AccessDeniedException when changing user passsword: " + e.getMessage());
+ }
+
+ // empty oldPassword submitted
+ try {
+ changeUserPassword.changePassword(user1Session,
+ user2.getID(),
+ "",
+ "testPwdChanged2",
+ "testPwdChanged2",
+ new ArrayList<>());
+ } catch (RepositoryException e) {
+ fail("Did not expect a RepositoryException when changing user passsword.");
+ }
+ try {
+ user1Session.save();
+ } catch (AccessDeniedException e) {
+ logger.error("Did not expect AccessDeniedException when changing user passsword: " + e.getMessage(), e);
+ fail("Did not expect AccessDeniedException when changing user passsword: " + e.getMessage());
+ }
+
+ } finally {
+ if (user2 != null) {
+ deleteUser.deleteUser(adminSession, user2.getID(), new ArrayList<>());
+ }
+
+ if (serviceReference != null) {
+ // done with this.
+ bundleContext.ungetService(serviceReference);
+ }
+ }
+ }
+
}