Java tutorial
/* * Licensed to The Apereo Foundation under one or more contributor license * agreements. See the NOTICE file distributed with this work for * additional information regarding copyright ownership. * * The Apereo Foundation licenses this file to you under the Educational * Community License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of the * License at: * * http://opensource.org/licenses/ecl2.txt * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.sakaiproject.roster.impl; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.commons.lang.ArrayUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.sakaiproject.api.privacy.PrivacyManager; import org.sakaiproject.authz.api.AuthzGroup; import org.sakaiproject.authz.api.FunctionManager; import org.sakaiproject.authz.api.GroupProvider; import org.sakaiproject.authz.api.Member; import org.sakaiproject.authz.api.Role; import org.sakaiproject.authz.api.SecurityService; import org.sakaiproject.component.api.ServerConfigurationService; import org.sakaiproject.coursemanagement.api.CourseManagementService; import org.sakaiproject.coursemanagement.api.Enrollment; import org.sakaiproject.coursemanagement.api.EnrollmentSet; import org.sakaiproject.coursemanagement.api.Section; import org.sakaiproject.exception.IdUnusedException; import org.sakaiproject.memory.api.Cache; import org.sakaiproject.memory.api.MemoryService; import org.sakaiproject.memory.api.SimpleConfiguration; import org.sakaiproject.profile2.logic.ProfileConnectionsLogic; import org.sakaiproject.roster.api.RosterEnrollment; import org.sakaiproject.roster.api.RosterFunctions; import org.sakaiproject.roster.api.RosterGroup; import org.sakaiproject.roster.api.RosterMember; import org.sakaiproject.roster.api.RosterMemberComparator; import org.sakaiproject.roster.api.RosterSite; import org.sakaiproject.roster.api.SakaiProxy; import org.sakaiproject.site.api.Group; import org.sakaiproject.site.api.Site; import org.sakaiproject.site.api.SiteService; import org.sakaiproject.tool.api.SessionManager; import org.sakaiproject.tool.api.ToolManager; import org.sakaiproject.user.api.User; import org.sakaiproject.user.api.UserDirectoryService; import org.sakaiproject.user.api.UserNotDefinedException; import org.sakaiproject.util.ResourceLoader; import lombok.Setter; /** * <code>SakaiProxy</code> acts as a proxy between Roster and Sakai components. * * @author Daniel Robinson (d.b.robinson@lancaster.ac.uk) * @author Adrian Fish (a.fish@lancaster.ac.uk) */ @Setter public class SakaiProxyImpl implements SakaiProxy { private static final Log log = LogFactory.getLog(SakaiProxyImpl.class); private CourseManagementService courseManagementService; private FunctionManager functionManager; private GroupProvider groupProvider; private PrivacyManager privacyManager; private MemoryService memoryService; private ProfileConnectionsLogic connectionsLogic; private SecurityService securityService; private ServerConfigurationService serverConfigurationService; private SessionManager sessionManager; private SiteService siteService; private ToolManager toolManager; private UserDirectoryService userDirectoryService; private RosterMemberComparator memberComparator; public void init() { List<String> registered = functionManager.getRegisteredFunctions(); if (!registered.contains(RosterFunctions.ROSTER_FUNCTION_EXPORT)) { functionManager.registerFunction(RosterFunctions.ROSTER_FUNCTION_EXPORT, true); } if (!registered.contains(RosterFunctions.ROSTER_FUNCTION_VIEWALL)) { functionManager.registerFunction(RosterFunctions.ROSTER_FUNCTION_VIEWALL, true); } if (!registered.contains(RosterFunctions.ROSTER_FUNCTION_VIEWHIDDEN)) { functionManager.registerFunction(RosterFunctions.ROSTER_FUNCTION_VIEWHIDDEN, true); } if (!registered.contains(RosterFunctions.ROSTER_FUNCTION_VIEWGROUP)) { functionManager.registerFunction(RosterFunctions.ROSTER_FUNCTION_VIEWGROUP, true); } if (!registered.contains(RosterFunctions.ROSTER_FUNCTION_VIEWENROLLMENTSTATUS)) { functionManager.registerFunction(RosterFunctions.ROSTER_FUNCTION_VIEWENROLLMENTSTATUS, true); } if (!registered.contains(RosterFunctions.ROSTER_FUNCTION_VIEWPROFILE)) { functionManager.registerFunction(RosterFunctions.ROSTER_FUNCTION_VIEWPROFILE, true); } if (!registered.contains(RosterFunctions.ROSTER_FUNCTION_VIEWEMAIL)) { functionManager.registerFunction(RosterFunctions.ROSTER_FUNCTION_VIEWEMAIL, true); } if (!registered.contains(RosterFunctions.ROSTER_FUNCTION_VIEWOFFICIALPHOTO)) { functionManager.registerFunction(RosterFunctions.ROSTER_FUNCTION_VIEWOFFICIALPHOTO, true); } memberComparator = new RosterMemberComparator(getFirstNameLastName()); } /** * {@inheritDoc} */ public boolean isSuperUser() { return securityService.isSuperUser(); } public Site getSite(String siteId) { try { return siteService.getSite(siteId); } catch (IdUnusedException e) { log.warn("site not found: " + e.getId()); return null; } } /** * {@inheritDoc} */ public String getCurrentUserId() { return sessionManager.getCurrentSessionUserId(); } /** * {@inheritDoc} */ public String getCurrentSiteId() { return toolManager.getCurrentPlacement().getContext(); } /** * {@inheritDoc} */ public String getCurrentSiteLocale() { String siteId = toolManager.getCurrentPlacement().getContext(); Site currentSite = getSite(siteId); if (currentSite != null) { String locale = currentSite.getProperties().getProperty("locale_string"); if (locale != null) { return locale; } } return null; } /** * {@inheritDoc} */ public Integer getDefaultRosterState() { return serverConfigurationService.getInt("roster.defaultState", DEFAULT_ROSTER_STATE); } /** * {@inheritDoc} */ public String getDefaultRosterStateString() { Integer defaultRosterState = getDefaultRosterState(); if (defaultRosterState > -1 && defaultRosterState < ROSTER_STATES.length - 1) { return ROSTER_STATES[defaultRosterState]; } else { return ROSTER_STATES[DEFAULT_ROSTER_STATE]; } } /** * {@inheritDoc} */ public String getDefaultSortColumn() { return serverConfigurationService.getString("roster.defaultSortColumn", DEFAULT_SORT_COLUMN); } /** * {@inheritDoc} */ public Boolean getFirstNameLastName() { return serverConfigurationService.getBoolean("roster.display.firstNameLastName", DEFAULT_FIRST_NAME_LAST_NAME); } /** * {@inheritDoc} */ public Boolean getHideSingleGroupFilter() { return serverConfigurationService.getBoolean("roster.display.hideSingleGroupFilter", DEFAULT_HIDE_SINGLE_GROUP_FILTER); } /** * {@inheritDoc} */ public Boolean getViewEmail() { return getViewEmail(getCurrentSiteId()); } /** * {@inheritDoc} */ public Boolean getViewEmail(String siteId) { //To view emails it first needs to be enabled in sakai.properties and the user must have the permission. if (serverConfigurationService.getBoolean("roster_view_email", DEFAULT_VIEW_EMAIL)) { return hasUserSitePermission(getCurrentUserId(), RosterFunctions.ROSTER_FUNCTION_VIEWEMAIL, siteId); } return false; } /** * {@inheritDoc} */ public Boolean getViewUserDisplayId() { return serverConfigurationService.getBoolean("roster.display.userDisplayId", DEFAULT_VIEW_USER_DISPLAY_ID); } public RosterMember getMember(String siteId, String userId, String enrollmentSetId) { User user = null; try { user = userDirectoryService.getUser(userId); } catch (UserNotDefinedException e) { log.error("User '" + userId + "' not found. Returning null ..."); return null; } Site site = null; try { site = siteService.getSite(siteId); } catch (IdUnusedException e) { log.error("Site '" + siteId + "' not found. Returning null ..."); return null; } if (enrollmentSetId != null) { // Get the cache Map<String, List<RosterMember>> membersMap = getAndCacheSortedEnrollmentSet(site, enrollmentSetId); if (membersMap != null) { List<RosterMember> members = membersMap.get(enrollmentSetId + "#all"); members = filterMembers(site, getCurrentUserId(), members, null); if (members != null) { for (RosterMember member : members) { if (member.getUserId().equals(userId)) { return member; } } } } else { log.error("Caching of enrollment set for site '" + siteId + "' and enrollmentset '" + enrollmentSetId + "' failed. Returning null ..."); } return null; } else { // Get the unfiltered memberships List<RosterMember> members = getAndCacheSortedMembership(site, null, null); members = filterMembers(site, getCurrentUserId(), members, null); for (RosterMember member : members) { if (member.getUserId().equals(userId)) { return member; } } return null; } } public List<User> getSiteUsers(String siteId) { Site site = null; try { site = siteService.getSite(siteId); } catch (IdUnusedException e) { log.error("Site '" + siteId + "' not found. Returning null ..."); return null; } return userDirectoryService.getUsers(site.getUsers()); } public List<RosterMember> getMembership(String currentUserId, String siteId, String groupId, String roleId, String enrollmentSetId, String enrollmentStatus) { if (currentUserId == null) { return null; } Site site = null; try { site = siteService.getSite(siteId); } catch (IdUnusedException e) { log.error("Site '" + siteId + "' not found. Returning null ..."); return null; } if (site.isType("course") && enrollmentSetId != null) { return getEnrollmentMembership(site, enrollmentSetId, enrollmentStatus, currentUserId); } else { List<RosterMember> rosterMembers = getAndCacheSortedMembership(site, groupId, roleId); rosterMembers = filterMembers(site, currentUserId, rosterMembers, groupId); return rosterMembers; } } private Map<String, User> getUserMap(Set<Member> members) { Map<String, User> userMap = new HashMap<String, User>(); Set<String> userIds = new HashSet<String>(); // Build a map of userId to role for (Member member : members) { if (member.isActive()) { userIds.add(member.getUserId()); } } // Get the user objects for (User user : userDirectoryService.getUsers(userIds)) { userMap.put(user.getId(), user); } return userMap; } /** * @return A mapping of RosterMember onto eid */ private Map<String, RosterMember> getMembershipMapped(Site site, String groupId) { Map<String, RosterMember> rosterMembers = new HashMap<String, RosterMember>(); String userId = getCurrentUserId(); Set<Member> membership = getUnfilteredMembers(groupId, site); if (membership == null) { return null; } Map<String, User> userMap = getUserMap(membership); Collection<Group> groups = site.getGroups(); for (Member member : membership) { try { RosterMember rosterMember = getRosterMember(userMap, groups, member, site); rosterMembers.put(rosterMember.getEid(), rosterMember); } catch (UserNotDefinedException e) { log.warn("user not found: " + e.getId()); } } return rosterMembers; } private List<RosterMember> filterMembers(Site site, String currentUserId, List<RosterMember> unfiltered, String groupId) { List<RosterMember> filtered = new ArrayList<RosterMember>(); if (isAllowed(currentUserId, RosterFunctions.ROSTER_FUNCTION_VIEWALL, site.getReference())) { if (groupId == null) { filtered.addAll(filterHiddenMembers(unfiltered, currentUserId, site.getId(), site)); } else { Group group = site.getGroup(groupId); if (group != null) { // get all members of requested groupId filtered.addAll(filterHiddenMembers(unfiltered, currentUserId, site.getId(), group)); } else { // assume invalid groupId specified return null; } } } else { if (groupId == null) { // get all members of groups current user is allowed to view for (Group group : site.getGroups()) { if (isAllowed(currentUserId, RosterFunctions.ROSTER_FUNCTION_VIEWGROUP, group.getReference())) { filtered.addAll(filterHiddenMembers(unfiltered, currentUserId, site.getId(), group)); } } } else if (null != site.getGroup(groupId)) { // get all members of requested groupId if current user is // member Group group = site.getGroup(groupId); if (isAllowed(currentUserId, RosterFunctions.ROSTER_FUNCTION_VIEWGROUP, group.getReference())) { filtered.addAll(filterHiddenMembers(unfiltered, currentUserId, site.getId(), group)); } } else { // assume invalid groupId specified or user not member return null; } } if (log.isDebugEnabled()) log.debug("membership.size(): " + filtered.size()); //remove duplicates. Yes, its a Set but there can be dupes because its storing objects and from multiple groups. Set<String> check = new HashSet<String>(); List<RosterMember> cleanedMembers = new ArrayList<RosterMember>(); for (RosterMember m : filtered) { if (check.add(m.getUserId())) { cleanedMembers.add(m); // Now strip out any unauthorised info if (!isAllowed(currentUserId, RosterFunctions.ROSTER_FUNCTION_VIEWEMAIL, site.getReference())) { m.setEmail(null); } } } if (log.isDebugEnabled()) log.debug("cleanedMembers.size(): " + cleanedMembers.size()); return cleanedMembers; } @SuppressWarnings("unchecked") private List<RosterMember> filterHiddenMembers(List<RosterMember> members, String currentUserId, String siteId, AuthzGroup authzGroup) { log.debug("filterHiddenMembers"); if (isAllowed(currentUserId, RosterFunctions.ROSTER_FUNCTION_VIEWHIDDEN, authzGroup.getReference())) { log.debug("permission to view all, including hidden"); return members; } List<RosterMember> filtered = new ArrayList<RosterMember>(); Set<String> userIds = new HashSet<String>(); for (Iterator<RosterMember> i = members.iterator(); i.hasNext();) { RosterMember member = i.next(); userIds.add(member.getEid()); // If this member is not in the authzGroup, remove them. if (authzGroup.getMember(member.getUserId()) == null) { i.remove(); } } Set<String> hiddenUserIds = privacyManager.findHidden("/site/" + siteId, userIds); //get the list of visible roles, optional config. //if set, the only users visible in the tool will be those with their role defined in this list String[] visibleRoles = serverConfigurationService.getStrings("roster2.visibleroles"); boolean filterRoles = ArrayUtils.isNotEmpty(visibleRoles); if (log.isDebugEnabled()) log.debug("visibleRoles: " + ArrayUtils.toString(visibleRoles)); if (log.isDebugEnabled()) log.debug("filterRoles: " + filterRoles); // determine filtered membership for (RosterMember member : members) { // skip if privacy restricted if (hiddenUserIds.contains(member.getEid())) { continue; } // now filter out users based on their role if (filterRoles) { String memberRoleId = member.getRole(); if (ArrayUtils.contains(visibleRoles, memberRoleId)) { filtered.add(member); } } else { filtered.add(member); } } if (log.isDebugEnabled()) log.debug("filteredMembership.size(): " + filtered.size()); return filtered; } private Set<Member> getUnfilteredMembers(String groupId, Site site) { Set<Member> membership = new HashSet<Member>(); if (null == groupId) { // get all members membership.addAll(site.getMembers()); } else if (null != site.getGroup(groupId)) { // get all members of requested groupId membership.addAll(site.getGroup(groupId).getMembers()); } else { // assume invalid groupId specified return null; } return membership; } private RosterMember getRosterMember(Map<String, User> userMap, Collection<Group> groups, Member member, Site site) throws UserNotDefinedException { String userId = member.getUserId(); User user = userMap.get(userId); if (user == null) { throw new UserNotDefinedException(userId); } RosterMember rosterMember = new RosterMember(userId); rosterMember.setEid(user.getEid()); rosterMember.setDisplayId(member.getUserDisplayId()); rosterMember.setRole(member.getRole().getId()); rosterMember.setEmail(user.getEmail()); rosterMember.setDisplayName(user.getDisplayName()); rosterMember.setSortName(user.getSortName()); for (Group group : groups) { if (group.getMember(userId) != null) { rosterMember.addGroup(group.getId(), group.getTitle()); } } if (connectionsLogic != null) { rosterMember.setConnectionStatus(connectionsLogic.getConnectionStatus(getCurrentUserId(), userId)); } return rosterMember; } /** * Returns the enrollment set members for the specified site and enrollment * set. * * @param siteId the ID of the site. * @param enrollmentSetId the ID of the enrollment set. * @return the enrollment set members for the specified site and enrollment * set. */ private List<RosterMember> getEnrollmentMembership(Site site, String enrollmentSetId, String enrollmentStatusId, String currentUserId) { if (site == null) { return null; } if (!isAllowed(currentUserId, RosterFunctions.ROSTER_FUNCTION_VIEWENROLLMENTSTATUS, site.getReference())) { return null; } Map<String, List<RosterMember>> membersMap = getAndCacheSortedEnrollmentSet(site, enrollmentSetId); String key = (enrollmentStatusId == null) ? enrollmentSetId + "#all" : enrollmentSetId + "#" + enrollmentStatusId; if (log.isDebugEnabled()) { log.debug("Trying to get members list " + key + " from membersMap ..."); } List<RosterMember> members = membersMap.get(key); if (members != null) { return filterMembers(site, currentUserId, members, null); } else { log.error("No enrollment set"); return null; } } /** * Tries to retrieve the sorted list of members for the supplied site and * group. If there is no entry, the entire site and group membership is * cached and the requested list is returned. IT IS THE CALLER'S * RESPONSIBILITY TO FILTER ON AUTHZ RULES. */ private List<RosterMember> getAndCacheSortedMembership(Site site, String groupId, String roleId) { String siteId = site.getId(); Cache cache = getCache(MEMBERSHIPS_CACHE); String key = siteId; if (groupId != null) { key += "#" + groupId; } if (roleId != null) { key += "#" + roleId; } if (log.isDebugEnabled()) { log.debug("Key: " + key); } List<RosterMember> siteMembers = (List<RosterMember>) cache.get(key); if (siteMembers != null) { if (log.isDebugEnabled()) { log.debug("Cache hit on '" + key + "'."); } return siteMembers; } else { if (log.isDebugEnabled()) { log.debug("Cache miss on '" + key + "'."); } Set<Member> membership = site.getMembers(); if (null == membership) { return null; } Map<String, User> userMap = getUserMap(membership); siteMembers = new ArrayList<RosterMember>(); Collection<Group> groups = site.getGroups(); Set<Role> roles = site.getRoles(); // Precache an empty list for each site#group and each site#group#role for (Group group : groups) { String gId = group.getId(); cache.put(siteId + "#" + gId, new ArrayList<RosterMember>()); for (Role role : roles) { cache.put(siteId + "#" + gId + "#" + role.getId(), new ArrayList<RosterMember>()); } } // Same for site#role for (Role role : roles) { cache.put(siteId + "#" + role.getId(), new ArrayList<RosterMember>()); } for (Member member : membership) { try { RosterMember rosterMember = getRosterMember(userMap, groups, member, site); siteMembers.add(rosterMember); String memberRoleId = rosterMember.getRole(); for (String memberGroupId : rosterMember.getGroups().keySet()) { List<RosterMember> groupMembers = (List<RosterMember>) cache .get(siteId + "#" + memberGroupId); groupMembers.add(rosterMember); List<RosterMember> groupRoleMembers = (List<RosterMember>) cache .get(siteId + "#" + memberGroupId + "#" + memberRoleId); groupRoleMembers.add(rosterMember); } List<RosterMember> roleMembers = (List<RosterMember>) cache.get(siteId + "#" + memberRoleId); roleMembers.add(rosterMember); } catch (UserNotDefinedException e) { log.warn("user not found: " + e.getId()); } } // Sort the groups. They're already cached. for (Group group : groups) { String gId = group.getId(); Collections.sort((List<RosterMember>) cache.get(siteId + "#" + gId), memberComparator); for (Role role : roles) { Collections.sort((List<RosterMember>) cache.get(siteId + "#" + gId + "#" + role.getId()), memberComparator); } } // Sort the main site list Collections.sort(siteMembers, memberComparator); if (log.isDebugEnabled()) { log.debug("Caching on '" + siteId + "' ..."); } // Cache the main site list cache.put(siteId, siteMembers); return (List<RosterMember>) cache.get(key); } } /** * Tries to retrieve the members map for the supplied site. If there is no * map yet for the site, it is created. If the members map doesn't contain * the three lists for the specified enrollment set, #all, #wait, and * #enrolled, the entire enrollment set is retrieved and cached into those * three sections, pre-sorted. Finally, the entire site's members map is * returned and the caller can pull the bits they want. IT IS THE CALLER'S * RESPONSIBILITY TO FILTER ON AUTHZ RULES. */ private Map<String, List<RosterMember>> getAndCacheSortedEnrollmentSet(Site site, String enrollmentSetId) { String siteId = site.getId(); Cache cache = getCache(ENROLLMENTS_CACHE); if (log.isDebugEnabled()) { log.debug("Trying to get '" + siteId + "' from enrollments cache ..."); } Map<String, List<RosterMember>> membersMap = (Map<String, List<RosterMember>>) cache.get(siteId); if (membersMap == null) { if (log.isDebugEnabled()) { log.debug("Cache miss. Putting empty membersMap on " + siteId + " ..."); } membersMap = new HashMap<String, List<RosterMember>>(); cache.put(siteId, membersMap); } if (membersMap.containsKey(enrollmentSetId + "#all") && membersMap.containsKey(enrollmentSetId + "#wait") && membersMap.containsKey(enrollmentSetId + "#enrolled")) { if (log.isDebugEnabled()) { log.debug("Cache hit on '" + enrollmentSetId + "'"); } return membersMap; } else { if (log.isDebugEnabled()) { log.debug("Cache miss on '" + enrollmentSetId + "'"); } EnrollmentSet enrollmentSet = courseManagementService.getEnrollmentSet(enrollmentSetId); if (null == enrollmentSet) { return null; } Map<String, RosterMember> membership = getMembershipMapped(site, null); List<RosterMember> members = new ArrayList<RosterMember>(); List<RosterMember> waiting = new ArrayList<RosterMember>(); List<RosterMember> enrolled = new ArrayList<RosterMember>(); for (Enrollment enrollment : courseManagementService.getEnrollments(enrollmentSet.getEid())) { RosterMember member = membership.get(enrollment.getUserId()); member.setCredits(enrollment.getCredits()); String enrollmentStatusId = enrollment.getEnrollmentStatus(); member.setEnrollmentStatusId(enrollmentStatusId); //member.setEnrollmentStatus(statusCodes.get(enrollmentStatusId)); if (enrollmentStatusId.equals("wait")) { waiting.add(member); } else if (enrollmentStatusId.equals("enrolled")) { enrolled.add(member); } members.add(member); } Collections.sort(members, memberComparator); Collections.sort(waiting, memberComparator); Collections.sort(enrolled, memberComparator); if (log.isDebugEnabled()) { log.debug("Caching all enrollment set members on '" + enrollmentSetId + "#all' ..."); log.debug("Caching watlisted members on '" + enrollmentSetId + "#wait' ..."); log.debug("Caching enrolled members on '" + enrollmentSetId + "#enrolled' ..."); } membersMap.put(enrollmentSetId + "#all", members); membersMap.put(enrollmentSetId + "#wait", waiting); membersMap.put(enrollmentSetId + "#enrolled", enrolled); return membersMap; } } /** * {@inheritDoc} */ public RosterSite getRosterSite(String siteId) { String currentUserId = getCurrentUserId(); if (null == currentUserId) { log.debug("No currentUserId. Returning null ..."); return null; } if (log.isDebugEnabled()) log.debug("currentUserId: " + currentUserId); Site site = getSite(siteId); if (null == site) { log.debug("No site. Returning null ..."); return null; } if (log.isDebugEnabled()) log.debug("site: " + site.getId()); RosterSite rosterSite = new RosterSite(siteId); rosterSite.setTitle(site.getTitle()); rosterSite.setMembersTotal(site.getMembers().size()); List<RosterGroup> siteGroups = getViewableSiteGroups(currentUserId, site); if (0 == siteGroups.size()) { // to avoid IndexOutOfBoundsException in EB code rosterSite.setSiteGroups(null); } else { rosterSite.setSiteGroups(siteGroups); } Map<String, Integer> roleCounts = new HashMap<String, Integer>(); List<String> userRoles = new ArrayList<String>(); for (Role role : site.getRoles()) { String roleId = role.getId(); userRoles.add(roleId); roleCounts.put(roleId, site.getUsersHasRole(roleId).size()); } rosterSite.setRoleCounts(roleCounts); if (0 == userRoles.size()) { // to avoid IndexOutOfBoundsException in EB code rosterSite.setUserRoles(null); } else { rosterSite.setUserRoles(userRoles); } Map<String, String> statusCodes = courseManagementService .getEnrollmentStatusDescriptions(new ResourceLoader().getLocale()); rosterSite.setEnrollmentStatusCodes(statusCodes); if (null == groupProvider) { log.warn("no group provider installed"); // to avoid IndexOutOfBoundsException in EB code rosterSite.setSiteEnrollmentSets(null); return rosterSite; } List<RosterEnrollment> siteEnrollmentSets = getEnrollmentSets(siteId, groupProvider); if (0 == siteEnrollmentSets.size()) { // to avoid IndexOutOfBoundsException in EB code rosterSite.setSiteEnrollmentSets(null); } else { rosterSite.setSiteEnrollmentSets(siteEnrollmentSets); } return rosterSite; } private List<RosterGroup> getViewableSiteGroups(String currentUserId, Site site) { List<RosterGroup> siteGroups = new ArrayList<RosterGroup>(); boolean viewAll = isAllowed(currentUserId, RosterFunctions.ROSTER_FUNCTION_VIEWALL, site); Collection<Group> groupsCollection = site.getGroups(); Group[] groups = new Group[groupsCollection.size()]; groups = groupsCollection.toArray(groups); // TODO: change this to BaseGroup's comparator when KNL-1305 has been // fixed. Arrays.sort(groups, new Comparator<Group>() { public int compare(final Group lhs, final Group rhs) { // If the groups are the same, say so if (lhs == rhs) return 0; // start the compare by comparing their title int compare = lhs.getTitle().compareTo(rhs.getTitle()); // if these are the same if (compare == 0) { // sort based on (unique) id compare = lhs.getId().compareTo(rhs.getId()); } return compare; } }); for (Group group : groups) { if (viewAll || isAllowed(currentUserId, RosterFunctions.ROSTER_FUNCTION_VIEWGROUP, group.getReference())) { RosterGroup rosterGroup = new RosterGroup(group.getId()); rosterGroup.setTitle(group.getTitle()); List<String> userIds = new ArrayList<String>(); for (Member member : group.getMembers()) { userIds.add(member.getUserId()); } rosterGroup.setUserIds(userIds); siteGroups.add(rosterGroup); } } return siteGroups; } private List<RosterEnrollment> getEnrollmentSets(String siteId, GroupProvider groupProvider) { List<RosterEnrollment> siteEnrollmentSets = new ArrayList<RosterEnrollment>(); String[] sectionIds = groupProvider.unpackId(getSite(siteId).getProviderGroupId()); // avoid duplicates List<String> enrollmentSetIdsProcessed = new ArrayList<String>(); for (String sectionId : sectionIds) { Section section = courseManagementService.getSection(sectionId); if (null == section) { continue; } EnrollmentSet enrollmentSet = section.getEnrollmentSet(); if (null == enrollmentSet) { continue; } if (enrollmentSetIdsProcessed.contains(enrollmentSet.getEid())) { continue; } RosterEnrollment rosterEnrollmentSet = new RosterEnrollment(enrollmentSet.getEid()); rosterEnrollmentSet.setTitle(enrollmentSet.getTitle()); siteEnrollmentSets.add(rosterEnrollmentSet); enrollmentSetIdsProcessed.add(enrollmentSet.getEid()); } return siteEnrollmentSets; } private boolean isAllowed(String userId, String permision, AuthzGroup authzGroup) { if (securityService.isSuperUser(userId)) { return true; } return authzGroup.isAllowed(userId, permision); } /** * Calls the SecurityService unlock method. This is the method you must use in order for Delegated Access to work. * Note that the SecurityService automatically handles super users. * * @param userId user uuid * @param permission permission to check for * @param reference reference to entity. The getReference() method should get you out of trouble. * @return true if user has permission, false otherwise */ private boolean isAllowed(String userId, String permission, String reference) { return securityService.unlock(userId, permission, reference); } /** * {@inheritDoc} */ public Boolean hasUserSitePermission(String userId, String permission, String siteId) { Site site = getSite(siteId); if (null == site) { return false; } else { return isAllowed(userId, permission, site.getReference()); } } /** * {@inheritDoc} */ public Boolean hasUserGroupPermission(String userId, String permission, String siteId, String groupId) { Site site = getSite(siteId); if (null == site) { return false; } else { if (null == site.getGroup(groupId)) { return false; } else { return isAllowed(userId, permission, site.getGroup(groupId).getReference()); } } } /** * {@inheritDoc} */ public boolean isSiteMaintainer(String siteId) { String userId = getCurrentUserId(); return hasUserSitePermission(userId, SiteService.SECURE_UPDATE_SITE, siteId) && hasUserSitePermission(userId, SiteService.SECURE_UPDATE_SITE_MEMBERSHIP, siteId); } /** * {@inheritDoc} */ private Cache getCache(String cache) { try { Cache c = memoryService.getCache(cache); if (c == null) { c = memoryService.createCache(cache, new SimpleConfiguration(0)); } return c; } catch (Exception e) { log.error("Exception whilst retrieving '" + cache + "' cache. Returning null ...", e); return null; } } /** * {@inheritDoc} */ public Map<String, String> getSearchIndex(String siteId) { try { // Try and load the sorted memberships from the cache Cache cache = memoryService.getCache(SEARCH_INDEX_CACHE); if (cache == null) { cache = memoryService.createCache(SEARCH_INDEX_CACHE, new SimpleConfiguration(0)); } Map<String, String> index = (Map<String, String>) cache.get(siteId); if (index == null) { index = new HashMap<String, String>(); for (User user : getSiteUsers(siteId)) { index.put(user.getDisplayName(), user.getId()); } cache.put(siteId, index); } return index; } catch (Exception e) { log.error("Exception whilst retrieving search index for site '" + siteId + "'. Returning null ...", e); return null; } } }