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);
    }
  }
 @Override
 protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response)
     throws ServletException, IOException {
   String paramUser = request.getParameter(SiteService.SiteEvent.USER);
   logger.info("Request to add user " + paramUser);
   String paramGroup = "";
   try {
     Node requestedNode = request.getResource().adaptTo(Node.class);
     Value[] authorizables = requestedNode.getProperty("sakai:authorizables").getValues();
     paramGroup = authorizables[1].getString();
     request.setAttribute(JoinRequestConstants.PARAM_SITENODE, requestedNode);
     Session session = slingRepository.loginAdministrative(null);
     UserManager userManager = AccessControlUtil.getUserManager(session);
     Authorizable userAuth = userManager.getAuthorizable(paramUser);
     Group groupAuth = (Group) userManager.getAuthorizable(paramGroup);
     if (siteJoinIsAuthorized(request)) {
       groupAuth.addMember(userAuth);
       logger.info(paramUser + " added as member of group " + paramGroup);
     } else {
       response.sendError(403, "Not authorized to add member to site.");
     }
     if (session.hasPendingChanges()) {
       session.save();
     }
   } catch (Exception e) {
     response.sendError(500, e.getMessage());
   }
 }
 public Resource next() {
   Principal nextPrincipal = principals.nextPrincipal();
   try {
     ResourceResolver resourceResolver = parent.getResourceResolver();
     if (resourceResolver != null) {
       Session session = resourceResolver.adaptTo(Session.class);
       if (session != null) {
         UserManager userManager = AccessControlUtil.getUserManager(session);
         if (userManager != null) {
           Authorizable authorizable = userManager.getAuthorizable(nextPrincipal.getName());
           if (authorizable != null) {
             String path;
             if (authorizable.isGroup()) {
               path = SYSTEM_USER_MANAGER_GROUP_PREFIX + nextPrincipal.getName();
             } else {
               path = SYSTEM_USER_MANAGER_USER_PREFIX + nextPrincipal.getName();
             }
             return new SakaiAuthorizableResource(authorizable, resourceResolver, path);
           }
         }
       }
     }
   } catch (RepositoryException re) {
     log.error("Exception while looking up authorizable resource.", re);
   }
   return null;
 }
  public void initDefaultUsers() {
    Session session = null;
    try {
      session = repository.loginAdministrative(null);
      UserManager userManager = AccessControlUtil.getUserManager(session);

      // Apply default user properties from JSON files.
      Pattern fileNamePattern = Pattern.compile("/users/|\\.json");
      @SuppressWarnings("rawtypes")
      Enumeration entriesEnum = bundle.findEntries("users", "*.json", true);
      while (entriesEnum.hasMoreElements()) {
        Object entry = entriesEnum.nextElement();
        URL jsonUrl = new URL(entry.toString());
        String jsonFileName = jsonUrl.getFile();
        String authorizableId = fileNamePattern.matcher(jsonFileName).replaceAll("");
        Authorizable authorizable = userManager.getAuthorizable(authorizableId);
        if (authorizable != null) {
          applyJsonToAuthorizable(jsonUrl, authorizable, session);
          LOGGER.info("Initialized default authorizable {}", authorizableId);
        } else {
          LOGGER.warn("Configured default authorizable {} not found", authorizableId);
        }
      }
    } catch (RepositoryException e) {
      LOGGER.error("Could not configure default authorizables", e);
    } catch (IOException e) {
      LOGGER.error("Could not configure default authorizables", e);
    } finally {
      if (session != null) {
        session.logout();
      }
    }
  }
  /**
   * KERN-1026 changed the results of this to be the authz's that are members of the managers group
   * associated to a group rather than the group managers associated to the group.
   *
   * <p><del>Get the managers for a group. These should be stored in the {@link
   * UserConstants#PROP_GROUP_MANAGERS}.</del>
   *
   * @param request
   * @param group
   * @param writer
   * @throws RepositoryException
   * @throws JSONException
   */
  protected TreeMap<String, Authorizable> getManagers(
      SlingHttpServletRequest request, Group group, Comparator<String> comparator)
      throws RepositoryException, JSONException {
    TreeMap<String, Authorizable> map = new TreeMap<String, Authorizable>(comparator);

    // KERN-949 will probably change this.
    // note above was made before this was changed to retrieving members of the managers
    // group and may not apply.
    Session session = request.getResourceResolver().adaptTo(Session.class);
    UserManager um = AccessControlUtil.getUserManager(session);
    Value[] managersGroup = group.getProperty(UserConstants.PROP_MANAGERS_GROUP);
    if (managersGroup != null && managersGroup.length == 1) {
      String mgrGroupName = managersGroup[0].getString();

      Group mgrGroup = (Group) um.getAuthorizable(mgrGroupName);

      Iterator<Authorizable> members = mgrGroup.getMembers();
      while (members.hasNext()) {
        Authorizable member = members.next();
        String prinName = member.getPrincipal().getName();
        Authorizable mau = um.getAuthorizable(prinName);
        String name = getName(mau);
        map.put(name, mau);
      }
    }
    return map;
  }
  protected void refreshMemberAccess(
      Session session, String filePath, Principal principal, Node memberNode)
      throws RepositoryException {
    // Determine the new privileges for this principal.
    String[] privileges;
    if (memberNode.hasProperty(POOLED_CONTENT_USER_MANAGER)) {
      privileges = MANAGER_PRIVILEGES;
    } else if (memberNode.hasProperty(POOLED_CONTENT_USER_VIEWER)) {
      privileges = VIEWER_PRIVILEGES;
    } else {
      privileges = null;
    }

    // Completely replace any existing privileges for this principal.
    String[] removeAll = {JCR_ALL};
    AccessControlUtil.replaceAccessControlEntry(
        session, filePath, principal, privileges, null, removeAll, null);

    // We also need to set rights on the members node itself to avoid conflicts
    // with an ACE that keeps the EveryonePrincipal from seeing the list
    // of viewers and managers.
    AccessControlUtil.replaceAccessControlEntry(
        session, getMembersPath(filePath), principal, privileges, null, removeAll, null);
  }
  /*
   * (non-Javadoc)
   * @see
   * org.apache.sling.api.resource.ResourceProvider#listChildren(org.apache
   * .sling.api.resource.Resource)
   */
  public Iterator<Resource> listChildren(Resource parent) {
    if (parent == null) {
      throw new NullPointerException("parent is null");
    }
    try {
      String path = parent.getPath();
      ResourceResolver resourceResolver = parent.getResourceResolver();

      // handle children of /system/userManager
      if (SYSTEM_USER_MANAGER_PATH.equals(path)) {
        List<Resource> resources = new ArrayList<Resource>();
        if (resourceResolver != null) {
          resources.add(getResource(resourceResolver, SYSTEM_USER_MANAGER_USER_PATH));
          resources.add(getResource(resourceResolver, SYSTEM_USER_MANAGER_GROUP_PATH));
        }
        return resources.iterator();
      }

      int searchType = -1;
      if (SYSTEM_USER_MANAGER_USER_PATH.equals(path)) {
        searchType = PrincipalManager.SEARCH_TYPE_NOT_GROUP;
      } else if (SYSTEM_USER_MANAGER_GROUP_PATH.equals(path)) {
        searchType = PrincipalManager.SEARCH_TYPE_GROUP;
      }
      if (searchType != -1) {
        PrincipalIterator principals = null;

        // TODO: this actually does not work correctly since the
        // jackrabbit findPrincipals API
        // currently does an exact match of the search filter so it
        // won't match a wildcard
        Session session = resourceResolver.adaptTo(Session.class);
        if (session != null) {
          PrincipalManager principalManager = AccessControlUtil.getPrincipalManager(session);
          principals =
              principalManager.findPrincipals(".*", PrincipalManager.SEARCH_TYPE_NOT_GROUP);
        }

        if (principals != null) {
          return new ChildrenIterator(parent, principals);
        }
      }
    } catch (RepositoryException re) {
      throw new SlingException("Error listing children of resource: " + parent.getPath(), re);
    }

    return null;
  }
  /**
   * {@inheritDoc}
   *
   * @see
   *     org.sakaiproject.nakamura.api.search.SearchResultProcessor#writeNode(org.apache.sling.api.SlingHttpServletRequest,
   *     org.apache.sling.commons.json.io.JSONWriter,
   *     org.sakaiproject.nakamura.api.search.Aggregator, javax.jcr.query.Row)
   */
  public void writeNode(
      SlingHttpServletRequest request, JSONWriter write, Aggregator aggregator, Row row)
      throws JSONException, RepositoryException {

    write.object();
    Node node = row.getNode();
    write.key("jcr:created");
    write.value(node.getProperty("jcr:created").getString());
    String userID = node.getName();
    UserManager um = AccessControlUtil.getUserManager(node.getSession());
    Authorizable au = um.getAuthorizable(userID);
    if (au != null) {
      ValueMap map = profileService.getCompactProfileMap(au, node.getSession());
      ((ExtendedJSONWriter) write).valueMapInternals(map);
    }
    write.endObject();
  }
  /*
   * (non-Javadoc)
   * @see
   * org.apache.sling.api.resource.ResourceProvider#getResource(org.apache
   * .sling.api.resource.ResourceResolver, java.lang.String)
   */
  public Resource getResource(ResourceResolver resourceResolver, String path) {

    // handle resources for the virtual container resources
    if (path.equals(SYSTEM_USER_MANAGER_PATH)) {
      return new SyntheticResource(resourceResolver, path, "sling/userManager");
    } else if (path.equals(SYSTEM_USER_MANAGER_USER_PATH)) {
      return new SyntheticResource(resourceResolver, path, "sling/users");
    } else if (path.equals(SYSTEM_USER_MANAGER_GROUP_PATH)) {
      return new SyntheticResource(resourceResolver, path, "sling/groups");
    }

    // the principalId should be the first segment after the prefix
    String pid = null;
    if (path.startsWith(SYSTEM_USER_MANAGER_USER_PREFIX)) {
      pid = path.substring(SYSTEM_USER_MANAGER_USER_PREFIX.length());
    } else if (path.startsWith(SYSTEM_USER_MANAGER_GROUP_PREFIX)) {
      pid = path.substring(SYSTEM_USER_MANAGER_GROUP_PREFIX.length());
    }

    if (pid != null) {
      if (pid.indexOf('/') != -1) {
        return null; // something bogus on the end of the path so bail
        // out now.
      }
      try {
        Session session = resourceResolver.adaptTo(Session.class);
        if (session != null) {
          UserManager userManager = AccessControlUtil.getUserManager(session);
          if (userManager != null) {
            Authorizable authorizable = userManager.getAuthorizable(pid);
            if (authorizable != null) {
              // found the Authorizable, so return the resource
              // that wraps it.
              return new SakaiAuthorizableResource(authorizable, resourceResolver, path);
            }
          }
        }
      } catch (RepositoryException re) {
        throw new SlingException("Error looking up Authorizable for principal: " + pid, re);
      }
    }
    return null;
  }
