/** * Checks that the requesting user can view survey responses for some collection of users. There * may not actually be any responses to read or the responses may need to be made public first. * This only guarantees that, if the other users have any public responses that the requesting * user is allowed to view them. Therefore, this will pass as long as any of the following are * true: <br> * <br> * - If the user is a supervisor or an author.<br> * - If the user is an analyst and the campaign is shared.<br> * - If the user is the same as all of the requesting users.<br> * <br> * If you want to check if a user can read survey responses from every user in a campaign, don't * pass in any user usernames. * * @param campaignId The unique identifier for the campaign. * @param requesterUsername The requesting user's username. * @param userUsernames The array of usernames of specific users to check if the requesting user * has permission to read their information. * @throws ServiceException Thrown if none of the rules are true or there is an error. */ public void requesterCanViewUsersSurveyResponses( final String campaignId, final String requesterUsername, final String... userUsernames) throws ServiceException { try { // If the requester is asking about other users. if (userUsernames.length != 0) { // If the requester is the same as all of the users in question. boolean otherUsers = false; for (String username : userUsernames) { if (!requesterUsername.equals(username)) { otherUsers = true; } } if (!otherUsers) { return; } } List<Campaign.Role> requesterRoles = userCampaignQueries.getUserCampaignRoles(requesterUsername, campaignId); // If the requester's role list contains supervisor, return. if (requesterRoles.contains(Campaign.Role.SUPERVISOR)) { return; } // If the requester's role list contains author, return. if (requesterRoles.contains(Campaign.Role.AUTHOR)) { return; } // If the requester's role list contains analyst, if (requesterRoles.contains(Campaign.Role.ANALYST)) { Campaign.PrivacyState privacyState = campaignQueries.getCampaignPrivacyState(campaignId); if ((privacyState != null) && (Campaign.PrivacyState.SHARED.equals(privacyState))) { return; } } throw new ServiceException( ErrorCode.CAMPAIGN_INSUFFICIENT_PERMISSIONS, "The user does not have sufficient permissions to read information about other users."); } catch (DataAccessException e) { throw new ServiceException(e); } }
/** * Verifies that a user is allowed to update a campaign's XML. * * @param username The username of the user. * @param campaignId The campaign's unique identifier. * @param id The ID from the new XML. * @param name The name from the new XML. * @throws ServiceException Thrown if the user isn't allowed to modify the campaign, if the user * is allowed to modify the campaign but responses exist, or if there is an error. */ public void verifyUserCanUpdateCampaignXml( final String username, final String campaignId, final String id, final String name) throws ServiceException { try { // Get the user's roles for this campaign. List<Campaign.Role> roles = userCampaignQueries.getUserCampaignRoles(username, campaignId); // If the user isn't a supervisor or an author, then they aren't // allowed to update it. if (!(roles.contains(Campaign.Role.SUPERVISOR) || roles.contains(Campaign.Role.AUTHOR))) { throw new ServiceException( ErrorCode.CAMPAIGN_INSUFFICIENT_PERMISSIONS, "The user is not allowed to modify the campaign's XML."); } // If the campaign already has survey responses, then it cannot be // updated by anyone. if (campaignSurveyResponseQueries.getNumberOfSurveyResponsesForCampaign(campaignId) != 0) { throw new ServiceException( ErrorCode.CAMPAIGN_INSUFFICIENT_PERMISSIONS, "Survey responses exist; therefore the XML can no longer be modified."); } // Check to ensure that the ID of the campaign hasn't changed. if (!campaignId.equals(id)) { throw new ServiceException( ErrorCode.CAMPAIGN_XML_HEADER_CHANGED, "The campaign's ID in the new XML must be the same as the original XML."); } // Check to ensure that the name of the campaign hasn't changed. if (!campaignQueries.getName(campaignId).equals(name)) { throw new ServiceException( ErrorCode.CAMPAIGN_XML_HEADER_CHANGED, "The campaign's name in the new XML must be the same as the original XML."); } } catch (DataAccessException e) { throw new ServiceException(e); } }
/** * Retrieves the information about a campaign. * * @param campaignId The campaign's unqiue identifier. * @param withClasses Whether or not to populate the campaign with its list of classes. * @param withUsers Whether or not to populate the campaign with its list of users and their * respective roles. * @return The campaign object with the specified information. * @throws ServiceException Thrown if there is an error. */ public Campaign getCampaignInformation( final String campaignId, final boolean withClasses, final boolean withUsers) throws ServiceException { try { Campaign result = campaignQueries.findCampaignConfiguration(campaignId); if (withClasses) { try { result.addClasses(campaignClassQueries.getClassesAssociatedWithCampaign(campaignId)); } catch (DomainException e) { throw new ServiceException("There was a problem adding a class.", e); } } if (withUsers) { List<String> campaignUsernames = userCampaignQueries.getUsersInCampaign(campaignId); for (String campaignUsername : campaignUsernames) { List<Campaign.Role> userRoles = userCampaignQueries.getUserCampaignRoles(campaignUsername, campaignId); for (Campaign.Role userRole : userRoles) { try { result.addUser(campaignUsername, userRole); } catch (DomainException e) { throw new ServiceException("There was a problem adding a user.", e); } } } } return result; } catch (DataAccessException e) { throw new ServiceException(e); } }
/** * Gathers the requested information about a campaign. This will be at least its name, description * (possibly null), running state, privacy state, creation timestamp, and all of the requesting * user's roles in the campaign.<br> * <br> * The extras include the campaign's XML, all of the users associated with the campaign and their * roles, and all of the classes associated with the campaign. * * @param username The username of the user whose roles in the campaign are desired. * @param campaignIds The IDs for the campaigns whose information is desired. * @param withExtras A flag to indicate if the extra information should be included in each * Campaign object. * @return A map of campaigns and their information to the list of roles for this user in the * campaign. * @throws ServiceException Thrown if there is an error. */ public Map<Campaign, List<Campaign.Role>> getCampaignAndUserRolesForCampaigns( final String username, final Collection<String> campaignIds, final boolean withExtras) throws ServiceException { try { Map<Campaign, List<Campaign.Role>> result = new HashMap<Campaign, List<Campaign.Role>>(); for (String campaignId : campaignIds) { // Create the Campaign object with the campaign's ID. Campaign campaign = campaignQueries.getCampaignInformation(campaignId); // Get the user's roles. List<Campaign.Role> roles = userCampaignQueries.getUserCampaignRoles(username, campaignId); // If we are supposed to get the extra information as well. if (withExtras) { // Add the classes that are associated with the campaign. try { campaign.addClasses(campaignClassQueries.getClassesAssociatedWithCampaign(campaignId)); } catch (DomainException e) { throw new ServiceException("There was a problem adding a class.", e); } // Add the users and their roles to the campaign. campaign.addUsers(userCampaignQueries.getUsersAndRolesForCampaign(campaignId)); } // Add the user's roles. result.put(campaign, roles); } return result; } catch (DataAccessException e) { throw new ServiceException(e); } }
/** * Gathers the information about the classes that match the criteria based on the user's * permissions. If the requesting user is an admin, they will see all campaigns; otherwise, they * will only see the campaigns to which they belong. * * @param username The requesting user's username. This parameter is required. * @param campaignIds A list of campaign unique identifiers. This is optional and may be null. It * limits the results to only those campaigns to which the user belongs. * @param classIds A list of class unique identifiers. This is optional and may be null. It limits * the results to only those campaigns that are associated with any class in this list. * @param nameTokens A collection of token strings which limit the results to only those campaigns * whose name contains at least one of the tokens. * @param descriptionTokens A collection of token strings which limit the results to only those * campaigns that have a description and whose description contains at least one of the * tokens. * @param startDate A date that limits the results to only those campaigns that were created on or * after this date. * @param endDate A date that limits the results to only those campaigns that were created on or * before this date. * @param privacyState A campaign privacy state the limits the results to only those campaigns * that have this privacy state. * @param runningState A campaign running state that limits the results to only those campaigns * that have this running state. * @param role A campaign role which limits the results to only those campaigns where the * requesting user has this role in the campaign. * @param withClasses Whether or not to aggregate all of the classes associated with this * campaign. * @param withUsers Whether or not to aggregate all of the users and their respective roles for * this campaign. * @return A map of Campaign objects to the requesting user's respective roles. * @throws ServiceException There was an error. */ public Map<Campaign, Collection<Campaign.Role>> getCampaignInformation( final String username, final Collection<String> campaignIds, final Collection<String> classIds, final Collection<String> nameTokens, final Collection<String> descriptionTokens, final DateTime startDate, final DateTime endDate, final Campaign.PrivacyState privacyState, final Campaign.RunningState runningState, final Campaign.Role role, final boolean withClasses, final boolean withUsers) throws ServiceException { try { QueryResultsList<Campaign> queryResult = campaignQueries.getCampaignInformation( username, campaignIds, classIds, nameTokens, descriptionTokens, startDate, endDate, privacyState, runningState, role); List<Campaign> campaignResults = queryResult.getResults(); Map<Campaign, Collection<Campaign.Role>> result = new HashMap<Campaign, Collection<Campaign.Role>>(campaignResults.size()); for (Campaign campaign : campaignResults) { result.put(campaign, userCampaignQueries.getUserCampaignRoles(username, campaign.getId())); if (withClasses) { try { campaign.addClasses( campaignClassQueries.getClassesAssociatedWithCampaign(campaign.getId())); } catch (DomainException e) { throw new ServiceException("There was a problem adding the classes.", e); } } if (withUsers) { // Add the users and their roles to the campaign. campaign.addUsers(userCampaignQueries.getUsersAndRolesForCampaign(campaign.getId())); } // Get and apply the masks for this campaign. campaign.addMasks( userCampaignQueries.getCampaignMasks( null, null, null, null, username, campaign.getId())); } return result; } catch (DataAccessException e) { throw new ServiceException(e); } }
/** * Generates a List of unique identifiers for campaigns based on the parameters. The List is based * on the 'campaignIds' parameter unless it is null in which case the List is based on all * campaigns visible to the user. All parameters except 'request' and 'username' are optional and * each will filter the resulting List of campaign identifiers.<br> * <br> * <br> * For example, if 'campaignIds' was null as were 'endDate' and 'privacyState', then what would be * returned would be the intersection of the following lists:<br> * - All of the campaigns to which the user was associated (because 'campaignIds' was null).<br> * - All of the campaigns that are associated with any of the classes whose unique identifier was * in the 'classIds' list.<br> * - All of the campaigns whose creation timestamp was equal to or after 'startDate'<br> * - All of the campaigns whose running state equaled 'runningState'.<br> * - All of the campaigns to which the user had the campaign role 'role'. <br> * <br> * Therefore, if a campaign was associated with a user only through a single class, but that class * wasn't in the 'classIds' list, then that campaign ID would not be returned even if all of the * other parameters matched. * * @param username The username of the user. * @param campaignIds An optional Collection of campaign identifiers from which to base the List. * If this is empty, the resulting List will be empty. If this is null, the base List will be * all campaigns to which the user is associated. * @param classIds A Collection of unique identifiers for classes where the resulting list will * only contain campaign identifiers for campaigns that are associated with any of these * classes. * @param startDate A Calendar where only campaigns whose creation timestamp is equal to or after * this date. * @param endDate A Calendar where only campaigns whose creation timestamp is equal to or before * this date. * @param privacyState A campaign privacy state that trims the resulting list of campaigns to only * those that have this privacy state. * @param runningState A campaign running state that trims the resulting list of campaigns to only * those that have this running state. * @param role A campaign role that trims the resulting list of campaigns to only those where the * user has that role in the campaign. * @return A Set of campaign unique identifiers based on the 'campaignIds' parameter and trimmed * by the rest of the parameters. * @throws ServiceException Thrown if there is an error. */ public Set<String> getCampaignsForUser( final String username, final Collection<String> campaignIds, final Collection<String> classIds, final DateTime startDate, final DateTime endDate, final Campaign.PrivacyState privacyState, final Campaign.RunningState runningState, final Campaign.Role role) throws ServiceException { try { Set<String> desiredCampaignIds = new HashSet<String>(); if (campaignIds == null) { // Initializes the list with all of the campaign IDs for the // requesting user. desiredCampaignIds.addAll( userCampaignQueries.getCampaignIdsAndNameForUser(username).keySet()); } else { // Initializes the list with the campaign IDs in the query. desiredCampaignIds.addAll(campaignIds); } if (desiredCampaignIds.size() == 0) { return Collections.emptySet(); } if (classIds != null) { // Get all of the campaigns associated with all of the classes in // the list. for (String classId : classIds) { desiredCampaignIds.retainAll( campaignClassQueries.getCampaignsAssociatedWithClass(classId)); } if (desiredCampaignIds.size() == 0) { return Collections.emptySet(); } } if (startDate != null) { // Get all of the campaigns whose creation timestamp is greater // than or equal to the start date. desiredCampaignIds.retainAll(campaignQueries.getCampaignsOnOrAfterDate(startDate)); if (desiredCampaignIds.size() == 0) { return Collections.emptySet(); } } if (endDate != null) { // Get all of the campaigns whose creation timestamp is less than // or equal to the end date. desiredCampaignIds.retainAll(campaignQueries.getCampaignsOnOrBeforeDate(endDate)); if (desiredCampaignIds.size() == 0) { return Collections.emptySet(); } } if (privacyState != null) { // Get all of the campaigns with a privacy state of 'privacyState'. desiredCampaignIds.retainAll(campaignQueries.getCampaignsWithPrivacyState(privacyState)); if (desiredCampaignIds.size() == 0) { return Collections.emptySet(); } } if (runningState != null) { // Get all of the campaigns with a running state of 'runningState'. desiredCampaignIds.retainAll(campaignQueries.getCampaignsWithRunningState(runningState)); if (desiredCampaignIds.size() == 0) { return Collections.emptySet(); } } if (role != null) { // Get all of the campaigns where the user's role is 'role'. desiredCampaignIds.retainAll( userCampaignQueries.getCampaignIdsForUserWithRole(username, role)); if (desiredCampaignIds.size() == 0) { return Collections.emptySet(); } } return desiredCampaignIds; } catch (DataAccessException e) { throw new ServiceException(e); } }