001/* 002 * Copyright 2016 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.ametys.web.population; 017 018import java.util.Collection; 019import java.util.HashSet; 020import java.util.LinkedHashSet; 021import java.util.Map; 022import java.util.Set; 023import java.util.stream.Collectors; 024 025import org.apache.commons.lang3.tuple.Pair; 026 027import org.ametys.core.right.RightManager.RightResult; 028import org.ametys.core.user.UserIdentity; 029import org.ametys.core.user.population.UserPopulation; 030import org.ametys.runtime.authentication.AccessDeniedException; 031import org.ametys.web.AmetysContextHelper; 032 033 034/** 035 * Helper for associating {@link UserPopulation}s to contexts. 036 * This override allows a user to get user populations on a 'site' context if user belongs to the BO+FO site context ('/sites/SITENAME') or FO site context ('/sites-fo/SITENAME') 037 */ 038public class PopulationContextHelper extends org.ametys.core.user.population.PopulationContextHelper 039{ 040 @Override 041 public Set<String> getUserPopulationsOnContexts(Collection<String> contexts, boolean withDisabled, boolean checkRights) 042 { 043 UserIdentity currentUser = getCurrentUserProvider().getUser(); 044 045 if (!checkRights || contexts.contains(ADMIN_CONTEXT) || currentUser == null) 046 { 047 // no override required 048 return super.getUserPopulationsOnContexts(contexts, withDisabled, checkRights); 049 } 050 051 boolean isAdministrator = getRightManager().currentUserHasRight(__ADMIN_RIGHT_ACCESS, ADMIN_CONTEXT) == RightResult.RIGHT_ALLOW; 052 Set<String> populations = new LinkedHashSet<>(); 053 054 Set<String> handledContexts = new HashSet<>(); 055 056 for (String context : contexts) 057 { 058 if (!handledContexts.contains(context)) 059 { 060 Set<String> ctxPopulations = getUserPopulationsOnContext(context, withDisabled); 061 handledContexts.add(context); 062 if (!isAdministrator) 063 { 064 Set<String> ctxPopulationsToCheckAccess = new HashSet<>(ctxPopulations); 065 066 String complementaryContext = AmetysContextHelper.getSiteComplementaryContext(context); 067 if (complementaryContext != null) 068 { 069 Set<String> compPopulations = getUserPopulationsOnContext(complementaryContext, withDisabled); 070 ctxPopulationsToCheckAccess.addAll(compPopulations); 071 072 if (contexts.contains(complementaryContext)) 073 { 074 handledContexts.add(complementaryContext); 075 ctxPopulations.addAll(compPopulations); 076 } 077 } 078 079 if (!ctxPopulationsToCheckAccess.contains(currentUser.getPopulationId())) 080 { 081 throw new AccessDeniedException("User " + currentUser + " tried to access the list of user populations on context '" + context + "', but he does not belong to any populations on this context."); 082 } 083 } 084 085 populations.addAll(ctxPopulations); 086 } 087 } 088 089 return populations; 090 } 091 092 @Override 093 protected Set<String> _getSharedCompatibleContexts(Map<String, Set<Pair<String, Integer>>> cacheAsMap, String context, String userPopulation1, String userPopulation2) 094 { 095 String complementaryContext = AmetysContextHelper.getSiteComplementaryContext(context); 096 // If there is no complementary context, just check the populations for the context 097 if (complementaryContext == null) 098 { 099 return super._getSharedCompatibleContexts(cacheAsMap, context, userPopulation1, userPopulation2); 100 } 101 // Else check the populations for the two contexts 102 else 103 { 104 // Add the user populations of the two contexts to a new set 105 Set<Pair<String, Integer>> cacheForContexts = new HashSet<>(cacheAsMap.get(context)); 106 cacheForContexts.addAll(cacheAsMap.get(complementaryContext)); 107 108 Set<String> populationsForContext = cacheForContexts.stream().map(popPair -> popPair.getLeft()).collect(Collectors.toSet()); 109 110 if (populationsForContext.contains(userPopulation1) && populationsForContext.contains(userPopulation2)) 111 { 112 return Set.of(context, complementaryContext); 113 } 114 } 115 116 return Set.of(); 117 } 118}