/* (c) 2014 Open Source Geospatial Foundation - all rights reserved * (c) 2001 - 2013 OpenPlans * This code is licensed under the GPL 2.0 license, available at the root * application directory. */ package org.geoserver.security; import java.util.ArrayList; import java.util.List; import org.geoserver.catalog.Catalog; import org.geoserver.catalog.CatalogInfo; import org.geoserver.catalog.CoverageInfo; import org.geoserver.catalog.FeatureTypeInfo; import org.geoserver.catalog.LayerGroupInfo; import org.geoserver.catalog.LayerInfo; import org.geoserver.catalog.Predicates; import org.geoserver.catalog.ResourceInfo; import org.geoserver.catalog.StyleInfo; import org.geoserver.catalog.WMSLayerInfo; import org.geoserver.catalog.WorkspaceInfo; import org.geoserver.platform.GeoServerExtensions; import org.opengis.filter.Filter; import org.springframework.security.core.Authentication; /** * Filters viewable layers based on the registered CatalogFilter * * @author Justin Deoliveira, OpenGeo * @author David Winslow, OpenGeo * @author Andrea Aime, GeoSolutions */ public class CatalogFilterAccessManager extends ResourceAccessManagerWrapper { private List<? extends CatalogFilter> filters; private DataAccessLimits hide(ResourceInfo info) { if (info instanceof FeatureTypeInfo) { return new VectorAccessLimits(CatalogMode.HIDE, null, Filter.EXCLUDE, null, Filter.EXCLUDE); } else if (info instanceof CoverageInfo) { return new CoverageAccessLimits(CatalogMode.HIDE, Filter.EXCLUDE, null, null); } else if (info instanceof WMSLayerInfo) { return new WMSAccessLimits(CatalogMode.HIDE, Filter.EXCLUDE, null, false); } else { // TODO: Log warning about unknown resource type return new DataAccessLimits(CatalogMode.HIDE, Filter.EXCLUDE); } } @Override public DataAccessLimits getAccessLimits(Authentication user, LayerInfo layer) { if (hideLayer(layer) || hideResource(layer.getResource())) { return hide(layer.getResource()); } return super.getAccessLimits(user, layer); } @Override public DataAccessLimits getAccessLimits(Authentication user, LayerInfo layer, List<LayerGroupInfo> containers) { if (hideLayer(layer) || hideResource(layer.getResource())) { return hide(layer.getResource()); } return super.getAccessLimits(user, layer, containers); } @Override public DataAccessLimits getAccessLimits(Authentication user, ResourceInfo resource) { if (hideResource(resource)) { return hide(resource); } else { return super.getAccessLimits(user, resource); } } @Override public WorkspaceAccessLimits getAccessLimits(Authentication user, WorkspaceInfo workspace) { if (hideWorkspace(workspace)) { return new WorkspaceAccessLimits(CatalogMode.HIDE, false, false, false); } else { return super.getAccessLimits(user, workspace); } } @Override public StyleAccessLimits getAccessLimits(Authentication user, StyleInfo style) { if (hideStyle(style)) { return new StyleAccessLimits(CatalogMode.HIDE); } else { return super.getAccessLimits(user, style); } } @Override public LayerGroupAccessLimits getAccessLimits(Authentication user, LayerGroupInfo layerGroup) { if (hideLayerGroup(layerGroup)) { return new LayerGroupAccessLimits(CatalogMode.HIDE); } return super.getAccessLimits(user, layerGroup); } @Override public LayerGroupAccessLimits getAccessLimits(Authentication user, LayerGroupInfo layerGroup, List<LayerGroupInfo> containers) { if (hideLayerGroup(layerGroup)) { return new LayerGroupAccessLimits(CatalogMode.HIDE); } else { return super.getAccessLimits(user, layerGroup, containers); } } private boolean hideResource(ResourceInfo resource) { for (CatalogFilter filter : getCatalogFilters()) { if (filter.hideResource(resource)) { return true; } } return false; } private boolean hideLayer(LayerInfo layer) { for (CatalogFilter filter : getCatalogFilters()) { if (filter.hideLayer(layer)) { return true; } } return false; } private boolean hideWorkspace(WorkspaceInfo workspace) { for (CatalogFilter filter : getCatalogFilters()) { if (filter.hideWorkspace(workspace)) { return true; } } return false; } private boolean hideStyle(StyleInfo style) { for (CatalogFilter filter : getCatalogFilters()) { if (filter.hideStyle(style)) { return true; } } return false; } private boolean hideLayerGroup(LayerGroupInfo layerGroup) { for (CatalogFilter filter : getCatalogFilters()) { if (filter.hideLayerGroup(layerGroup)) { return true; } } return false; } private List<? extends CatalogFilter> getCatalogFilters() { if (filters == null) { filters = GeoServerExtensions.extensions(CatalogFilter.class); } return filters; } /** * Designed for testing, allows to manually configure the catalog filters bypassing * the Spring context lookup * @param filters */ public void setCatalogFilters(List<? extends CatalogFilter> filters) { this.filters = filters; } @Override public Filter getSecurityFilter(Authentication user, Class<? extends CatalogInfo> clazz) { // If there are no CatalogFilters, just get the delegate's filter if(filters==null || filters.isEmpty()) return delegate.getSecurityFilter(user, clazz); // Result is the conjunction of delegate's filter, and those of all the CatalogFilters ArrayList<Filter> convertedFilters = new ArrayList<Filter>(this.filters.size()+1); convertedFilters.add(delegate.getSecurityFilter(user, clazz)); // Delegate's filter for (CatalogFilter filter : getCatalogFilters()) { convertedFilters.add(filter.getSecurityFilter(clazz)); // Each CatalogFilter's filter } return Predicates.and(convertedFilters.toArray(new Filter[convertedFilters.size()])); } }