Example #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;
  }
  protected void updateGroupMembership(
      SlingHttpServletRequest request,
      Session session,
      Authorizable authorizable,
      String paramName,
      List<Modification> changes,
      Map<String, Object> toSave)
      throws AccessDeniedException, StorageClientException {
    if (authorizable instanceof Group) {
      Group group = ((Group) authorizable);
      String groupPath =
          LiteAuthorizableResourceProvider.SYSTEM_USER_MANAGER_GROUP_PREFIX + group.getId();

      boolean changed = false;

      AuthorizableManager authorizableManager = session.getAuthorizableManager();

      // first remove any members posted as ":member@Delete"
      String[] membersToDelete =
          request.getParameterValues(paramName + SlingPostConstants.SUFFIX_DELETE);
      if (membersToDelete != null) {
        toSave.put(group.getId(), group);
        LOGGER.info("Members to delete {} ", membersToDelete);
        for (String member : membersToDelete) {
          String memberId = getAuthIdFromParameter(member);
          group.removeMember(memberId);
          changed = true;
        }
      }

      Joinable groupJoin = getJoinable(group);

      // second add any members posted as ":member"
      String[] membersToAdd = request.getParameterValues(paramName);
      if (membersToAdd != null) {
        LOGGER.info("Members to add {} ", membersToAdd);
        Group peerGroup = getPeerGroupOf(group, authorizableManager, toSave);
        List<Authorizable> membersToRemoveFromPeer = new ArrayList<Authorizable>();
        for (String member : membersToAdd) {
          String memberId = getAuthIdFromParameter(member);
          Authorizable memberAuthorizable = (Authorizable) toSave.get(memberId);
          if (memberAuthorizable == null) {
            memberAuthorizable = authorizableManager.findAuthorizable(memberId);
          }
          if (memberAuthorizable != null) {
            if (!User.ADMIN_USER.equals(session.getUserId())
                && !UserConstants.ANON_USERID.equals(session.getUserId())
                && Joinable.yes.equals(groupJoin)
                && memberAuthorizable.getId().equals(session.getUserId())) {
              LOGGER.debug("Is Joinable {} {} ", groupJoin, session.getUserId());
              // we can grab admin session since group allows all users to join
              Session adminSession = getSession();
              try {
                AuthorizableManager adminAuthorizableManager =
                    adminSession.getAuthorizableManager();
                Group adminAuthGroup =
                    (Group) adminAuthorizableManager.findAuthorizable(group.getId());
                if (adminAuthGroup != null) {
                  adminAuthGroup.addMember(memberAuthorizable.getId());
                  adminAuthorizableManager.updateAuthorizable(adminAuthGroup);
                  changed = true;
                }
              } finally {
                ungetSession(adminSession);
              }
            } else {
              LOGGER.info(
                  "Group {} is not Joinable: User {} adding {}  ",
                  new Object[] {
                    group.getId(), session.getUserId(), memberAuthorizable.getId(),
                  });
              // group is restricted, so use the current user's authorization
              // to add the member to the group:

              group.addMember(memberAuthorizable.getId());
              if (LOGGER.isInfoEnabled()) {
                LOGGER.info(
                    "{} Membership now {} {} {}",
                    new Object[] {
                      group.getId(),
                      Arrays.toString(group.getMembers()),
                      Arrays.toString(group.getMembersAdded()),
                      Arrays.toString(group.getMembersRemoved())
                    });
              }
              toSave.put(group.getId(), group);
              Group gt = (Group) toSave.get(group.getId());
              if (LOGGER.isInfoEnabled()) {
                LOGGER.info(
                    "{} Membership now {} {} {}",
                    new Object[] {
                      group.getId(),
                      Arrays.toString(gt.getMembers()),
                      Arrays.toString(gt.getMembersAdded()),
                      Arrays.toString(gt.getMembersRemoved())
                    });
              }
              changed = true;
            }
            if (peerGroup != null && peerGroup.getId() != group.getId()) {
              Set<String> members = ImmutableSet.of(peerGroup.getMembers());
              if (members.contains(memberAuthorizable.getId())) {
                membersToRemoveFromPeer.add(memberAuthorizable);
              }
            }
          } else {
            LOGGER.warn("member not found {} ", memberId);
          }
        }
        if ((peerGroup != null) && (membersToRemoveFromPeer.size() > 0)) {
          for (Authorizable member : membersToRemoveFromPeer) {
            if (LOGGER.isInfoEnabled()) {
              LOGGER.info("Removing Member {} from {} ", member.getId(), peerGroup.getId());
            }
            peerGroup.removeMember(member.getId());
          }
          toSave.put(peerGroup.getId(), peerGroup);
          if (LOGGER.isInfoEnabled()) {
            LOGGER.info(
                "{} Just Updated Peer Group Membership now {} {} {}",
                new Object[] {
                  peerGroup.getId(),
                  Arrays.toString(peerGroup.getMembers()),
                  Arrays.toString(peerGroup.getMembersAdded()),
                  Arrays.toString(peerGroup.getMembersRemoved())
                });
          }
        }
      }

      if (changed) {
        // add an entry to the changes list to record the membership
        // change
        changes.add(Modification.onModified(groupPath + "/members"));
      }
    }
  }