This is an automated email from the ASF dual-hosted git repository. rombert pushed a commit to annotated tag org.apache.sling.jcr.jackrabbit.usermanager-2.1.0 in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-jackrabbit-usermanager.git
commit c06d6a5e85a512a9a726ec7cfad61dc8ce154089 Author: Eric Norman <[email protected]> AuthorDate: Fri Mar 19 19:31:12 2010 +0000 SLING-1453 Provide AuthorizablePrivilegesInfo service to help user/group management scripts query what the current user is allowed to do git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/jcr/jackrabbit-usermanager@925392 13f79535-47bb-0310-9956-ffa450edef68 --- pom.xml | 5 +- .../usermanager/AuthorizablePrivilegesInfo.java | 58 ++++ .../impl/AuthorizablePrivilegesInfoImpl.java | 306 +++++++++++++++++++++ 3 files changed, 368 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 89411b9..262b189 100644 --- a/pom.xml +++ b/pom.xml @@ -60,8 +60,11 @@ <extensions>true</extensions> <configuration> <instructions> + <Export-Package> + org.apache.sling.jackrabbit.usermanager;version=${pom.version}, + </Export-Package> <Private-Package> - org.apache.sling.jackrabbit.usermanager.* + org.apache.sling.jackrabbit.usermanager.impl.* </Private-Package> </instructions> </configuration> diff --git a/src/main/java/org/apache/sling/jackrabbit/usermanager/AuthorizablePrivilegesInfo.java b/src/main/java/org/apache/sling/jackrabbit/usermanager/AuthorizablePrivilegesInfo.java new file mode 100644 index 0000000..5ccb119 --- /dev/null +++ b/src/main/java/org/apache/sling/jackrabbit/usermanager/AuthorizablePrivilegesInfo.java @@ -0,0 +1,58 @@ +package org.apache.sling.jackrabbit.usermanager; + +import javax.jcr.Session; + +public interface AuthorizablePrivilegesInfo { + + /** + * Checks whether the current user has been granted privileges + * to add a new user. + * + * @param jcrSession the JCR session of the current user + * @return true if the current user has the privileges, false otherwise + */ + boolean canAddUser(Session jcrSession); + + /** + * Checks whether the current user has been granted privileges + * to add a new group. + * + * @param jcrSession the JCR session of the current user + * @return true if the current user has the privileges, false otherwise + */ + boolean canAddGroup(Session jcrSession); + + /** + * Checks whether the current user has been granted privileges + * to update the properties of the specified user or group. + * + * @param jcrSession the JCR session of the current user + * @param principalId the user or group id to check + * @return true if the current user has the privileges, false otherwise + */ + boolean canUpdateProperties(Session jcrSession, + String principalId); + + /** + * Checks whether the current user has been granted privileges + * to remove the specified user or group. + * + * @param jcrSession the JCR session of the current user + * @param principalId the user or group id to check + * @return true if the current user has the privileges, false otherwise + */ + boolean canRemove(Session jcrSession, + String principalId); + + /** + * Checks whether the current user has been granted privileges + * to update the membership of the specified group. + * + * @param jcrSession the JCR session of the current user + * @param groupId the group id to check + * @return true if the current user has the privileges, false otherwise + */ + boolean canUpdateGroupMembers(Session jcrSession, + String groupId); + +} \ 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 new file mode 100644 index 0000000..f158c9a --- /dev/null +++ b/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/AuthorizablePrivilegesInfoImpl.java @@ -0,0 +1,306 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.sling.jackrabbit.usermanager.impl; + +import java.io.UnsupportedEncodingException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.util.Dictionary; + +import javax.jcr.RepositoryException; +import javax.jcr.Session; + +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.sling.commons.osgi.OsgiUtil; +import org.apache.sling.jackrabbit.usermanager.AuthorizablePrivilegesInfo; +import org.apache.sling.jcr.base.util.AccessControlUtil; +import org.osgi.service.component.ComponentContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Helper class to assist in the usage of access control of users/groups from scripts. + * + * The default access control policy defined by this provider has the following + * characteristics: + * <ul> + * <li>everybody has READ permission to all items,</li> + * + * <li>every known user is allowed to modify it's own properties except for + * her/his group membership,</li> + * + * <li>members of the 'User administrator' group are allowed to create, modify + * and remove users,</li> + * + * <li>members of the 'Group administrator' group are allowed to create, modify + * and remove groups,</li> + * + * <li>group membership can only be edited by members of the 'Group administrator' + * and the 'User administrator' group.</li> + * </ul> + * + * @scr.component immediate="true" metatype="no" + * @scr.service + * + * @scr.property name="service.description" value="User/Group Privileges Information" + * @scr.property name="service.vendor" value="The Apache Software Foundation" + */ +public class AuthorizablePrivilegesInfoImpl implements AuthorizablePrivilegesInfo { + + /** default log */ + private final Logger log = LoggerFactory.getLogger(getClass()); + + /** + * The name of the configuration parameter providing the + * 'User administrator' group name. + * + * @scr.property valueRef="DEFAULT_USER_ADMIN_GROUP_NAME" + */ + private static final String PAR_USER_ADMIN_GROUP_NAME = "user.admin.group.name"; + + /** + * The default 'User administrator' group name + * + * @see #PAR_USER_ADMIN_GROUP_NAME + */ + private static final String DEFAULT_USER_ADMIN_GROUP_NAME = "UserAdmin"; + + private String userAdminGroupName = DEFAULT_USER_ADMIN_GROUP_NAME; + + /** + * The name of the configuration parameter providing the + * 'Group administrator' group name. + * + * @scr.property valueRef="DEFAULT_GROUP_ADMIN_GROUP_NAME" + */ + private static final String PAR_GROUP_ADMIN_GROUP_NAME = "group.admin.group.name"; + + /** + * The default 'User administrator' group name + * + * @see #PAR_GROUP_ADMIN_GROUP_NAME + */ + private static final String DEFAULT_GROUP_ADMIN_GROUP_NAME = "GroupAdmin"; + + private String groupAdminGroupName = DEFAULT_GROUP_ADMIN_GROUP_NAME; + + + /* (non-Javadoc) + * @see org.apache.sling.jackrabbit.usermanager.AuthorizablePrivilegesInfo#canAddGroup(javax.jcr.Session) + */ + public boolean canAddGroup(Session jcrSession) { + try { + UserManager userManager = AccessControlUtil.getUserManager(jcrSession); + Authorizable currentUser = userManager.getAuthorizable(jcrSession.getUserID()); + + if (((User)currentUser).isAdmin()) { + return true; //admin user has full control + } + + //check if the user is a member of the 'Group administrator' group + Authorizable groupAdmin = userManager.getAuthorizable(this.groupAdminGroupName); + if (groupAdmin instanceof Group) { + boolean isMember = ((Group)groupAdmin).isMember(currentUser); + if (isMember) { + return true; + } + } + } catch (RepositoryException e) { + log.warn("Failed to determine if {} can add a new group", jcrSession.getUserID()); + } + return false; + } + + /* (non-Javadoc) + * @see org.apache.sling.jackrabbit.usermanager.AuthorizablePrivilegesInfo#canAddUser(javax.jcr.Session) + */ + public boolean canAddUser(Session jcrSession) { + try { + UserManager userManager = AccessControlUtil.getUserManager(jcrSession); + Authorizable currentUser = userManager.getAuthorizable(jcrSession.getUserID()); + + if (((User)currentUser).isAdmin()) { + return true; //admin user has full control + } + + //check if the user is a member of the 'User administrator' group + Authorizable userAdmin = userManager.getAuthorizable(this.userAdminGroupName); + if (userAdmin instanceof Group) { + boolean isMember = ((Group)userAdmin).isMember(currentUser); + if (isMember) { + return true; + } + } + } catch (RepositoryException e) { + log.warn("Failed to determine if {} can add a new user", jcrSession.getUserID()); + } + return false; + } + + /* (non-Javadoc) + * @see org.apache.sling.jackrabbit.usermanager.AuthorizablePrivilegesInfo#canRemove(javax.jcr.Session, java.lang.String) + */ + public boolean canRemove(Session jcrSession, String principalId) { + try { + UserManager userManager = AccessControlUtil.getUserManager(jcrSession); + Authorizable currentUser = userManager.getAuthorizable(jcrSession.getUserID()); + + if (((User)currentUser).isAdmin()) { + return true; //admin user has full control + } + + Authorizable authorizable = userManager.getAuthorizable(principalId); + if (authorizable instanceof User) { + //check if the user is a member of the 'User administrator' group + Authorizable userAdmin = userManager.getAuthorizable(this.userAdminGroupName); + if (userAdmin instanceof Group) { + boolean isMember = ((Group)userAdmin).isMember(currentUser); + if (isMember) { + return true; + } + } + } else if (authorizable instanceof Group) { + //check if the user is a member of the 'Group administrator' group + Authorizable groupAdmin = userManager.getAuthorizable(this.groupAdminGroupName); + if (groupAdmin instanceof Group) { + boolean isMember = ((Group)groupAdmin).isMember(currentUser); + if (isMember) { + return true; + } + } + } + } catch (RepositoryException e) { + log.warn("Failed to determine if {} can remove authorizable {}", jcrSession.getUserID(), principalId); + } + return false; + } + + /* (non-Javadoc) + * @see org.apache.sling.jackrabbit.usermanager.AuthorizablePrivilegesInfo#canUpdateGroupMembers(javax.jcr.Session, java.lang.String) + */ + public boolean canUpdateGroupMembers(Session jcrSession, String groupId) { + try { + UserManager userManager = AccessControlUtil.getUserManager(jcrSession); + Authorizable currentUser = userManager.getAuthorizable(jcrSession.getUserID()); + + if (((User)currentUser).isAdmin()) { + return true; //admin user has full control + } + + Authorizable authorizable = userManager.getAuthorizable(groupId); + if (authorizable instanceof Group) { + //check if the user is a member of the 'Group administrator' group + Authorizable groupAdmin = userManager.getAuthorizable(this.groupAdminGroupName); + if (groupAdmin instanceof Group) { + boolean isMember = ((Group)groupAdmin).isMember(currentUser); + if (isMember) { + return true; + } + } + + //check if the user is a member of the 'User administrator' group + Authorizable userAdmin = userManager.getAuthorizable(this.userAdminGroupName); + if (userAdmin instanceof Group) { + boolean isMember = ((Group)userAdmin).isMember(currentUser); + if (isMember) { + return true; + } + } + } + } catch (RepositoryException e) { + log.warn("Failed to determine if {} can remove authorizable {}", jcrSession.getUserID(), groupId); + } + return false; + } + + /* (non-Javadoc) + * @see org.apache.sling.jackrabbit.usermanager.AuthorizablePrivilegesInfo#canUpdateProperties(javax.jcr.Session, java.lang.String) + */ + public boolean canUpdateProperties(Session jcrSession, String principalId) { + try { + if (jcrSession.getUserID().equals(principalId)) { + //user is allowed to update it's own properties + return true; + } + + UserManager userManager = AccessControlUtil.getUserManager(jcrSession); + Authorizable currentUser = userManager.getAuthorizable(jcrSession.getUserID()); + + if (((User)currentUser).isAdmin()) { + return true; //admin user has full control + } + + Authorizable authorizable = userManager.getAuthorizable(principalId); + if (authorizable instanceof User) { + //check if the user is a member of the 'User administrator' group + Authorizable userAdmin = userManager.getAuthorizable(this.userAdminGroupName); + if (userAdmin instanceof Group) { + boolean isMember = ((Group)userAdmin).isMember(currentUser); + if (isMember) { + return true; + } + } + } else if (authorizable instanceof Group) { + //check if the user is a member of the 'Group administrator' group + Authorizable groupAdmin = userManager.getAuthorizable(this.groupAdminGroupName); + if (groupAdmin instanceof Group) { + boolean isMember = ((Group)groupAdmin).isMember(currentUser); + if (isMember) { + return true; + } + } + } + } catch (RepositoryException e) { + log.warn("Failed to determine if {} can remove authorizable {}", jcrSession.getUserID(), principalId); + } + return false; + } + + + // ---------- SCR Integration ---------------------------------------------- + + /** + * Called by SCR to activate the component. + * + * @throws InvalidKeyException + * @throws NoSuchAlgorithmException + * @throws IllegalStateException + * @throws UnsupportedEncodingException + */ + protected void activate(ComponentContext componentContext) + throws InvalidKeyException, NoSuchAlgorithmException, + IllegalStateException, UnsupportedEncodingException { + + Dictionary<?, ?> properties = componentContext.getProperties(); + + this.userAdminGroupName = OsgiUtil.toString(properties.get(PAR_USER_ADMIN_GROUP_NAME), + DEFAULT_USER_ADMIN_GROUP_NAME); + log.info("User Admin Group Name {}", this.userAdminGroupName); + + this.groupAdminGroupName = OsgiUtil.toString(properties.get(PAR_GROUP_ADMIN_GROUP_NAME), + DEFAULT_GROUP_ADMIN_GROUP_NAME); + log.info("Group Admin Group Name {}", this.groupAdminGroupName); + } + + protected void deactivate(ComponentContext componentContext) { + this.userAdminGroupName = DEFAULT_USER_ADMIN_GROUP_NAME; + this.groupAdminGroupName = DEFAULT_GROUP_ADMIN_GROUP_NAME; + } +} -- To stop receiving notification emails like this one, please contact "[email protected]" <[email protected]>.
