private String[] getReadingPrincipals( RepositorySession repositorySession, String zone, String path) throws StorageClientException { Session session = repositorySession.adaptTo(Session.class); AccessControlManager accessControlManager = session.getAccessControlManager(); return accessControlManager.findPrincipals( zone, path, Permissions.CAN_READ.getPermission(), true); }
/** * Gets the principals that can read content at a given path. * * @param session * @param path The path to check. * @return {@link String[]} of principal names that can read {@link path}. An empty array is * returned if no principals can read the path. * @throws StorageClientException */ @SuppressWarnings("unused") private String[] getReadingPrincipals(Session session, String path) throws StorageClientException { AccessControlManager accessControlManager = session.getAccessControlManager(); return accessControlManager.findPrincipals( Security.ZONE_CONTENT, path, Permissions.CAN_READ.getPermission(), true); }
private static boolean hasPermission( AccessControlManager acm, String path, Permission permission) { try { acm.check(Security.ZONE_CONTENT, path, permission); return true; } catch (org.sakaiproject.nakamura.api.lite.accesscontrol.AccessDeniedException e) { return false; } catch (StorageClientException e) { return false; } }
public void internalImportContent( ContentManager contentManager, JSONObject json, String path, boolean replaceProperties, AccessControlManager accessControlManager) throws JSONException, StorageClientException, AccessDeniedException { Iterator<String> keys = json.keys(); Map<String, Object> properties = new HashMap<String, Object>(); List<AclModification> modifications = Lists.newArrayList(); while (keys.hasNext()) { String key = keys.next(); if (!key.startsWith("jcr:")) { Object obj = json.get(key); String pathKey = getPathElement(key); Class<?> typeHint = getElementType(key); if (obj instanceof JSONObject) { if (key.endsWith("@grant")) { JSONObject acl = (JSONObject) obj; int bitmap = getPermissionBitMap(acl.getJSONArray("permission")); Operation op = getOperation(acl.getString("operation")); modifications.add(new AclModification(AclModification.grantKey(pathKey), bitmap, op)); } else if (key.endsWith("@deny")) { JSONObject acl = (JSONObject) obj; int bitmap = getPermissionBitMap(acl.getJSONArray("permission")); Operation op = getOperation(acl.getString("operation")); modifications.add(new AclModification(AclModification.denyKey(pathKey), bitmap, op)); } else if (key.endsWith("@Delete")) { StorageClientUtils.deleteTree(contentManager, path); } else { // need to do somethingwith delete here internalImportContent( contentManager, (JSONObject) obj, path + "/" + pathKey, replaceProperties, accessControlManager); } } else if (obj instanceof JSONArray) { if (key.endsWith("@Delete")) { properties.put(pathKey, new RemoveProperty()); } else { // This represents a multivalued property JSONArray arr = (JSONArray) obj; properties.put(pathKey, getArray(arr, typeHint)); } } else { if (key.endsWith("@Delete")) { properties.put(pathKey, new RemoveProperty()); } else { properties.put(pathKey, getObject(obj, typeHint)); } } } } Content content = contentManager.get(path); if (content == null) { contentManager.update(new Content(path, properties)); LOGGER.info("Created Node {} {}", path, properties); } else { for (Entry<String, Object> e : properties.entrySet()) { if (replaceProperties || !content.hasProperty(e.getKey())) { LOGGER.info("Updated Node {} {} {} ", new Object[] {path, e.getKey(), e.getValue()}); content.setProperty(e.getKey(), e.getValue()); } } contentManager.update(content); } if (modifications.size() > 0) { accessControlManager.setAcl( Security.ZONE_CONTENT, path, modifications.toArray(new AclModification[modifications.size()])); } }
/** * Manipulate the member list for this file. * * <p>{@inheritDoc} * * @see * org.apache.sling.api.servlets.SlingAllMethodsServlet#doPost(org.apache.sling.api.SlingHttpServletRequest, * org.apache.sling.api.SlingHttpServletResponse) */ @SuppressWarnings("unchecked") @Override protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException { // fail if anonymous String remoteUser = request.getRemoteUser(); if (User.ANON_USER.equals(remoteUser)) { response.sendError(SC_FORBIDDEN, "Anonymous users cannot update content members."); return; } Session session = null; boolean releaseSession = false; try { Resource resource = request.getResource(); session = resource.adaptTo(Session.class); Content pooledContent = resource.adaptTo(Content.class); AccessControlManager accessControlManager = session.getAccessControlManager(); AuthorizableManager authorizableManager = session.getAuthorizableManager(); User thisUser = authorizableManager.getUser(); if (!accessControlManager.can( thisUser, Security.ZONE_CONTENT, pooledContent.getPath(), Permissions.CAN_READ)) { response.sendError(SC_FORBIDDEN, "Insufficient permission to read this content."); } Map<String, Object> properties = pooledContent.getProperties(); String[] managers = StorageClientUtils.nonNullStringArray( (String[]) properties.get(POOLED_CONTENT_USER_MANAGER)); String[] editors = StorageClientUtils.nonNullStringArray( (String[]) properties.get(POOLED_CONTENT_USER_EDITOR)); String[] viewers = StorageClientUtils.nonNullStringArray( (String[]) properties.get(POOLED_CONTENT_USER_VIEWER)); Set<String> managerSet = Sets.newHashSet(managers); Set<String> editorSet = Sets.newHashSet(editors); Set<String> viewerSet = Sets.newHashSet(viewers); List<String> removeViewers = Arrays.asList( StorageClientUtils.nonNullStringArray(request.getParameterValues(":viewer@Delete"))); List<String> removeManagers = Arrays.asList( StorageClientUtils.nonNullStringArray(request.getParameterValues(":manager@Delete"))); List<String> removeEditors = Arrays.asList( StorageClientUtils.nonNullStringArray(request.getParameterValues(":editor@Delete"))); List<String> addViewers = Arrays.asList( StorageClientUtils.nonNullStringArray(request.getParameterValues(":viewer"))); List<String> addManagers = Arrays.asList( StorageClientUtils.nonNullStringArray(request.getParameterValues(":manager"))); List<String> addEditors = Arrays.asList( StorageClientUtils.nonNullStringArray(request.getParameterValues(":editor"))); if (!accessControlManager.can( thisUser, Security.ZONE_CONTENT, pooledContent.getPath(), Permissions.CAN_WRITE)) { if (!addManagers.isEmpty()) { response.sendError(SC_FORBIDDEN, "Non-managers may not add managers to content."); return; } for (String name : removeManagers) { // asking to remove managers who don't exist is harmless if (managerSet.contains(name)) { response.sendError(SC_FORBIDDEN, "Non-managers may not remove managers from content."); return; } } if (addViewers.contains(User.ANON_USER) || addViewers.contains(Group.EVERYONE)) { response.sendError( SC_FORBIDDEN, "Non-managers may not add 'anonymous' or 'everyone' as viewers."); return; } if (addEditors.contains(User.ANON_USER) || addEditors.contains(Group.EVERYONE)) { response.sendError( SC_FORBIDDEN, "Non-managers may not add 'anonymous' or 'everyone' as editors."); return; } for (String name : removeViewers) { if (!thisUser.getId().equals(name)) { Authorizable viewer = authorizableManager.findAuthorizable(name); if (viewer != null && !accessControlManager.can( thisUser, Security.ZONE_AUTHORIZABLES, name, Permissions.CAN_WRITE)) { response.sendError( SC_FORBIDDEN, "Non-managers may not remove any viewer other than themselves or a group which they manage."); } } } // the request has passed all the rules that govern non-manager users // so we'll grant an administrative session session = session.getRepository().loginAdministrative(); releaseSession = true; } List<AclModification> aclModifications = Lists.newArrayList(); for (String addManager : addManagers) { if ((addManager.length() > 0) && !managerSet.contains(addManager)) { managerSet.add(addManager); AclModification.addAcl(true, Permissions.CAN_MANAGE, addManager, aclModifications); } } for (String removeManager : removeManagers) { if ((removeManager.length() > 0) && managerSet.contains(removeManager)) { managerSet.remove(removeManager); AclModification.removeAcl(true, Permissions.CAN_MANAGE, removeManager, aclModifications); } } for (String addEditor : addEditors) { if ((addEditor.length() > 0) && !editorSet.contains(addEditor)) { editorSet.add(addEditor); AclModification.addAcl(true, PERMISSION_EDITOR, addEditor, aclModifications); } } for (String removeEditor : removeEditors) { if ((removeEditor.length() > 0) && editorSet.contains(removeEditor)) { editorSet.remove(removeEditor); AclModification.removeAcl(true, PERMISSION_EDITOR, removeEditor, aclModifications); } } for (String addViewer : addViewers) { if ((addViewer.length() > 0) && !viewerSet.contains(addViewer)) { viewerSet.add(addViewer); AclModification.addAcl(true, Permissions.CAN_READ, addViewer, aclModifications); } } for (String removeViewer : removeViewers) { removeViewer = removeViewer.trim(); if ((removeViewer.length() > 0) && viewerSet.contains(removeViewer)) { viewerSet.remove(removeViewer); if (!managerSet.contains(removeViewer)) { AclModification.removeAcl(true, Permissions.CAN_READ, removeViewer, aclModifications); } } } updateContentMembers(session, pooledContent, viewerSet, managerSet, editorSet); updateContentAccess(session, pooledContent, aclModifications); this.authorizableCountChanger.notify( UserConstants.CONTENT_ITEMS_PROP, addViewers, addEditors, addManagers, removeViewers, removeEditors, removeManagers); response.setStatus(SC_OK); } catch (StorageClientException e) { LOGGER.error(e.getMessage()); response.sendError( SC_INTERNAL_SERVER_ERROR, "StorageClientException: " + e.getLocalizedMessage()); } catch (AccessDeniedException e) { response.sendError( SC_FORBIDDEN, "Insufficient permission to update content members at " + request.getRequestURI()); } finally { if (session != null && releaseSession) { try { session.logout(); } catch (ClientPoolException e) { LOGGER.error(e.getMessage()); } } } }
/** * Retrieves the list of members. * * <p>{@inheritDoc} * * @see * org.apache.sling.api.servlets.SlingSafeMethodsServlet#doGet(org.apache.sling.api.SlingHttpServletRequest, * org.apache.sling.api.SlingHttpServletResponse) */ @Override protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException { try { // Get hold of the actual file. Resource resource = request.getResource(); javax.jcr.Session jcrSession = request.getResourceResolver().adaptTo(javax.jcr.Session.class); Session session = resource.adaptTo(Session.class); AuthorizableManager am = session.getAuthorizableManager(); AccessControlManager acm = session.getAccessControlManager(); Content node = resource.adaptTo(Content.class); Authorizable thisUser = am.findAuthorizable(session.getUserId()); if (!acm.can(thisUser, Security.ZONE_CONTENT, resource.getPath(), Permissions.CAN_READ)) { response.sendError(HttpServletResponse.SC_NOT_FOUND); return; } Map<String, Object> properties = node.getProperties(); String[] managers = (String[]) properties.get(POOLED_CONTENT_USER_MANAGER); String[] editors = (String[]) properties.get(POOLED_CONTENT_USER_EDITOR); String[] viewers = (String[]) properties.get(POOLED_CONTENT_USER_VIEWER); boolean detailed = false; boolean tidy = false; for (String selector : request.getRequestPathInfo().getSelectors()) { if ("detailed".equals(selector)) { detailed = true; } else if ("tidy".equals(selector)) { tidy = true; } } // Loop over the sets and output it. ExtendedJSONWriter writer = new ExtendedJSONWriter(response.getWriter()); writer.setTidy(tidy); writer.object(); writer.key("managers"); writer.array(); for (String manager : StorageClientUtils.nonNullStringArray(managers)) { try { writeProfileMap(jcrSession, am, writer, manager, detailed); } catch (AccessDeniedException e) { LOGGER.debug("Skipping private manager [{}]", manager); } } writer.endArray(); writer.key("editors"); writer.array(); for (String editor : StorageClientUtils.nonNullStringArray(editors)) { try { writeProfileMap(jcrSession, am, writer, editor, detailed); } catch (AccessDeniedException e) { LOGGER.debug("Skipping private editor [{}]", editor); } } writer.endArray(); writer.key("viewers"); writer.array(); for (String viewer : StorageClientUtils.nonNullStringArray(viewers)) { try { writeProfileMap(jcrSession, am, writer, viewer, detailed); } catch (AccessDeniedException e) { LOGGER.debug("Skipping private viewer [{}]", viewer); } } writer.endArray(); writer.endObject(); } catch (JSONException e) { response.sendError(SC_INTERNAL_SERVER_ERROR, "Failed to generate proper JSON."); LOGGER.error(e.getMessage(), e); } catch (StorageClientException e) { response.sendError(SC_INTERNAL_SERVER_ERROR, "Failed to generate proper JSON."); LOGGER.error(e.getMessage(), e); } catch (AccessDeniedException e) { response.sendError(SC_INTERNAL_SERVER_ERROR, "Failed to generate proper JSON."); LOGGER.error(e.getMessage(), e); } catch (RepositoryException e) { response.sendError(SC_INTERNAL_SERVER_ERROR, "Failed to generate proper JSON."); LOGGER.error(e.getMessage(), e); } }