private Group getPeerGroupOf( Group group, AuthorizableManager authorizableManager, Map<String, Object> toSave) throws AccessDeniedException, StorageClientException { Group peerGroup = null; if (group.hasProperty(UserConstants.PROP_MANAGERS_GROUP)) { String managersGroupId = (String) group.getProperty(UserConstants.PROP_MANAGERS_GROUP); if (group.getId().equals(managersGroupId)) { return group; } peerGroup = (Group) toSave.get(managersGroupId); if (peerGroup == null) { if (LOGGER.isDebugEnabled()) { LOGGER.debug( "For {} Not in toSave List loading Managers Group from store {} ", group.getId(), managersGroupId); } peerGroup = (Group) authorizableManager.findAuthorizable(managersGroupId); } else { if (LOGGER.isDebugEnabled()) { LOGGER.debug( "For {} got Managers Group from save list {} ", group.getId(), managersGroupId); } } } else if (group.hasProperty(UserConstants.PROP_MANAGED_GROUP)) { String managedGroupId = (String) group.getProperty(UserConstants.PROP_MANAGED_GROUP); if (group.getId().equals(managedGroupId)) { return group; } peerGroup = (Group) toSave.get(managedGroupId); if (peerGroup == null) { if (LOGGER.isDebugEnabled()) { LOGGER.debug( "For {} Not in toSave List loading Managed Group from store {} ", group.getId(), managedGroupId); } peerGroup = (Group) authorizableManager.findAuthorizable(managedGroupId); } else { if (LOGGER.isDebugEnabled()) { LOGGER.debug( "For {} got Managed Group from save list {} ", group.getId(), managedGroupId); } } } return peerGroup; }
@Before public void setUp() throws Exception { provider = new MyRelatedGroupsPropertyProvider(searchServiceFactory); when(request.getRemoteUser()).thenReturn("user1"); when(repo.loginAdministrative()).thenReturn(session); when(session.getAuthorizableManager()).thenReturn(authMgr); when(authMgr.findAuthorizable("user1")).thenReturn(auth1); Group group1 = mock(Group.class); when(group1.getId()).thenReturn("group1"); when(group1.getProperty(GROUP_TITLE_PROPERTY)).thenReturn("Group 1 Test"); when(group1.getProperty("sakai:tag-uuid")).thenReturn(new String[] {"123-456"}); when(auth1.memberOf(authMgr)).thenReturn(Sets.newHashSet(group1).iterator()); when(searchServiceFactory.getSearchResultSet(eq(request), any(Query.class))).thenReturn(rs); }
/** * @param request The request that contains the authorizables. * @param group The group that should be modified. * @param propertyName The name of the property on the group where the authorizable IDs should be * added/deleted. * @param paramName The name of the parameter that contains the authorizable IDs. ie: :manager or * :viewer. If :manager is specified, :manager@Delete will be used for deletes. * @param extraPropertyValues An array of authorizable IDs that should be added as well. * @param toSave * @throws RepositoryException */ protected void handleAuthorizablesOnProperty( SlingHttpServletRequest request, Group group, String propertyName, String paramName, String[] extraPropertyValues, Map<String, Object> toSave) { Set<String> propertyValueSet = new HashSet<String>(); if (group.hasProperty(propertyName)) { String[] existingProperties = (String[]) group.getProperty(propertyName); for (String property : existingProperties) { propertyValueSet.add(property); } } boolean changed = false; // Remove all the managers that are in the :manager@Delete request parameter. String[] propertiesToDelete = request.getParameterValues(paramName + SlingPostConstants.SUFFIX_DELETE); if (propertiesToDelete != null) { for (String propertyToDelete : propertiesToDelete) { propertyValueSet.remove(propertyToDelete); changed = true; } } // Add the new ones (if any) String[] proeprtiesToAdd = request.getParameterValues(paramName); if (proeprtiesToAdd != null) { for (String propertyToAdd : proeprtiesToAdd) { propertyValueSet.add(propertyToAdd); changed = true; } } // Add the extra ones (if any.) if (extraPropertyValues != null) { for (String propertyValue : extraPropertyValues) { propertyValueSet.add(propertyValue); changed = true; } } // Write the property. if (changed) { group.setProperty( propertyName, propertyValueSet.toArray(new String[propertyValueSet.size()])); if (LOGGER.isDebugEnabled()) { LOGGER.debug("Adding to save Queue {} {}", group.getId(), group.getSafeProperties()); } toSave.put(group.getId(), group); } }
@Override protected TreeMap<String, Group> getGroups( Authorizable member, AuthorizableManager userManager, SlingHttpServletRequest request) throws StorageClientException, AccessDeniedException { TreeMap<String, Group> managedGroups = new TreeMap<String, Group>(); Iterator<Group> allGroupsIter = member.memberOf(userManager); for (String principal : member.getPrincipals()) { Group group = (Group) userManager.findAuthorizable(principal); if (group != null && !group.getId().equals(Group.EVERYONE)) { boolean isManager = false; if (isPseudoGroup(group) && isManagerGroup(group, userManager)) { // The group we want is the child of the pseudo group isManager = true; group = (Group) userManager.findAuthorizable( (String) group.getProperty(UserConstants.PROP_PSEUDO_GROUP_PARENT)); } else { for (String managerId : StorageClientUtils.nonNullStringArray( (String[]) group.getProperty(UserConstants.PROP_GROUP_MANAGERS))) { if (member.getId().equals(managerId)) { isManager = true; break; } } } if (isManager) { final String category = stringRequestParameter(request, "category", null); if (category == null) { // no filtering managedGroups.put(group.getId(), group); } else { // KERN-1865 category filter if (category.equals(group.getProperty("sakai:category"))) { managedGroups.put(group.getId(), group); } } } } } return managedGroups; }
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")); } } }
@SuppressWarnings("unchecked") public void onMessage(Message message) { log.debug("Receiving a message on {} : {}", SyncJMSMessageProducer.QUEUE_NAME, message); try { String topic = message.getJMSType(); String groupId = (String) message.getStringProperty("path"); String operation = "UNKNOWN"; // A group was DELETED if ("org/sakaiproject/nakamura/lite/authorizables/DELETE".equals(topic) && config.getDeletesEnabled()) { Map<String, Object> attributes = (Map<String, Object>) message.getObjectProperty(StoreListener.BEFORE_EVENT_PROPERTY); grouperManager.deleteGroup(groupId, attributes); operation = "DELETED"; } // A new group was ADDED or an existing group was UPDATED if ("org/sakaiproject/nakamura/lite/authorizables/ADDED".equals(topic) || "org/sakaiproject/nakamura/lite/authorizables/UPDATED".equals(topic)) { // These events should be under org/sakaiproject/nakamura/lite/authorizables/UPDATED // http://jira.sakaiproject.org/browse/KERN-1795 String membersAdded = (String) message.getStringProperty(GrouperEventUtils.MEMBERS_ADDED_PROP); if (membersAdded != null) { // membership adds can be attached to the same event for the group add. grouperManager.createGroup(groupId, config.getGroupTypes()); grouperManager.addMemberships( groupId, Arrays.asList(StringUtils.split(membersAdded, ","))); operation = "ADD_MEMBERS"; } String membersRemoved = (String) message.getStringProperty(GrouperEventUtils.MEMBERS_REMOVED_PROP); if (membersRemoved != null) { grouperManager.removeMemberships( groupId, Arrays.asList(StringUtils.split(membersRemoved, ","))); operation = "REMOVE_MEMBERS"; } if (membersAdded == null && membersRemoved == null) { org.sakaiproject.nakamura.api.lite.Session repositorySession = repository.loginAdministrative(); AuthorizableManager am = repositorySession.getAuthorizableManager(); Group group = (Group) am.findAuthorizable(groupId); repositorySession.logout(); if (groupId.startsWith(ContactsGrouperNameProviderImpl.CONTACTS_GROUPID_PREFIX)) { // TODO Why are we not getting added and removed properties on the Message grouperManager.createGroup(groupId, null); grouperManager.addMemberships(groupId, Arrays.asList(group.getMembers())); operation = "UPDATE CONTACTS"; } else { grouperManager.createGroup(groupId, config.getGroupTypes()); grouperManager.addMemberships(groupId, Arrays.asList(group.getMembers())); operation = "CREATE"; } } } // The message was processed successfully. No exceptions were thrown. // We acknowledge the message and its removed from the queue message.acknowledge(); // We got a message that we didn't know what to do with. if (operation.equals("UNKNOWN")) { log.error( "I don't know what to do with this topic: {}. Turn on debug logs to see the message.", topic); log.debug(message.toString()); } else { log.info("Successfully processed and acknowledged. {}, {}", operation, groupId); log.debug(message.toString()); } } catch (JMSException jmse) { log.error("JMSException while processing message.", jmse); } catch (Exception e) { log.error("Exception while processing message.", e); } }