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.Set; 022import java.util.regex.Matcher; 023import java.util.regex.Pattern; 024 025import org.ametys.core.right.RightManager.RightResult; 026import org.ametys.core.user.UserIdentity; 027import org.ametys.core.user.population.UserPopulation; 028import org.ametys.runtime.authentication.AccessDeniedException; 029 030 031/** 032 * Helper for associating {@link UserPopulation}s to contexts. 033 * 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') 034 */ 035public class PopulationContextHelper extends org.ametys.core.user.population.PopulationContextHelper 036{ 037 private static final Pattern _SITES_CONTEXT_PATTERN = Pattern.compile("^/sites/(.+)$"); 038 private static final Pattern _SITES_FO_CONTEXT_PATTERN = Pattern.compile("^/sites-fo/(.+)$"); 039 040 private static final String _SITES_CONTEXT_PREFIX = "/sites/"; 041 private static final String _SITES_FO_CONTEXT_PREFIX = "/sites-fo/"; 042 043 @Override 044 public Set<String> getUserPopulationsOnContexts(Collection<String> contexts, boolean withDisabled, boolean checkRights) 045 { 046 UserIdentity currentUser = getCurrentUserProvider().getUser(); 047 048 if (!checkRights || contexts.contains(ADMIN_CONTEXT) || currentUser == null) 049 { 050 // no override required 051 return super.getUserPopulationsOnContexts(contexts, withDisabled, checkRights); 052 } 053 054 boolean isAdministrator = getRightManager().currentUserHasRight(__ADMIN_RIGHT_ACCESS, ADMIN_CONTEXT) == RightResult.RIGHT_ALLOW; 055 Set<String> populations = new LinkedHashSet<>(); 056 057 Set<String> handledContexts = new HashSet<>(); 058 059 for (String context : contexts) 060 { 061 if (!handledContexts.contains(context)) 062 { 063 Set<String> ctxPopulations = getUserPopulationsOnContext(context, withDisabled); 064 handledContexts.add(context); 065 if (!isAdministrator) 066 { 067 Set<String> ctxPopulationsToCheckAccess = new HashSet<>(ctxPopulations); 068 069 String complementaryContext = _getSiteComplementaryContext(context); 070 if (complementaryContext != null) 071 { 072 Set<String> compPopulations = getUserPopulationsOnContext(complementaryContext, withDisabled); 073 ctxPopulationsToCheckAccess.addAll(compPopulations); 074 075 if (contexts.contains(complementaryContext)) 076 { 077 handledContexts.add(complementaryContext); 078 ctxPopulations.addAll(compPopulations); 079 } 080 } 081 082 if (!ctxPopulationsToCheckAccess.contains(currentUser.getPopulationId())) 083 { 084 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."); 085 } 086 } 087 088 populations.addAll(ctxPopulations); 089 } 090 } 091 092 return populations; 093 } 094 095 private String _getSiteComplementaryContext(String context) 096 { 097 Matcher matcher = _SITES_CONTEXT_PATTERN.matcher(context); 098 if (matcher.matches()) 099 { 100 String siteName = matcher.group(1); 101 return _SITES_FO_CONTEXT_PREFIX + siteName; 102 } 103 else 104 { 105 matcher = _SITES_FO_CONTEXT_PATTERN.matcher(context); 106 if (matcher.matches()) 107 { 108 String siteName = matcher.group(1); 109 return _SITES_CONTEXT_PREFIX + siteName; 110 } 111 } 112 113 return null; 114 } 115}