Beispiel #1
0
  /**
   * Create a link to a file. There is no need to call a session.save, the change is persistent.
   *
   * @param fileNode The node that represents the file. This node has to be retrieved via the normal
   *     user his {@link Session session}. If the userID equals {@link UserConstants.ANON_USERID} an
   *     AccessDeniedException will be thrown.
   * @param linkPath The absolute path in JCR where the link should be placed.
   * @param slingRepository The {@link SlingRepository} to use to login as an administrative.
   * @return The newly created node.
   * @throws AccessDeniedException When the user is anonymous.
   * @throws RepositoryException Something else went wrong.
   */
  public static boolean createLink(Node fileNode, String linkPath, SlingRepository slingRepository)
      throws AccessDeniedException, RepositoryException {
    Session session = fileNode.getSession();
    String userId = session.getUserID();
    if (UserConstants.ANON_USERID.equals(userId)) {
      throw new AccessDeniedException();
    }

    boolean hasMixin =
        JcrUtils.hasMixin(fileNode, REQUIRED_MIXIN) && fileNode.canAddMixin(REQUIRED_MIXIN);
    // If the fileNode doesn't have the required referenceable mixin, we need to set it.
    if (!hasMixin) {
      // The required mixin is not on the node.
      // Set it.
      Session adminSession = null;
      try {
        adminSession = slingRepository.loginAdministrative(null);

        // Grab the node via the adminSession
        String path = fileNode.getPath();
        Node adminFileNode = (Node) adminSession.getItem(path);
        if (!hasMixin) {
          adminFileNode.addMixin(REQUIRED_MIXIN);
        }

        if (adminSession.hasPendingChanges()) {
          adminSession.save();
        }
      } finally {
        if (adminSession != null) {
          adminSession.logout();
        }
      }
    }

    // Now that the file is referenceable, it has a uuid.
    // Use it for the link.
    // Grab the (updated) node via the user's session id.
    fileNode = (Node) session.getItem(fileNode.getPath());

    // Create the link
    Node linkNode = JcrUtils.deepGetOrCreateNode(session, linkPath);
    if (!"sling:Folder".equals(linkNode.getPrimaryNodeType().getName())) {
      // sling folder allows single and multiple properties, no need for the mixin.
      if (linkNode.canAddMixin(REQUIRED_MIXIN)) {
        linkNode.addMixin(REQUIRED_MIXIN);
      }
    }
    linkNode.setProperty(JcrResourceConstants.SLING_RESOURCE_TYPE_PROPERTY, RT_SAKAI_LINK);
    linkNode.setProperty(SAKAI_LINK, fileNode.getIdentifier());

    // Save link.
    if (session.hasPendingChanges()) {
      session.save();
    }

    return true;
  }
  public void process(Authorizable authorizable, Session session, Modification change)
      throws Exception {
    LOGGER.debug("Starting MessageAuthorizablePostProcessor process");
    if (authorizable != null && authorizable.getID() != null && !authorizable.isGroup()) {
      PrincipalManager principalManager = AccessControlUtil.getPrincipalManager(session);
      String path =
          PersonalUtils.getHomeFolder(authorizable) + "/" + MessageConstants.FOLDER_MESSAGES;
      LOGGER.debug("Getting/creating message store node: {}", path);

      Node messageStore = JcrUtils.deepGetOrCreateNode(session, path);
      messageStore.setProperty(
          JcrResourceConstants.SLING_RESOURCE_TYPE_PROPERTY,
          MessageConstants.SAKAI_MESSAGESTORE_RT);
      // ACL's are managed by the Personal User Post processor.
      Principal anon =
          new Principal() {

            public String getName() {
              return UserConstants.ANON_USERID;
            }
          };
      Principal everyone = principalManager.getEveryone();

      // The user can do everything on this node.
      replaceAccessControlEntry(
          session, path, authorizable.getPrincipal(), new String[] {JCR_ALL}, null, null, null);

      // explicitly deny anon and everyone, this is private space.
      String[] deniedPrivs = new String[] {JCR_READ, JCR_WRITE};
      replaceAccessControlEntry(session, path, anon, null, deniedPrivs, null, null);
      replaceAccessControlEntry(session, path, everyone, null, deniedPrivs, null, null);
    }
  }
  public void testCreateSimpleStructure() throws Exception {
    long time = System.currentTimeMillis();

    ACMEGroupStructure acme = createAcmeStructure("" + time);

    // The basic properties of the site.
    String json = "{";
    json += "\"groups\" : {";
    json += "    \"collaborators\" : {";
    json += "        \"name\" : \"g-mysite-collaborators\",";
    json += "        \"members\" : [\"" + acme.acmeManagers.getID() + "\"]";
    json += "    },";
    json += "     \"viewers\" : {";
    json += "        \"name\" : \"g-mysite-viewers\",";
    json +=
        "         \"members\" : [\""
            + acme.acmeDevelopers.getID()
            + "\", \""
            + acme.acmeResearchers.getID()
            + "\"]";
    json += "     }";
    json += "  },";
    json += "\"site\" : {";
    json += "      \"properties\" : {";
    json += "         \"title\" : \"My site " + time + "\",";
    json += "          \"id\" : \"mysite-" + time + "\",";
    json += "          \"status\" : \"offline\"";
    json += "      },";
    json += "   \"pages\" : [";
    json += "       {";
    json += "          \"id\" : \"week-i\",";
    json += "          \"content\": \"First week content\"";
    json += "      },";
    json += "     {";
    json += "         \"id\" : \"week-ii\",";
    json += "          \"content\": \"First week content\"";
    json += "       }";
    json += "    ]";
    json += "    }";
    json += "  }";

    Session session = loginAdministrative();
    String templatePath = createTemplateStructure("" + time);
    Node templateNode = JcrUtils.deepGetOrCreateNode(session, templatePath);

    JSONObject jsonObject = new JSONObject(json);
    SiteTemplateBuilder builder = new SiteTemplateBuilder(templateNode, jsonObject);

    List<GroupToCreate> groups = builder.getGroups();
    assertEquals(2, groups.size());
  }
 /**
  * @param settingsNode2
  * @param propertyName
  * @return
  */
 private String[] getStringProperty(Node node, String propertyName) throws RepositoryException {
   if (node == null) {
     return new String[0];
   }
   Value[] v = JcrUtils.getValues(node, propertyName);
   if (v == null || v.length == 0) {
     return new String[0];
   }
   String[] s = new String[v.length];
   for (int i = 0; i < s.length; i++) {
     s[i] = v[i].getString();
   }
   return s;
 }
  protected void addMember(
      Session session, String filePath, Authorizable authorizable, String memberType)
      throws RepositoryException {
    Principal principal = authorizable.getPrincipal();

    // Add (or re-use) a members node for the new viewer or manager.
    String memberPath = getMemberNodePath(filePath, authorizable);
    Node memberNode = JcrUtils.deepGetOrCreateNode(session, memberPath);
    memberNode.setProperty(SLING_RESOURCE_TYPE_PROPERTY, POOLED_CONTENT_USER_RT);
    memberNode.setProperty(memberType, new String[] {principal.getName()});

    // Update the member's access to the pooled content.
    refreshMemberAccess(session, filePath, principal, memberNode);
  }
 private Node makeNode(String path, Session session) {
   if (!"/".equals(path) && path.endsWith("/")) { // strip trailing slash
     path = path.substring(0, path.lastIndexOf("/"));
   }
   Node node = null;
   try {
     node = JcrUtils.deepGetOrCreateNode(session, path);
     if (session.hasPendingChanges()) {
       session.save();
     }
   } catch (RepositoryException e) {
     throw new Error(e);
   }
   return node;
 }
  protected void dispatch(
      SlingHttpServletRequest request, SlingHttpServletResponse response, boolean userInputStream)
      throws ServletException, IOException {
    try {

      Resource resource = request.getResource();
      if (!resource.getPath().startsWith(PROXY_PATH_PREFIX)) {
        response.sendError(
            HttpServletResponse.SC_FORBIDDEN,
            "Proxying templates may only be stored in " + PROXY_PATH_PREFIX);
        return;
      }
      Node node = resource.adaptTo(Node.class);
      if (!userInputStream) {
        Value[] v = JcrUtils.getValues(node, SAKAI_REQUEST_STREAM_BODY);
        if (v != null && v.length > 0) {
          userInputStream = Boolean.parseBoolean(v[0].getString());
        }
      }
      Map<String, String> headers = new ConcurrentHashMap<String, String>();
      for (Enumeration<?> enames = request.getHeaderNames(); enames.hasMoreElements(); ) {

        String name = (String) enames.nextElement();
        if (!headerBacklist.contains(name)) {
          headers.put(name, request.getHeader(name));
        }
      }
      // search for special headers.
      if (headers.containsKey(BASIC_USER)) {
        String user = headers.get(BASIC_USER);
        String password = headers.get(BASIC_PASSWORD);
        Base64 base64 = new Base64();
        String passwordDigest =
            new String(base64.encode((user + ":" + password).getBytes("UTF-8")));
        String digest = BASIC + passwordDigest.trim();
        headers.put(AUTHORIZATION, digest);
      }

      for (Entry<String, String> e : headers.entrySet()) {
        if (e.getKey().startsWith(":")) {
          headers.remove(e.getKey());
        }
      }

      // collect the parameters and store into a mutable map.
      RequestParameterMap parameterMap = request.getRequestParameterMap();
      Map<String, Object> templateParams = new ConcurrentHashMap<String, Object>(parameterMap);

      // search for special parameters.
      if (parameterMap.containsKey(BASIC_USER)) {
        String user = parameterMap.getValue(BASIC_USER).getString();
        String password = parameterMap.getValue(BASIC_PASSWORD).getString();
        Base64 base64 = new Base64();
        String passwordDigest =
            new String(base64.encode((user + ":" + password).getBytes("UTF-8")));
        String digest = BASIC + passwordDigest.trim();
        headers.put(AUTHORIZATION, digest);
      }

      // we might want to pre-process the headers
      if (node.hasProperty(ProxyPreProcessor.SAKAI_PREPROCESSOR)) {
        String preprocessorName =
            node.getProperty(ProxyPreProcessor.SAKAI_PREPROCESSOR).getString();
        ProxyPreProcessor preprocessor = preProcessors.get(preprocessorName);
        if (preprocessor != null) {
          preprocessor.preProcessRequest(request, headers, templateParams);
        } else {
          LOGGER.warn(
              "Unable to find pre processor of name {} for node {} ",
              preprocessorName,
              node.getPath());
        }
      }
      ProxyPostProcessor postProcessor = defaultPostProcessor;
      // we might want to post-process the headers
      if (node.hasProperty(ProxyPostProcessor.SAKAI_POSTPROCESSOR)) {
        String postProcessorName =
            node.getProperty(ProxyPostProcessor.SAKAI_POSTPROCESSOR).getString();
        if (postProcessors.containsKey(postProcessorName)) {
          postProcessor = postProcessors.get(postProcessorName);
        }
        if (postProcessor == null) {
          LOGGER.warn(
              "Unable to find post processor of name {} for node {} ",
              postProcessorName,
              node.getPath());
          postProcessor = defaultPostProcessor;
        }
      }

      ProxyResponse proxyResponse =
          proxyClientService.executeCall(node, headers, templateParams, null, -1, null);
      try {
        postProcessor.process(templateParams, response, proxyResponse);
      } finally {
        proxyResponse.close();
      }
    } catch (IOException e) {
      throw e;
    } catch (ProxyClientException e) {
      response.sendError(500, e.getMessage());
    } catch (RepositoryException e) {
      response.sendError(500, e.getMessage());
    }
  }
  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;
  }