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);
    }
  }
 private void applyJsonToAuthorizable(URL url, Authorizable authorizable, Session session)
     throws IOException, RepositoryException {
   String jsonString = IOUtils.readFully(url.openStream(), "UTF-8");
   if (jsonString != null) {
     Map<String, Object[]> postprocessParameters = new HashMap<String, Object[]>();
     try {
       JSONObject jsonObject = new JSONObject(jsonString);
       Iterator<String> keys = jsonObject.keys();
       while (keys.hasNext()) {
         String key = keys.next();
         Object jsonValue = jsonObject.get(key);
         if (key.startsWith(SlingPostConstants.RP_PREFIX)) {
           postprocessParameters.put(key, new Object[] {jsonValue});
         } else {
           Value value = JcrResourceUtil.createValue(jsonValue, session);
           authorizable.setProperty(key, value);
         }
       }
     } catch (JSONException e) {
       LOGGER.error("Faulty JSON at " + url, e);
     }
     try {
       authorizablePostProcessService.process(
           authorizable, session, ModificationType.CREATE, postprocessParameters);
     } catch (Exception e) {
       LOGGER.error("Could not configure default authorizable " + authorizable.getID(), e);
     }
   }
 }
 /**
  * Get's the name for an authorizable on what the list should be sorted. sakai:group-title for
  * Groups, lastName for Users.
  *
  * @param member The authorizable to get a name for.
  * @return The name.
  * @throws RepositoryException
  */
 private String getName(Authorizable member) throws RepositoryException {
   String name = member.getID();
   if (member.isGroup()) {
     Value[] values = member.getProperty("sakai:group-title");
     if (values != null && values.length != 0) {
       name = values[0].getString();
     }
   } else {
     Value[] values = member.getProperty("lastName");
     if (values != null && values.length != 0) {
       name = values[0].getString();
     }
   }
   // We need to add the ID to keep the keys unique.
   return name + member.getID();
 }
  /**
   * Add an ACL entry at a path for the authorizable.
   *
   * @param path
   * @param authorizable
   * @param session
   * @param writePrivilageGranted
   * @throws RepositoryException
   */
  public static void addEntry(
      String path, Authorizable authorizable, Session session, String... privilegeSpec)
      throws RepositoryException {

    String principalName = authorizable.getPrincipal().getName();

    List<String> grantedPrivilegeNames = new ArrayList<String>();
    List<String> deniedPrivilegeNames = new ArrayList<String>();
    for (String spec : privilegeSpec) {
      if (spec.startsWith(GRANTED)) {
        grantedPrivilegeNames.add(spec.substring(GRANTED.length()));
      } else if (spec.startsWith(DENIED)) {
        deniedPrivilegeNames.add(spec.substring(DENIED.length()));
      }
    }

    AccessControlManager accessControlManager = AccessControlUtil.getAccessControlManager(session);
    AccessControlList updatedAcl = null;
    AccessControlPolicyIterator applicablePolicies =
        accessControlManager.getApplicablePolicies(path);
    while (applicablePolicies.hasNext()) {
      AccessControlPolicy policy = applicablePolicies.nextAccessControlPolicy();
      if (policy instanceof AccessControlList) {
        updatedAcl = (AccessControlList) policy;
        break;
      }
    }
    if (updatedAcl == null) {
      throw new RepositoryException("Unable to find an access conrol policy to update.");
    }

    StringBuilder oldPrivileges = null;
    StringBuilder newPrivileges = null;
    if (LOGGER.isInfoEnabled()) {
      oldPrivileges = new StringBuilder();
      newPrivileges = new StringBuilder();
    }

    // keep track of the existing Aces for the target principal
    AccessControlEntry[] accessControlEntries = updatedAcl.getAccessControlEntries();
    List<AccessControlEntry> oldAces = new ArrayList<AccessControlEntry>();
    for (AccessControlEntry ace : accessControlEntries) {
      if (principalName.equals(ace.getPrincipal().getName())) {
        if (LOGGER.isInfoEnabled()) {
          LOGGER.info(
              "Found Existing ACE for principal {} on resource: ",
              new Object[] {principalName, path});
        }
        oldAces.add(ace);

        if (LOGGER.isInfoEnabled()) {
          // collect the information for debug logging
          boolean isAllow = AccessControlUtil.isAllow(ace);
          Privilege[] privileges = ace.getPrivileges();
          for (Privilege privilege : privileges) {
            if (oldPrivileges.length() > 0) {
              oldPrivileges.append(", "); // separate entries by commas
            }
            if (isAllow) {
              oldPrivileges.append("granted=");
            } else {
              oldPrivileges.append("denied=");
            }
            oldPrivileges.append(privilege.getName());
          }
        }
      }
    }

    // remove the old aces
    if (!oldAces.isEmpty()) {
      for (AccessControlEntry ace : oldAces) {
        updatedAcl.removeAccessControlEntry(ace);
      }
    }

    // add a fresh ACE with the granted privileges
    List<Privilege> grantedPrivilegeList = new ArrayList<Privilege>();
    for (String name : grantedPrivilegeNames) {
      if (name.length() == 0) {
        continue; // empty, skip it.
      }
      Privilege privilege = accessControlManager.privilegeFromName(name);
      grantedPrivilegeList.add(privilege);

      if (LOGGER.isInfoEnabled()) {
        if (newPrivileges.length() > 0) {
          newPrivileges.append(", "); // separate entries by commas
        }
        newPrivileges.append("granted=");
        newPrivileges.append(privilege.getName());
      }
    }
    if (grantedPrivilegeList.size() > 0) {
      Principal principal = authorizable.getPrincipal();
      updatedAcl.addAccessControlEntry(
          principal, grantedPrivilegeList.toArray(new Privilege[grantedPrivilegeList.size()]));
    }

    // add a fresh ACE with the denied privileges
    List<Privilege> deniedPrivilegeList = new ArrayList<Privilege>();
    for (String name : deniedPrivilegeNames) {
      if (name.length() == 0) {
        continue; // empty, skip it.
      }
      Privilege privilege = accessControlManager.privilegeFromName(name);
      deniedPrivilegeList.add(privilege);

      if (LOGGER.isInfoEnabled()) {
        if (newPrivileges.length() > 0) {
          newPrivileges.append(", "); // separate entries by commas
        }
        newPrivileges.append("denied=");
        newPrivileges.append(privilege.getName());
      }
    }
    if (deniedPrivilegeList.size() > 0) {
      Principal principal = authorizable.getPrincipal();
      AccessControlUtil.addEntry(
          updatedAcl,
          principal,
          deniedPrivilegeList.toArray(new Privilege[deniedPrivilegeList.size()]),
          false);
    }

    accessControlManager.setPolicy(path, updatedAcl);

    if (LOGGER.isInfoEnabled()) {
      LOGGER.info(
          "Updated ACE for principalId {} for resource {} from {} to {}",
          new Object[] {
            authorizable.getID(), path, oldPrivileges.toString(), newPrivileges.toString()
          });
    }
  }
  /**
   * {@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 {
    Authorizable authorizable = null;
    Resource resource = request.getResource();
    if (resource != null) {
      authorizable = resource.adaptTo(Authorizable.class);
    }

    if (authorizable == null || !authorizable.isGroup()) {
      response.sendError(HttpServletResponse.SC_NO_CONTENT, "Couldn't find group");
      return;
    }

    Group group = (Group) authorizable;

    List<String> selectors = Arrays.asList(request.getRequestPathInfo().getSelectors());
    ExtendedJSONWriter writer = new ExtendedJSONWriter(response.getWriter());
    writer.setTidy(selectors.contains("tidy"));

    // Get the sorting order, default is ascending or the natural sorting order (which is
    // null for a TreeMap.)
    Comparator<String> comparator = null;
    String order = "ascending";
    if (request.getRequestParameter("sortOrder") != null) {
      order = request.getRequestParameter("sortOrder").getString();
      if (order.equals("descending")) {
        comparator = Collections.reverseOrder();
      }
    }

    try {
      response.setContentType("application/json");
      TreeMap<String, Authorizable> map = null;
      if (selectors.contains("managers")) {
        map = getManagers(request, group, comparator);
      } else {
        // Members is the default.
        map = getMembers(request, group, comparator);
      }

      // Do some paging.
      long items =
          (request.getParameter(ITEMS) != null) ? Long.parseLong(request.getParameter(ITEMS)) : 25;
      long page =
          (request.getParameter(PAGE) != null) ? Long.parseLong(request.getParameter(PAGE)) : 0;
      if (page < 0) {
        page = 0;
      }
      if (items < 0) {
        items = 25;
      }
      Iterator<Entry<String, Authorizable>> iterator =
          getInPlaceIterator(request, map, items, page);

      // Write the whole lot out.
      Session session = request.getResourceResolver().adaptTo(Session.class);
      writer.array();
      int i = 0;
      while (iterator.hasNext() && i < items) {
        Entry<String, Authorizable> entry = iterator.next();
        Authorizable au = entry.getValue();
        ValueMap profile;
        if (selectors.contains("detailed")) {
          profile = profileService.getProfileMap(au, session);
        } else {
          profile = profileService.getCompactProfileMap(au, session);
        }
        if (profile != null) {
          writer.valueMap(profile);
          i++;
        } else {
          // profile wasn't found.  safe to ignore and not include the group
          logger.info("Profile not found for " + au.getID());
        }
      }
      writer.endArray();

    } catch (RepositoryException e) {
      response.sendError(
          HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Failed to retrieve members/managers.");
      return;
    } catch (JSONException e) {
      response.sendError(
          HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Failed to build a proper JSON output.");
      return;
    }
  }
  public void setRoleMembers(
      Session session,
      final ITenant theTenant,
      final String roleName,
      final String[] memberUserNames)
      throws RepositoryException, NotFoundException {
    List<IPentahoUser> currentRoleMembers = getRoleMembers(session, theTenant, roleName);
    if (tenantAdminRoleName.equals(roleName)
        && (currentRoleMembers != null && currentRoleMembers.size() > 0)
        && memberUserNames.length == 0) {
      throw new RepositoryException(
          Messages.getInstance()
              .getString(
                  "AbstractJcrBackedUserRoleDao.ERROR_0001_LAST_ADMIN_ROLE", tenantAdminRoleName));
    }
    Group jackrabbitGroup = getJackrabbitGroup(theTenant, roleName, session);

    if ((jackrabbitGroup == null)
        || !TenantUtils.isAccessibleTenant(
            theTenant == null
                ? tenantedRoleNameUtils.getTenant(jackrabbitGroup.getID())
                : theTenant)) {
      throw new NotFoundException(
          Messages.getInstance()
              .getString("AbstractJcrBackedUserRoleDao.ERROR_0002_ROLE_NOT_FOUND"));
    }
    HashMap<String, User> currentlyAssignedUsers = new HashMap<String, User>();
    Iterator<Authorizable> currentMembers = jackrabbitGroup.getMembers();
    while (currentMembers.hasNext()) {
      Authorizable member = currentMembers.next();
      if (member instanceof User) {
        currentlyAssignedUsers.put(member.getID(), (User) member);
      }
    }

    HashMap<String, User> finalCollectionOfAssignedUsers = new HashMap<String, User>();
    if (memberUserNames != null) {
      ITenant tenant = theTenant == null ? JcrTenantUtils.getTenant(roleName, false) : theTenant;
      for (String user : memberUserNames) {
        User jackrabbitUser = getJackrabbitUser(tenant, user, session);
        if (jackrabbitUser != null) {
          finalCollectionOfAssignedUsers.put(
              tenantedRoleNameUtils.getPrincipleId(tenant, user), jackrabbitUser);
        }
      }
    }

    ArrayList<String> usersToRemove = new ArrayList<String>(currentlyAssignedUsers.keySet());
    usersToRemove.removeAll(finalCollectionOfAssignedUsers.keySet());

    ArrayList<String> usersToAdd = new ArrayList<String>(finalCollectionOfAssignedUsers.keySet());
    usersToAdd.removeAll(currentlyAssignedUsers.keySet());

    for (String userId : usersToRemove) {
      jackrabbitGroup.removeMember(currentlyAssignedUsers.get(userId));
    }

    for (String userId : usersToAdd) {
      jackrabbitGroup.addMember(finalCollectionOfAssignedUsers.get(userId));

      // Purge the UserDetails cache
      purgeUserFromCache(userId);
    }
  }