You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by en...@apache.org on 2018/09/07 05:33:24 UTC
[sling-org-apache-sling-jcr-jackrabbit-usermanager] branch master
updated: SLING-7886 AuthorizablePrivilegesInfo returns incorrect
information for non-admin user who has been granted sufficient privileges
to do User/Group Management activites SLING-7887 The CreateUserServlet
should allow non-admin users to create a user if sufficient privileges have
been granted
This is an automated email from the ASF dual-hosted git repository.
enorman pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-jackrabbit-usermanager.git
The following commit(s) were added to refs/heads/master by this push:
new 141637a SLING-7886 AuthorizablePrivilegesInfo returns incorrect information for non-admin user who has been granted sufficient privileges to do User/Group Management activites SLING-7887 The CreateUserServlet should allow non-admin users to create a user if sufficient privileges have been granted
141637a is described below
commit 141637a6afaae62f593eb45ab4721b5b356e3182
Author: Eric Norman <en...@apache.org>
AuthorDate: Thu Sep 6 22:33:08 2018 -0700
SLING-7886 AuthorizablePrivilegesInfo returns incorrect information for
non-admin user who has been granted sufficient privileges to do
User/Group Management activites
SLING-7887 The CreateUserServlet should allow non-admin users to create
a user if sufficient privileges have been granted
---
pom.xml | 7 +-
.../impl/AuthorizablePrivilegesInfoImpl.java | 128 ++++++++++++++++-----
.../usermanager/impl/post/CreateUserServlet.java | 37 ++++--
3 files changed, 134 insertions(+), 38 deletions(-)
diff --git a/pom.xml b/pom.xml
index ebe1633..45ee512 100644
--- a/pom.xml
+++ b/pom.xml
@@ -134,6 +134,11 @@
<version>1.0.0</version>
<scope>provided</scope>
</dependency>
-
+ <dependency>
+ <groupId>org.apache.jackrabbit</groupId>
+ <artifactId>oak-core</artifactId>
+ <version>1.6.7</version>
+ <optional>true</optional>
+ </dependency>
</dependencies>
</project>
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 54486b8..86d7430 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
@@ -19,24 +19,28 @@ package org.apache.sling.jackrabbit.usermanager.impl;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
-import java.util.Collection;
import java.util.Map;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
-import javax.servlet.Servlet;
+import javax.jcr.security.AccessControlManager;
+import javax.jcr.security.Privilege;
import org.apache.jackrabbit.api.security.user.Authorizable;
import org.apache.jackrabbit.api.security.user.User;
import org.apache.jackrabbit.api.security.user.UserManager;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants;
+import org.apache.jackrabbit.oak.spi.security.user.UserConfiguration;
+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.CreateUser;
import org.apache.sling.jcr.base.util.AccessControlUtil;
import org.osgi.framework.BundleContext;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferenceCardinality;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -87,7 +91,31 @@ public class AuthorizablePrivilegesInfoImpl implements AuthorizablePrivilegesInf
* 'Group administrator' group name.
*/
static final String PAR_GROUP_ADMIN_GROUP_NAME = "group.admin.group.name";
+
+ private String usersPath;
+ private String groupsPath;
+ private boolean selfRegistrationEnabled;
+ @Reference(cardinality=ReferenceCardinality.OPTIONAL)
+ private void bindUserConfiguration(UserConfiguration userConfig, Map<String, Object> properties) {
+ usersPath = (String)properties.get(UserConstants.PARAM_USER_PATH);
+ groupsPath = (String)properties.get(UserConstants.PARAM_GROUP_PATH);
+ }
+ @SuppressWarnings("unused")
+ private void unbindUserConfiguration(UserConfiguration userConfig, Map<String, Object> properties) {
+ usersPath = null;
+ groupsPath = null;
+ }
+
+ @Reference(cardinality=ReferenceCardinality.OPTIONAL)
+ private void bindCreateUser(CreateUser createUser, Map<String, Object> properties) {
+ selfRegistrationEnabled = Boolean.TRUE.equals(properties.get("self.registration.enabled"));
+ }
+ @SuppressWarnings("unused")
+ private void unbindCreateUser(CreateUser createUser, Map<String, Object> properties) {
+ selfRegistrationEnabled = false;
+ }
+
/* (non-Javadoc)
* @see org.apache.sling.jackrabbit.usermanager.AuthorizablePrivilegesInfo#canAddGroup(javax.jcr.Session)
*/
@@ -101,6 +129,19 @@ public class AuthorizablePrivilegesInfoImpl implements AuthorizablePrivilegesInf
return true; //admin user has full control
}
}
+
+ if (groupsPath != null) {
+ //check if the non-admin user has sufficient rights on the home folder
+ AccessControlManager acm = jcrSession.getAccessControlManager();
+ boolean hasRights = acm.hasPrivileges(groupsPath, new Privilege[] {
+ acm.privilegeFromName(Privilege.JCR_READ),
+ acm.privilegeFromName(Privilege.JCR_READ_ACCESS_CONTROL),
+ acm.privilegeFromName(Privilege.JCR_MODIFY_ACCESS_CONTROL),
+ acm.privilegeFromName(PrivilegeConstants.REP_WRITE),
+ acm.privilegeFromName(PrivilegeConstants.REP_USER_MANAGEMENT)
+ });
+ return hasRights;
+ }
} catch (RepositoryException e) {
log.warn("Failed to determine if {} can add a new group", jcrSession.getUserID());
}
@@ -113,23 +154,9 @@ public class AuthorizablePrivilegesInfoImpl implements AuthorizablePrivilegesInf
public boolean canAddUser(Session jcrSession) {
try {
//if self-registration is enabled, then anyone can create a user
- if (bundleContext != null) {
- String filter = "(&(sling.servlet.resourceTypes=sling/users)(|(sling.servlet.methods=POST)(sling.servlet.selectors=create)))";
- Collection<ServiceReference<Servlet>> serviceReferences = bundleContext.getServiceReferences(Servlet.class, filter);
- if (serviceReferences != null) {
- String propName = "self.registration.enabled";
- for (ServiceReference<Servlet> serviceReference : serviceReferences) {
- Object propValue = serviceReference.getProperty(propName);
- if (propValue != null) {
- boolean selfRegEnabled = Boolean.TRUE.equals(propValue);
- if (selfRegEnabled) {
- return true;
- }
- break;
- }
- }
- }
- }
+ if (selfRegistrationEnabled) {
+ return true;
+ }
UserManager userManager = AccessControlUtil.getUserManager(jcrSession);
Authorizable currentUser = userManager.getAuthorizable(jcrSession.getUserID());
@@ -138,10 +165,21 @@ public class AuthorizablePrivilegesInfoImpl implements AuthorizablePrivilegesInf
return true; //admin user has full control
}
}
+
+ if (usersPath != null) {
+ //check if the non-admin user has sufficient rights on the home folder
+ AccessControlManager acm = jcrSession.getAccessControlManager();
+ boolean hasRights = acm.hasPrivileges(usersPath, new Privilege[] {
+ acm.privilegeFromName(Privilege.JCR_READ),
+ acm.privilegeFromName(Privilege.JCR_READ_ACCESS_CONTROL),
+ acm.privilegeFromName(Privilege.JCR_MODIFY_ACCESS_CONTROL),
+ acm.privilegeFromName(PrivilegeConstants.REP_WRITE),
+ acm.privilegeFromName(PrivilegeConstants.REP_USER_MANAGEMENT)
+ });
+ return hasRights;
+ }
} catch (RepositoryException e) {
log.warn("Failed to determine if {} can add a new user", jcrSession.getUserID());
- } catch (InvalidSyntaxException e) {
- log.warn("Failed to determine if {} can add a new user", jcrSession.getUserID());
}
return false;
}
@@ -157,6 +195,19 @@ public class AuthorizablePrivilegesInfoImpl implements AuthorizablePrivilegesInf
if (((User)currentUser).isAdmin()) {
return true; //admin user has full control
}
+
+ if (usersPath != null) {
+ //check if the non-admin user has sufficient rights on the home folder
+ AccessControlManager acm = jcrSession.getAccessControlManager();
+ boolean hasRights = acm.hasPrivileges("/home/users", new Privilege[] {
+ acm.privilegeFromName(Privilege.JCR_READ),
+ acm.privilegeFromName(Privilege.JCR_READ_ACCESS_CONTROL),
+ acm.privilegeFromName(Privilege.JCR_MODIFY_ACCESS_CONTROL),
+ acm.privilegeFromName(PrivilegeConstants.REP_WRITE),
+ acm.privilegeFromName(PrivilegeConstants.REP_USER_MANAGEMENT)
+ });
+ return hasRights;
+ }
} catch (RepositoryException e) {
log.warn("Failed to determine if {} can remove authorizable {}", jcrSession.getUserID(), principalId);
}
@@ -174,6 +225,19 @@ public class AuthorizablePrivilegesInfoImpl implements AuthorizablePrivilegesInf
if (((User)currentUser).isAdmin()) {
return true; //admin user has full control
}
+
+ if (groupsPath != null) {
+ //check if the non-admin user has sufficient rights on the home folder
+ AccessControlManager acm = jcrSession.getAccessControlManager();
+ boolean hasRights = acm.hasPrivileges(groupsPath, new Privilege[] {
+ acm.privilegeFromName(Privilege.JCR_READ),
+ acm.privilegeFromName(Privilege.JCR_READ_ACCESS_CONTROL),
+ acm.privilegeFromName(Privilege.JCR_MODIFY_ACCESS_CONTROL),
+ acm.privilegeFromName(PrivilegeConstants.REP_WRITE),
+ acm.privilegeFromName(PrivilegeConstants.REP_USER_MANAGEMENT)
+ });
+ return hasRights;
+ }
} catch (RepositoryException e) {
log.warn("Failed to determine if {} can remove authorizable {}", jcrSession.getUserID(), groupId);
}
@@ -196,6 +260,20 @@ public class AuthorizablePrivilegesInfoImpl implements AuthorizablePrivilegesInf
if (((User)currentUser).isAdmin()) {
return true; //admin user has full control
}
+
+ String path = currentUser.isGroup() ? groupsPath : usersPath;
+ if (path != null) {
+ //check if the non-admin user has sufficient rights on the home folder
+ AccessControlManager acm = jcrSession.getAccessControlManager();
+ boolean hasRights = acm.hasPrivileges(path, new Privilege[] {
+ acm.privilegeFromName(Privilege.JCR_READ),
+ acm.privilegeFromName(Privilege.JCR_READ_ACCESS_CONTROL),
+ acm.privilegeFromName(Privilege.JCR_MODIFY_ACCESS_CONTROL),
+ acm.privilegeFromName(PrivilegeConstants.REP_WRITE),
+ acm.privilegeFromName(PrivilegeConstants.REP_USER_MANAGEMENT)
+ });
+ return hasRights;
+ }
} catch (RepositoryException e) {
log.warn("Failed to determine if {} can remove authorizable {}", jcrSession.getUserID(), principalId);
}
@@ -205,16 +283,12 @@ public class AuthorizablePrivilegesInfoImpl implements AuthorizablePrivilegesInf
// ---------- SCR Integration ----------------------------------------------
- //keep track of the bundle context
- private BundleContext bundleContext;
@Activate
protected void activate(BundleContext bundleContext, Map<String, Object> properties)
throws InvalidKeyException, NoSuchAlgorithmException,
IllegalStateException, UnsupportedEncodingException {
- this.bundleContext = bundleContext;
-
String userAdminGroupName = OsgiUtil.toString(properties.get(PAR_USER_ADMIN_GROUP_NAME), null);
if ( userAdminGroupName != null && ! DEFAULT_USER_ADMIN_GROUP_NAME.equals(userAdminGroupName)) {
log.warn("Configuration setting for {} is deprecated and will not have any effect", PAR_USER_ADMIN_GROUP_NAME);
diff --git a/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/post/CreateUserServlet.java b/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/post/CreateUserServlet.java
index 7fae917..da80ed5 100644
--- a/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/post/CreateUserServlet.java
+++ b/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/post/CreateUserServlet.java
@@ -22,12 +22,16 @@ import java.util.Map;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
+import javax.jcr.security.AccessControlManager;
+import javax.jcr.security.Privilege;
import javax.servlet.Servlet;
import org.apache.jackrabbit.api.security.user.Authorizable;
-import org.apache.jackrabbit.api.security.user.Group;
import org.apache.jackrabbit.api.security.user.User;
import org.apache.jackrabbit.api.security.user.UserManager;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants;
+import org.apache.jackrabbit.oak.spi.security.user.UserConfiguration;
+import org.apache.jackrabbit.oak.spi.security.user.UserConstants;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.commons.osgi.OsgiUtil;
import org.apache.sling.jackrabbit.usermanager.CreateUser;
@@ -132,6 +136,17 @@ public class CreateUserServlet extends AbstractAuthorizablePostServlet implement
@Reference
private SlingRepository repository;
+ private String usersPath;
+
+ @Reference(cardinality=ReferenceCardinality.OPTIONAL)
+ private void bindUserConfiguration(UserConfiguration userConfig, Map<String, Object> properties) {
+ usersPath = (String)properties.get(UserConstants.PARAM_USER_PATH);
+ }
+ @SuppressWarnings("unused")
+ private void unbindUserConfiguration(UserConfiguration userConfig, Map<String, Object> properties) {
+ usersPath = null;
+ }
+
/**
* Returns an administrative session to the default workspace.
*/
@@ -257,15 +272,17 @@ public class CreateUserServlet extends AbstractAuthorizablePostServlet implement
administrator = currentUser.isAdmin();
if (!administrator) {
- //check if the user is a member of the 'User administrator' group
- Authorizable userAdmin = um.getAuthorizable(this.userAdminGroupName);
- if (userAdmin instanceof Group) {
- boolean isMember = ((Group)userAdmin).isMember(currentUser);
- if (isMember) {
- administrator = true;
- }
- }
-
+ if (usersPath != null) {
+ //check if the current user has the minimum privileges needed to create a user
+ AccessControlManager acm = jcrSession.getAccessControlManager();
+ administrator = acm.hasPrivileges(usersPath, new Privilege[] {
+ acm.privilegeFromName(Privilege.JCR_READ),
+ acm.privilegeFromName(Privilege.JCR_READ_ACCESS_CONTROL),
+ acm.privilegeFromName(Privilege.JCR_MODIFY_ACCESS_CONTROL),
+ acm.privilegeFromName(PrivilegeConstants.REP_WRITE),
+ acm.privilegeFromName(PrivilegeConstants.REP_USER_MANAGEMENT)
+ });
+ }
}
} catch ( Exception ex ) {
log.warn("Failed to determine if the user is an admin, assuming not. Cause: "+ex.getMessage());