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);
 }
Ejemplo n.º 3
0
 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;
   }
 }
Ejemplo n.º 4
0
  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);
    }
  }