/** * Set-up minimal permissions for the workspace: * * <ul> * <li>'adminstrators' principal -> all privileges * <li>'everyone' -> read privilege * </ul> * * @param session to the workspace to set-up initial ACL to * @param editor for the specified session. * @throws RepositoryException If an error occurs. */ private static void initRootACL(SessionImpl session, AccessControlEditor editor) throws RepositoryException { try { log.debug("Install initial ACL:..."); String rootPath = session.getRootNode().getPath(); AccessControlPolicy[] acls = editor.editAccessControlPolicies(rootPath); if (acls.length > 0) { ACLTemplate acl = (ACLTemplate) acls[0]; PrincipalManager pMgr = session.getPrincipalManager(); AccessControlManager acMgr = session.getAccessControlManager(); String pName = SecurityConstants.ADMINISTRATORS_NAME; if (pMgr.hasPrincipal(pName)) { Principal administrators = pMgr.getPrincipal(pName); log.debug("... Privilege.ALL for administrators."); Privilege[] privs = new Privilege[] {acMgr.privilegeFromName(Privilege.JCR_ALL)}; acl.addAccessControlEntry(administrators, privs); } else { log.info( "Administrators principal group is missing -> omitting initialization of default permissions."); } Principal everyone = pMgr.getEveryone(); log.debug("... Privilege.READ for everyone."); Privilege[] privs = new Privilege[] {acMgr.privilegeFromName(Privilege.JCR_READ)}; acl.addAccessControlEntry(everyone, privs); editor.setPolicy(rootPath, acl); session.save(); } else { log.info( "No applicable ACL available for the root node -> skip initialization of the root node's ACL."); } } catch (RepositoryException e) { log.error( "Failed to set-up minimal access control for root node of workspace " + session.getWorkspace().getName()); session.getRootNode().refresh(false); } }
private Resource resolveMappedResource(ResourceResolver resourceResolver, String path) throws RepositoryException { String poolId = null; if (path.startsWith("/p/")) { poolId = path.substring("/p/".length()); } else if (path.length() == 2) { try { poolId = generatePoolId(); // we also need to create the node. Session adminSession = null; Session userSession = resourceResolver.adaptTo(Session.class); try { adminSession = slingRepository.loginAdministrative(null); String userId = userSession.getUserID(); PrincipalManager principalManager = AccessControlUtil.getPrincipalManager(userSession); Principal userPrincipal = principalManager.getPrincipal(userId); Node node = JcrUtils.deepGetOrCreateNode(adminSession, hash(poolId)); // make the node inherit the repository defaults for content, but admin for the user. String nodePath = node.getPath(); AccessControlUtil.replaceAccessControlEntry( adminSession, nodePath, userPrincipal, new String[] {JCR_ALL}, null, null, null); // set some properties to make it possible to locate this pool file without having to use // the path. node.setProperty("sakai:pool-file", "1"); node.setProperty("sakai:pool-file-owner", userId); // save so the resolver further down will find this file. if (adminSession.hasPendingChanges()) { adminSession.save(); } } finally { adminSession.logout(); } } catch (Exception e) { throw new RepositoryException("Unable to generate new pool ID " + e.getMessage(), e); } } if (poolId != null && poolId.length() > 0) { int i = poolId.indexOf('/'); if (i > 0) { poolId = poolId.substring(0, i); } i = poolId.indexOf('.'); String selectors = ""; if (i > 0) { selectors = poolId.substring(i); poolId = poolId.substring(0, i); } if (LOGGER.isInfoEnabled()) { LOGGER.info("Pool ID is [{}]", poolId); } String poolPath = null; try { poolPath = hash(poolId) + selectors; } catch (Exception e) { throw new RepositoryException("Unable to hash pool ID " + e.getMessage(), e); } Resource r = resourceResolver.resolve(poolPath); if (r instanceof NonExistingResource) { LOGGER.info("Pool ID does not exist, reject and dont allow creation on POST {} ", poolPath); throw new SlingException( "Resources may not be created at /p by the user", new AccessDeniedException("Cant create user specified pool resoruce")); } LOGGER.info("Resolving [{}] to [{}] ", poolPath, r); if (r != null) { // are the last elements the same ? if (getLastElement(r.getPath()).equals("/" + poolId)) { r.getResourceMetadata().put(CONTENT_RESOURCE_PROVIDER, this); return r; } else { if (LOGGER.isInfoEnabled()) { LOGGER.info("Rejected [{}] != [{}] ", getLastElement(r.getPath()), "/" + poolId); } } } } return null; }
/* * (non-Javadoc) * * @seeorg.apache.sling.jackrabbit.usermanager.post.AbstractAuthorizablePostServlet# * handleOperation(org.apache.sling.api.SlingHttpServletRequest, * org.apache.sling.api.servlets.HtmlResponse, java.util.List) */ @Override @edu.umd.cs.findbugs.annotations.SuppressWarnings( justification = "If there is an exception, the user is certainly not admin", value = {"REC_CATCH_EXCEPTION"}) protected void handleOperation( SlingHttpServletRequest request, HtmlResponse response, List<Modification> changes) throws RepositoryException { // KERN-432 dont allow anon users to access create group. if (SecurityConstants.ANONYMOUS_ID.equals(request.getRemoteUser())) { response.setStatus(403, "AccessDenied"); } // check that the submitted parameter values have valid values. final String principalName = request.getParameter(SlingPostConstants.RP_NODE_NAME); if (principalName == null) { throw new RepositoryException("Group name was not submitted"); } NameSanitizer san = new NameSanitizer(principalName, false); san.validate(); // check for allow create Group boolean allowCreateGroup = false; User currentUser = null; try { Session currentSession = request.getResourceResolver().adaptTo(Session.class); UserManager um = AccessControlUtil.getUserManager(currentSession); currentUser = (User) um.getAuthorizable(currentSession.getUserID()); if (currentUser.isAdmin()) { LOGGER.debug("User is an admin "); allowCreateGroup = true; } else { LOGGER.debug("Checking for membership of one of {} ", Arrays.toString(authorizedGroups)); PrincipalManager principalManager = AccessControlUtil.getPrincipalManager(currentSession); PrincipalIterator pi = principalManager.getGroupMembership( principalManager.getPrincipal(currentSession.getUserID())); Set<String> groups = new HashSet<String>(); for (; pi.hasNext(); ) { groups.add(pi.nextPrincipal().getName()); } for (String groupName : authorizedGroups) { if (groups.contains(groupName)) { allowCreateGroup = true; break; } // TODO: move this nasty hack into the PrincipalManager dynamic groups need to // be in the principal manager for this to work. if ("authenticated".equals(groupName) && !SecurityConstants.ADMIN_ID.equals(currentUser.getID())) { allowCreateGroup = true; break; } // just check via the user manager for dynamic resolution. Group group = (Group) um.getAuthorizable(groupName); LOGGER.debug("Checking for group {} {} ", groupName, group); if (group != null && group.isMember(currentUser)) { allowCreateGroup = true; LOGGER.debug("User is a member of {} {} ", groupName, group); break; } } } } catch (Exception ex) { LOGGER.warn( "Failed to determin if the user is an admin, assuming not. Cause: " + ex.getMessage()); allowCreateGroup = false; } if (!allowCreateGroup) { LOGGER.debug("User is not allowed to create groups "); response.setStatus(HttpServletResponse.SC_FORBIDDEN, "User is not allowed to create groups"); return; } Session session = getSession(); try { UserManager userManager = AccessControlUtil.getUserManager(session); Authorizable authorizable = userManager.getAuthorizable(principalName); if (authorizable != null) { // principal already exists! throw new RepositoryException( "A principal already exists with the requested name: " + principalName); } else { Group group = userManager.createGroup( new Principal() { public String getName() { return principalName; } }); String groupPath = AuthorizableResourceProvider.SYSTEM_USER_MANAGER_GROUP_PREFIX + group.getID(); Map<String, RequestProperty> reqProperties = collectContent(request, response, groupPath); response.setPath(groupPath); response.setLocation(externalizePath(request, groupPath)); response.setParentLocation( externalizePath(request, AuthorizableResourceProvider.SYSTEM_USER_MANAGER_GROUP_PATH)); changes.add(Modification.onCreated(groupPath)); // It is not allowed to touch the rep:group-managers property directly. String key = SYSTEM_USER_MANAGER_GROUP_PREFIX + principalName + "/"; reqProperties.remove(key + PROP_GROUP_MANAGERS); reqProperties.remove(key + PROP_GROUP_VIEWERS); // write content from form writeContent(session, group, reqProperties, changes); // update the group memberships, although this uses session from the request, it // only // does so for finding authorizables, so its ok that we are using an admin session // here. updateGroupMembership(request, group, changes); updateOwnership(request, group, new String[] {currentUser.getID()}, changes); sakaiAuthorizableService.postprocess(group, session); // Launch an OSGi event for creating a group. try { Dictionary<String, String> properties = new Hashtable<String, String>(); properties.put(UserConstants.EVENT_PROP_USERID, principalName); EventUtils.sendOsgiEvent(properties, UserConstants.TOPIC_GROUP_CREATED, eventAdmin); } catch (Exception e) { // Trap all exception so we don't disrupt the normal behaviour. LOGGER.error("Failed to launch an OSGi event for creating a user.", e); } } } catch (RepositoryException re) { throw new RepositoryException("Failed to create new group.", re); } finally { ungetSession(session); } }