Beispiel #10
0
  /**
   * 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()
          });
    }
  }
 /**
  * Checks to see if the current user is a member of the administrators group.
  *
  * @param session
  * @return
  * @throws UnsupportedRepositoryOperationException
  * @throws RepositoryException
  */
 protected static boolean isAdminUser(final Session session)
     throws UnsupportedRepositoryOperationException, RepositoryException {
   final AccessControlManager acm = AccessControlUtil.getAccessControlManager(session);
   final Privilege[] privJcrAll = {acm.privilegeFromName(Privilege.JCR_ALL)};
   return acm.hasPrivileges("/", privJcrAll);
 }
  /*
   * (non-Javadoc)
   * @see
   * org.apache.sling.jackrabbit.usermanager.post.AbstractAuthorizablePostServlet
   * #handleOperation(org.apache.sling.api.SlingHttpServletRequest,
   * org.apache.sling.api.servlets.HtmlResponse, java.util.List)
   */
  @Override
  protected void handleOperation(
      SlingHttpServletRequest request, HtmlResponse response, List<Modification> changes)
      throws RepositoryException {
    // make sure user self-registration is enabled
    if (!selfRegistrationEnabled) {
      throw new RepositoryException(
          "Sorry, registration of new users is not currently enabled.  Please try again later.");
    }

    Session session = request.getResourceResolver().adaptTo(Session.class);
    if (session == null) {
      throw new RepositoryException("JCR Session not found");
    }

    // check that the submitted parameter values have valid values.
    String principalName = request.getParameter(SlingPostConstants.RP_NODE_NAME);
    if (principalName == null) {
      throw new RepositoryException("User name was not submitted");
    }
    String pwd = request.getParameter("pwd");
    if (pwd == null) {
      throw new RepositoryException("Password was not submitted");
    }
    String pwdConfirm = request.getParameter("pwdConfirm");
    if (!pwd.equals(pwdConfirm)) {
      throw new RepositoryException("Password value does not match the confirmation password");
    }

    Session selfRegSession = null;
    try {
      selfRegSession = getSession();

      UserManager userManager = AccessControlUtil.getUserManager(selfRegSession);
      Authorizable authorizable = userManager.getAuthorizable(principalName);

      if (authorizable != null) {
        // user already exists!
        throw new RepositoryException(
            "A principal already exists with the requested name: " + principalName);
      } else {
        Map<String, RequestProperty> reqProperties = collectContent(request, response);

        User user = userManager.createUser(principalName, digestPassword(pwd));
        String userPath =
            AuthorizableResourceProvider.SYSTEM_USER_MANAGER_USER_PREFIX + user.getID();

        response.setPath(userPath);
        response.setLocation(externalizePath(request, userPath));
        response.setParentLocation(
            externalizePath(request, AuthorizableResourceProvider.SYSTEM_USER_MANAGER_USER_PATH));
        changes.add(Modification.onCreated(userPath));

        // write content from form
        writeContent(selfRegSession, user, reqProperties, changes);

        if (selfRegSession.hasPendingChanges()) {
          selfRegSession.save();
        }
      }
    } finally {
      ungetSession(selfRegSession);
    }
  }
  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);
    }
  }