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