/* Copyright (c) 2001 - 2007 TOPP - www.openplans.org. All rights reserved.
* 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.Collection;
import java.util.List;
import org.geoserver.catalog.Catalog;
import org.geoserver.catalog.CatalogFacade;
import org.geoserver.catalog.CatalogFactory;
import org.geoserver.catalog.CatalogInfo;
import org.geoserver.catalog.CatalogVisitor;
import org.geoserver.catalog.CoverageInfo;
import org.geoserver.catalog.CoverageStoreInfo;
import org.geoserver.catalog.DataStoreInfo;
import org.geoserver.catalog.FeatureTypeInfo;
import org.geoserver.catalog.LayerGroupInfo;
import org.geoserver.catalog.LayerInfo;
import org.geoserver.catalog.MapInfo;
import org.geoserver.catalog.NamespaceInfo;
import org.geoserver.catalog.ResourceInfo;
import org.geoserver.catalog.ResourcePool;
import org.geoserver.catalog.StoreInfo;
import org.geoserver.catalog.StyleInfo;
import org.geoserver.catalog.WMSLayerInfo;
import org.geoserver.catalog.WMSStoreInfo;
import org.geoserver.catalog.WorkspaceInfo;
import org.geoserver.catalog.event.CatalogListener;
import org.geoserver.catalog.impl.AbstractDecorator;
import org.geoserver.ows.Dispatcher;
import org.geoserver.ows.Request;
import org.geoserver.platform.GeoServerExtensions;
import org.geoserver.platform.GeoServerResourceLoader;
import org.geoserver.security.decorators.SecuredCoverageInfo;
import org.geoserver.security.decorators.SecuredCoverageStoreInfo;
import org.geoserver.security.decorators.SecuredDataStoreInfo;
import org.geoserver.security.decorators.SecuredFeatureTypeInfo;
import org.geoserver.security.decorators.SecuredLayerGroupInfo;
import org.geoserver.security.decorators.SecuredLayerInfo;
import org.geoserver.security.decorators.SecuredWMSLayerInfo;
import org.geoserver.security.impl.DataAccessRuleDAO;
import org.geoserver.security.impl.DefaultDataAccessManager;
import org.opengis.feature.type.Name;
import org.opengis.filter.Filter;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.core.Authentication;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
/**
* Wraps the catalog and applies the security directives provided by a {@link ResourceAccessManager}
* or a {@link DataAccessManager} registered in the Spring application context
*
* @author Andrea Aime - GeoSolutions
*/
public class SecureCatalogImpl extends AbstractDecorator<Catalog> implements Catalog {
protected ResourceAccessManager accessManager;
public SecureCatalogImpl(Catalog catalog) throws Exception {
this(catalog, lookupResourceAccessManager());
}
public String getId() {
return delegate.getId();
}
static ResourceAccessManager lookupResourceAccessManager() throws Exception {
ResourceAccessManager manager = GeoServerExtensions.bean(ResourceAccessManager.class);
if (manager == null) {
DataAccessManager daManager = lookupDataAccessManager();
manager = new DataAccessManagerAdapter(daManager);
}
CatalogFilterAccessManager lwManager = new CatalogFilterAccessManager();
lwManager.setDelegate(manager);
return lwManager;
}
static DataAccessManager lookupDataAccessManager() throws Exception {
DataAccessManager manager = GeoServerExtensions.bean(DataAccessManager.class);
if (manager == null) {
manager = new DefaultDataAccessManager(GeoServerExtensions.bean(DataAccessRuleDAO.class));
} else {
if (manager instanceof DataAccessManagerWrapper) {
((DataAccessManagerWrapper)manager).setDelegate(
new DefaultDataAccessManager(GeoServerExtensions.bean(DataAccessRuleDAO.class)));
}
}
return manager;
}
public SecureCatalogImpl(Catalog catalog, ResourceAccessManager manager) {
super(catalog);
this.accessManager = manager;
}
// -------------------------------------------------------------------
// SECURED METHODS
// -------------------------------------------------------------------
public CoverageInfo getCoverage(String id) {
return (CoverageInfo) checkAccess(user(), delegate.getCoverage(id));
}
public CoverageInfo getCoverageByName(String ns, String name) {
return (CoverageInfo) checkAccess(user(), delegate.getCoverageByName(ns, name));
}
public CoverageInfo getCoverageByName(NamespaceInfo ns, String name) {
return (CoverageInfo) checkAccess(user(), delegate.getCoverageByName(ns, name));
}
public CoverageInfo getCoverageByName(Name name) {
return (CoverageInfo) checkAccess(user(), delegate.getCoverageByName(name));
}
public CoverageInfo getCoverageByName(String name) {
return (CoverageInfo) checkAccess(user(), delegate.getCoverageByName(name));
}
public List<CoverageInfo> getCoverages() {
return filterResources(user(), delegate.getCoverages());
}
public List<CoverageInfo> getCoveragesByNamespace(NamespaceInfo namespace) {
return filterResources(user(), delegate.getCoveragesByNamespace(namespace));
}
public List<CoverageInfo> getCoveragesByCoverageStore(
CoverageStoreInfo store) {
return filterResources(user(), delegate.getCoveragesByCoverageStore(store));
}
public CoverageInfo getCoverageByCoverageStore(
CoverageStoreInfo coverageStore, String name) {
return checkAccess(user(), delegate.getCoverageByCoverageStore(coverageStore, name));
}
public List<CoverageInfo> getCoveragesByStore(CoverageStoreInfo store) {
return filterResources(user(), delegate.getCoveragesByStore(store));
}
public CoverageStoreInfo getCoverageStore(String id) {
return checkAccess(user(), delegate.getCoverageStore(id));
}
public CoverageStoreInfo getCoverageStoreByName(String name) {
return checkAccess(user(), delegate.getCoverageStoreByName(name));
}
public CoverageStoreInfo getCoverageStoreByName(String workspaceName,
String name) {
return checkAccess(user(), delegate.getCoverageStoreByName(workspaceName,name));
}
public CoverageStoreInfo getCoverageStoreByName(WorkspaceInfo workspace,
String name) {
return checkAccess(user(), delegate.getCoverageStoreByName(workspace,name));
}
public List<CoverageStoreInfo> getCoverageStoresByWorkspace(
String workspaceName) {
return filterStores(user(),delegate.getCoverageStoresByWorkspace(workspaceName));
}
public List<CoverageStoreInfo> getCoverageStoresByWorkspace(
WorkspaceInfo workspace) {
return filterStores(user(),delegate.getCoverageStoresByWorkspace(workspace));
}
public List<CoverageStoreInfo> getCoverageStores() {
return filterStores(user(), delegate.getCoverageStores());
}
public DataStoreInfo getDataStore(String id) {
return checkAccess(user(), delegate.getDataStore(id));
}
public DataStoreInfo getDataStoreByName(String name) {
return checkAccess(user(), delegate.getDataStoreByName(name));
}
public DataStoreInfo getDataStoreByName(String workspaceName, String name) {
return checkAccess(user(), delegate.getDataStoreByName(workspaceName,name));
}
public DataStoreInfo getDataStoreByName(WorkspaceInfo workspace, String name) {
return checkAccess(user(), delegate.getDataStoreByName(workspace,name)) ;
}
public List<DataStoreInfo> getDataStoresByWorkspace(String workspaceName) {
return filterStores(user(), delegate.getDataStoresByWorkspace(workspaceName));
}
public List<DataStoreInfo> getDataStoresByWorkspace(WorkspaceInfo workspace) {
return filterStores(user(), delegate.getDataStoresByWorkspace(workspace));
}
public List<DataStoreInfo> getDataStores() {
return filterStores(user(), delegate.getDataStores());
}
public NamespaceInfo getDefaultNamespace() {
return delegate.getDefaultNamespace();
}
public WorkspaceInfo getDefaultWorkspace() {
return delegate.getDefaultWorkspace();
}
public FeatureTypeInfo getFeatureType(String id) {
return checkAccess(user(), delegate.getFeatureType(id));
}
public FeatureTypeInfo getFeatureTypeByName(String ns, String name) {
return checkAccess(user(), delegate.getFeatureTypeByName(ns, name));
}
public FeatureTypeInfo getFeatureTypeByName(NamespaceInfo ns, String name) {
return checkAccess(user(), delegate.getFeatureTypeByName(ns,name));
}
public FeatureTypeInfo getFeatureTypeByName(Name name) {
return checkAccess(user(), delegate.getFeatureTypeByName(name));
}
public FeatureTypeInfo getFeatureTypeByName(String name) {
return checkAccess(user(), delegate.getFeatureTypeByName(name));
}
public List<FeatureTypeInfo> getFeatureTypes() {
return filterResources(user(), delegate.getFeatureTypes());
}
public List<FeatureTypeInfo> getFeatureTypesByNamespace(NamespaceInfo namespace) {
return filterResources(user(), delegate.getFeatureTypesByNamespace(namespace));
}
public FeatureTypeInfo getFeatureTypeByStore(DataStoreInfo dataStore,
String name) {
return checkAccess(user(), delegate.getFeatureTypeByStore(dataStore , name));
}
public FeatureTypeInfo getFeatureTypeByDataStore(DataStoreInfo dataStore,
String name) {
return checkAccess(user(), delegate.getFeatureTypeByDataStore(dataStore , name));
}
public List<FeatureTypeInfo> getFeatureTypesByStore(DataStoreInfo store) {
return filterResources(user(), delegate.getFeatureTypesByStore(store));
}
public List<FeatureTypeInfo> getFeatureTypesByDataStore(DataStoreInfo store) {
return filterResources(user(), delegate.getFeatureTypesByDataStore(store));
}
public LayerInfo getLayer(String id) {
return checkAccess(user(), delegate.getLayer(id));
}
public LayerInfo getLayerByName(String name) {
return checkAccess(user(), delegate.getLayerByName(name));
}
public LayerInfo getLayerByName(Name name) {
return checkAccess(user(), delegate.getLayerByName(name));
}
public LayerGroupInfo getLayerGroup(String id) {
return checkAccess(user(), delegate.getLayerGroup(id));
}
public LayerGroupInfo getLayerGroupByName(String name) {
return checkAccess(user(), delegate.getLayerGroupByName(name));
}
public List<LayerGroupInfo> getLayerGroups() {
return filterGroups(user(), delegate.getLayerGroups());
}
public List<LayerInfo> getLayers() {
return filterLayers(user(), delegate.getLayers());
}
public List<LayerInfo> getLayers(ResourceInfo resource) {
return filterLayers(user(), delegate.getLayers(unwrap(resource)));
}
public List<LayerInfo> getLayers(StyleInfo style) {
return filterLayers(user(), delegate.getLayers(style));
}
public NamespaceInfo getNamespace(String id) {
return checkAccess(user(), delegate.getNamespace(id));
}
public NamespaceInfo getNamespaceByPrefix(String prefix) {
return checkAccess(user(), delegate.getNamespaceByPrefix(prefix));
}
public NamespaceInfo getNamespaceByURI(String uri) {
return checkAccess(user(), delegate.getNamespaceByURI(uri));
}
public List<NamespaceInfo> getNamespaces() {
return filterNamespaces(user(), delegate.getNamespaces());
}
public <T extends ResourceInfo> T getResource(String id, Class<T> clazz) {
return checkAccess(user(), delegate.getResource(id, clazz));
}
public <T extends ResourceInfo> T getResourceByName(Name name, Class<T> clazz) {
return checkAccess(user(), delegate.getResourceByName(name, clazz));
}
public <T extends ResourceInfo> T getResourceByName(String name, Class<T> clazz) {
return checkAccess(user(), delegate.getResourceByName(name, clazz));
}
public <T extends ResourceInfo> T getResourceByName(NamespaceInfo ns,
String name, Class<T> clazz) {
return checkAccess(user(), delegate.getResourceByName(ns, name, clazz)) ;
}
public <T extends ResourceInfo> T getResourceByName(String ns, String name, Class<T> clazz) {
return checkAccess(user(), delegate.getResourceByName(ns, name, clazz));
}
public <T extends ResourceInfo> List<T> getResources(Class<T> clazz) {
return filterResources(user(), delegate.getResources(clazz));
}
public <T extends ResourceInfo> List<T> getResourcesByNamespace(NamespaceInfo namespace,
Class<T> clazz) {
return filterResources(user(), delegate.getResourcesByNamespace(namespace, clazz));
}
public <T extends ResourceInfo> List<T> getResourcesByNamespace(
String namespace, Class<T> clazz) {
return filterResources(user(), delegate.getResourcesByNamespace(namespace, clazz));
}
public <T extends ResourceInfo> T getResourceByStore(StoreInfo store,
String name, Class<T> clazz) {
return checkAccess(user(), delegate.getResourceByStore(store, name, clazz));
}
public <T extends ResourceInfo> List<T> getResourcesByStore(
StoreInfo store, Class<T> clazz) {
return filterResources(user(), delegate.getResourcesByStore(store, clazz));
}
public <T extends StoreInfo> T getStore(String id, Class<T> clazz) {
return checkAccess(user(), delegate.getStore(id, clazz));
}
public <T extends StoreInfo> T getStoreByName(String name, Class<T> clazz) {
return checkAccess(user(), delegate.getStoreByName(name, clazz));
}
public <T extends StoreInfo> T getStoreByName(String workspaceName,
String name, Class<T> clazz) {
return checkAccess(user(), delegate.getStoreByName(workspaceName, name, clazz));
}
public <T extends StoreInfo> T getStoreByName(WorkspaceInfo workspace,
String name, Class<T> clazz) {
return checkAccess(user(), delegate.getStoreByName(workspace, name, clazz));
}
public <T extends StoreInfo> List<T> getStores(Class<T> clazz) {
return filterStores(user(), delegate.getStores(clazz));
}
public <T extends StoreInfo> List<T> getStoresByWorkspace(
String workspaceName, Class<T> clazz) {
return filterStores(user(), delegate.getStoresByWorkspace(workspaceName , clazz));
}
public <T extends StoreInfo> List<T> getStoresByWorkspace(WorkspaceInfo workspace,
Class<T> clazz) {
return filterStores(user(), delegate.getStoresByWorkspace(workspace, clazz));
}
public WorkspaceInfo getWorkspace(String id) {
return checkAccess(user(), delegate.getWorkspace(id));
}
public WorkspaceInfo getWorkspaceByName(String name) {
return checkAccess(user(), delegate.getWorkspaceByName(name));
}
public List<WorkspaceInfo> getWorkspaces() {
return filterWorkspaces(user(), delegate.getWorkspaces());
}
// -------------------------------------------------------------------
// Security support method
// -------------------------------------------------------------------
protected static Authentication user() {
return SecurityContextHolder.getContext().getAuthentication();
}
/**
* Given a {@link FeatureTypeInfo} and a user, returns it back if the user
* can access it in write mode, makes it read only if the user can access it
* in read only mode, returns null otherwise
* @return
*/
protected <T extends ResourceInfo> T checkAccess(Authentication user,
T info) {
// handle null case
if (info == null)
return null;
// first off, handle the case where the user cannot even read the data
WrapperPolicy policy = buildWrapperPolicy(user, info, info.getName());
// handle the modes that do not require wrapping
if(policy.level == AccessLevel.HIDDEN)
return null;
else if(policy.level == AccessLevel.READ_WRITE && policy.getLimits() == null)
return info;
// otherwise we are in a mixed case where the user can read but not write, or
// cannot read but is allowed by the operation mode to access the metadata
if(info instanceof FeatureTypeInfo) {
return (T) new SecuredFeatureTypeInfo((FeatureTypeInfo) info, policy);
} else if(info instanceof CoverageInfo) {
return (T) new SecuredCoverageInfo((CoverageInfo) info, policy);
} else if(info instanceof WMSLayerInfo) {
return (T) new SecuredWMSLayerInfo((WMSLayerInfo) info, policy);
} else {
throw new RuntimeException("Unknown resource type " + info.getClass());
}
}
/**
* Given a store and a user, returns it back if the user can access its
* workspace in read mode, null otherwise
* @return
*/
protected <T extends StoreInfo> T checkAccess(Authentication user, T store) {
if (store == null)
return null;
WrapperPolicy policy = buildWrapperPolicy(user, store.getWorkspace(), store.getName());
// handle the modes that do not require wrapping
if(policy.level == AccessLevel.HIDDEN)
return null;
else if(policy.level == AccessLevel.READ_WRITE ||
(policy.level == AccessLevel.READ_ONLY && store instanceof CoverageStoreInfo))
return store;
// otherwise we are in a mixed case where the user can read but not write, or
// cannot read but is allowed by the operation mode to access the metadata
if(store instanceof DataStoreInfo) {
return (T) new SecuredDataStoreInfo((DataStoreInfo) store, policy);
} else if(store instanceof CoverageStoreInfo) {
return (T) new SecuredCoverageStoreInfo((CoverageStoreInfo) store, policy);
} else if(store instanceof WMSStoreInfo) {
// TODO: implement WMSStoreInfo wrappring if necessary
return store;
} else {
throw new RuntimeException("Unknown store type " + store.getClass());
}
}
/**
* Given a layer and a user, returns it back if the user can access it, null
* otherwise
* @return
*/
protected LayerInfo checkAccess(Authentication user, LayerInfo layer) {
if (layer == null)
return null;
// first off, handle the case where the user cannot even read the data
WrapperPolicy policy = buildWrapperPolicy(user, layer, layer.getName());
// handle the modes that do not require wrapping
if(policy.level == AccessLevel.HIDDEN)
return null;
else if(policy.level == AccessLevel.READ_WRITE && policy.getLimits() == null)
return layer;
// otherwise we are in a mixed case where the user can read but not write, or
// cannot read but is allowed by the operation mode to access the metadata
return new SecuredLayerInfo(layer, policy);
}
/**
* Given a layer group and a user, returns it back if the user can access
* it, null otherwise
* @return
*/
protected LayerGroupInfo checkAccess(Authentication user, LayerGroupInfo group) {
if (group == null)
return null;
// scan thru the layers, if any cannot be accessed, we hide the group, otherwise
// we return the group back, eventually wrapping the read only layers
final List<LayerInfo> layers = group.getLayers();
ArrayList<LayerInfo> wrapped = new ArrayList<LayerInfo>(layers.size());
boolean needsWrapping = false;
for (LayerInfo layer : layers) {
LayerInfo checked = checkAccess(user, layer);
if(checked == null)
return null;
else if(checked != null && checked != layer)
needsWrapping = true;
wrapped.add(checked);
}
if(needsWrapping)
return new SecuredLayerGroupInfo(group, wrapped);
else
return group;
}
/**
* Given a namespace and user, returns it back if the user can access it,
* null otherwise
* @return
*/
protected <T extends NamespaceInfo> T checkAccess(Authentication user, T ns) {
if(ns == null)
return null;
// route the security check thru the associated workspace info
WorkspaceInfo ws = delegate.getWorkspaceByName(ns.getPrefix());
if(ws == null) {
// temporary workaround, build a fake workspace, as we're probably
// in between a change of workspace/namespace name
ws = delegate.getFactory().createWorkspace();
ws.setName(ns.getPrefix());
}
WorkspaceInfo info = checkAccess(user, ws);
if (info == null)
return null;
else
return ns;
}
/**
* Given a workspace and user, returns it back if the user can access it,
* null otherwise
* @return
*/
protected <T extends WorkspaceInfo> T checkAccess(Authentication user, T ws) {
if (ws == null)
return null;
WrapperPolicy policy = buildWrapperPolicy(user, ws, ws.getName());
// if we don't need to hide it, then we can return it as is since it
// can only provide metadata.
if(policy.level == AccessLevel.HIDDEN)
return null;
else
return ws;
}
/**
* Factors out the policy that decides what access level the current user
* has to a specific resource considering the read/write access, the security
* mode, and the filtering status
* @param user
* @param canRead
* @param canWrite
* @param resourceName
* @return
*/
public WrapperPolicy buildWrapperPolicy(Authentication user,
CatalogInfo info, String resourceName) {
boolean canRead = true;
boolean canWrite = true;
AccessLimits limits;
if(info instanceof WorkspaceInfo) {
// unsure here... shall we disallow writing? Only catalog and config
// related code should be playing with stores directly, so it's more of a
// matter if you can admin a workspace or not
limits = accessManager.getAccessLimits(user, (WorkspaceInfo) info);
WorkspaceAccessLimits wl = (WorkspaceAccessLimits) limits;
if(wl != null) {
canRead = wl.isReadable();
canWrite = wl.isWritable();
}
} else if(info instanceof LayerInfo || info instanceof ResourceInfo) {
DataAccessLimits dl;
if(info instanceof LayerInfo) {
dl = accessManager.getAccessLimits(user, (LayerInfo) info);
} else {
dl = accessManager.getAccessLimits(user, (ResourceInfo) info);
}
if(dl != null) {
canRead = dl.getReadFilter() != Filter.EXCLUDE;
if(dl instanceof VectorAccessLimits) {
canWrite = ((VectorAccessLimits) dl).getWriteFilter() != Filter.EXCLUDE;
} else {
canWrite = false;
}
}
limits = dl;
} else {
throw new IllegalArgumentException("Can't build the wrapper policy for objects " +
"other than workspace, layer or resource: " + info);
}
final CatalogMode mode = limits != null ? limits.getMode() : CatalogMode.HIDE;
if (!canRead) {
// if in hide mode, we just hide the resource
if (mode == CatalogMode.HIDE) {
return WrapperPolicy.hide(limits);
} else if (mode == CatalogMode.MIXED) {
// if request is a get capabilities and mixed, we hide again
Request request = Dispatcher.REQUEST.get();
if(request != null && "GetCapabilities".equalsIgnoreCase(request.getRequest()))
return WrapperPolicy.hide(limits);
// otherwise challenge the user for credentials
else
throw unauthorizedAccess(resourceName);
} else {
// for challenge mode we agree to show freely only the metadata, every
// other access will trigger a security exception
return WrapperPolicy.metadata(limits);
}
} else if (!canWrite) {
if (mode == CatalogMode.HIDE) {
return WrapperPolicy.readOnlyHide(limits);
} else {
return WrapperPolicy.readOnlyChallenge(limits);
}
}
return WrapperPolicy.readWrite(limits);
}
public static RuntimeException unauthorizedAccess(String resourceName) {
// not hide, and not filtering out a list, this
// is an unauthorized direct resource access, complain
Authentication user = user();
if (user == null || user.getAuthorities().size() == 0)
return new InsufficientAuthenticationException("Cannot access "
+ resourceName + " as anonymous");
else
return new AccessDeniedException("Cannot access "
+ resourceName + " with the current privileges");
}
public static RuntimeException unauthorizedAccess() {
// not hide, and not filtering out a list, this
// is an unauthorized direct resource access, complain
Authentication user = user();
if (user == null || user.getAuthorities().size() == 0)
return new InsufficientAuthenticationException("Operation unallowed with the current privileges");
else
return new AccessDeniedException("Operation unallowed with the current privileges");
}
/**
* Given a list of resources, returns a copy of it containing only the
* resources the user can access
*
* @param user
* @param resources
*
* @return
*/
protected <T extends ResourceInfo> List<T> filterResources(Authentication user,
List<T> resources) {
List<T> result = new ArrayList<T>();
for (T original : resources) {
T secured = checkAccess(user, original);
if (secured != null)
result.add(secured);
}
return result;
}
/**
* Given a list of stores, returns a copy of it containing only the
* resources the user can access
*
* @param user
* @param resources
*
* @return
*/
protected <T extends StoreInfo> List<T> filterStores(Authentication user, List<T> resources) {
List<T> result = new ArrayList<T>();
for (T original : resources) {
T secured = checkAccess(user, original);
if (secured != null)
result.add(secured);
}
return result;
}
/**
* Given a list of layer groups, returns a copy of it containing only the
* groups the user can access
*
* @param user
* @param groups
*
* @return
*/
protected List<LayerGroupInfo> filterGroups(Authentication user, List<LayerGroupInfo> groups) {
List<LayerGroupInfo> result = new ArrayList<LayerGroupInfo>();
for (LayerGroupInfo original : groups) {
LayerGroupInfo secured = checkAccess(user, original);
if (secured != null)
result.add(secured);
}
return result;
}
/**
* Given a list of layers, returns a copy of it containing only the layers
* the user can access
*
* @param user
* @param layers
*
* @return
*/
protected List<LayerInfo> filterLayers(Authentication user, List<LayerInfo> layers) {
List<LayerInfo> result = new ArrayList<LayerInfo>();
for (LayerInfo original : layers) {
LayerInfo secured = checkAccess(user, original);
if (secured != null)
result.add(secured);
}
return result;
}
/**
* Given a list of namespaces, returns a copy of it containing only the
* namespaces the user can access
*
* @param user
* @param namespaces
*
* @return
*/
protected <T extends NamespaceInfo> List<T> filterNamespaces(Authentication user,
List<T> namespaces) {
List<T> result = new ArrayList<T>();
for (T original : namespaces) {
T secured = checkAccess(user, original);
if (secured != null)
result.add(secured);
}
return result;
}
/**
* Given a list of workspaces, returns a copy of it containing only the
* workspaces the user can access
*
* @param user
* @param namespaces
*
* @return
*/
protected <T extends WorkspaceInfo> List<T> filterWorkspaces(Authentication user,
List<T> workspaces) {
List<T> result = new ArrayList<T>();
for (T original : workspaces) {
T secured = checkAccess(user, original);
if (secured != null)
result.add(secured);
}
return result;
}
// -------------------------------------------------------------------
// Unwrappers, used to make sure the lower level does not get hit by
// read only wrappers
// -------------------------------------------------------------------
static LayerGroupInfo unwrap(LayerGroupInfo layerGroup) {
if(layerGroup instanceof SecuredLayerGroupInfo)
return ((SecuredLayerGroupInfo) layerGroup).unwrap(LayerGroupInfo.class);
return layerGroup;
}
static LayerInfo unwrap(LayerInfo layer) {
if(layer instanceof SecuredLayerInfo)
return ((SecuredLayerInfo) layer).unwrap(LayerInfo.class);
return layer;
}
static ResourceInfo unwrap(ResourceInfo info) {
if(info instanceof SecuredFeatureTypeInfo)
return ((SecuredFeatureTypeInfo) info).unwrap(ResourceInfo.class);
if (info instanceof SecuredCoverageInfo)
return ((SecuredCoverageInfo) info).unwrap(ResourceInfo.class);
return info;
}
static StoreInfo unwrap(StoreInfo info) {
if(info instanceof SecuredDataStoreInfo)
return ((SecuredDataStoreInfo) info).unwrap(StoreInfo.class);
return info;
}
public static Object unwrap( Object obj ) {
if ( obj instanceof LayerGroupInfo ) {
return unwrap((LayerGroupInfo)obj);
}
if ( obj instanceof LayerInfo ) {
return unwrap((LayerInfo)obj);
}
if ( obj instanceof ResourceInfo ) {
return unwrap((ResourceInfo)obj);
}
if ( obj instanceof StoreInfo ) {
return unwrap((StoreInfo)obj);
}
if ( obj instanceof SecureCatalogImpl ) {
return ((SecureCatalogImpl)obj).delegate;
}
return obj;
}
// -------------------------------------------------------------------
// PURE DELEGATING METHODS
// (MapInfo being here since its role in the grand scheme of things
// is still undefined)
// -------------------------------------------------------------------
public MapInfo getMap(String id) {
return delegate.getMap(id);
}
public MapInfo getMapByName(String name) {
return delegate.getMapByName(name);
}
public List<MapInfo> getMaps() {
return delegate.getMaps();
}
public void add(LayerGroupInfo layerGroup) {
delegate.add(unwrap(layerGroup));
}
public List<RuntimeException> validate(LayerGroupInfo layerGroup, boolean isNew) {
return delegate.validate(unwrap(layerGroup), isNew);
}
public LayerGroupInfo detach(LayerGroupInfo layerGroup) {
return delegate.detach(layerGroup);
}
public void add(LayerInfo layer) {
delegate.add(unwrap(layer));
}
public List<RuntimeException> validate(LayerInfo layer, boolean isNew) {
return delegate.validate(unwrap(layer), isNew);
}
public LayerInfo detach(LayerInfo layer) {
return delegate.detach(layer);
}
public void add(MapInfo map) {
delegate.add(map);
}
public MapInfo detach(MapInfo map) {
return delegate.detach(map);
}
public void add(NamespaceInfo namespace) {
delegate.add(namespace);
}
public List<RuntimeException> validate(NamespaceInfo namespace, boolean isNew) {
return delegate.validate(namespace, isNew);
}
public NamespaceInfo detach(NamespaceInfo namespace) {
return delegate.detach(namespace);
}
public void add(ResourceInfo resource) {
delegate.add(unwrap(resource));
}
public List<RuntimeException> validate(ResourceInfo resource, boolean isNew) {
return delegate.validate(unwrap(resource), isNew);
}
public <T extends ResourceInfo> T detach(T resource) {
return delegate.detach(resource);
}
public void add(StoreInfo store) {
delegate.add(unwrap(store));
}
public List<RuntimeException> validate(StoreInfo store, boolean isNew) {
return delegate.validate(unwrap(store), isNew);
}
public <T extends StoreInfo> T detach(T store) {
return delegate.detach(store);
}
public void add(StyleInfo style) {
delegate.add(style);
}
public List<RuntimeException> validate(StyleInfo style, boolean isNew) {
return delegate.validate(style, isNew);
}
public StyleInfo detach(StyleInfo style) {
return delegate.detach(style);
}
public void add(WorkspaceInfo workspace) {
delegate.add(workspace);
}
public List<RuntimeException> validate(WorkspaceInfo workspace, boolean isNew) {
return delegate.validate(workspace, isNew);
}
public WorkspaceInfo detach(WorkspaceInfo workspace) {
return delegate.detach(workspace);
}
public void addListener(CatalogListener listener) {
delegate.addListener(listener);
}
public void dispose() {
delegate.dispose();
}
public CatalogFacade getFacade() {
return delegate.getFacade();
}
public CatalogFactory getFactory() {
return delegate.getFactory();
}
public Collection<CatalogListener> getListeners() {
return delegate.getListeners();
}
public void fireAdded(CatalogInfo object) {
delegate.fireAdded(object);
}
public void fireModified(CatalogInfo object, List<String> propertyNames, List oldValues,
List newValues) {
delegate.fireModified(object, propertyNames, oldValues, newValues);
}
public void firePostModified(CatalogInfo object) {
delegate.firePostModified(object);
}
public void fireRemoved(CatalogInfo object) {
delegate.fireRemoved(object);
}
// TODO: why is resource pool being exposed???
public ResourcePool getResourcePool() {
return delegate.getResourcePool();
}
public StyleInfo getStyle(String id) {
return delegate.getStyle(id);
}
public StyleInfo getStyleByName(String name) {
return delegate.getStyleByName(name);
}
public List<StyleInfo> getStyles() {
return delegate.getStyles();
}
public void remove(LayerGroupInfo layerGroup) {
delegate.remove(unwrap(layerGroup));
}
public void remove(LayerInfo layer) {
delegate.remove(unwrap(layer));
}
public void remove(MapInfo map) {
delegate.remove(map);
}
public void remove(NamespaceInfo namespace) {
delegate.remove(namespace);
}
public void remove(ResourceInfo resource) {
delegate.remove(unwrap(resource));
}
public void remove(StoreInfo store) {
delegate.remove(unwrap(store));
}
public void remove(StyleInfo style) {
delegate.remove(style);
}
public void remove(WorkspaceInfo workspace) {
delegate.remove(workspace);
}
public void removeListener(CatalogListener listener) {
delegate.removeListener(listener);
}
public void save(LayerGroupInfo layerGroup) {
delegate.save(unwrap(layerGroup));
}
public void save(LayerInfo layer) {
delegate.save(unwrap(layer));
}
public void save(MapInfo map) {
delegate.save(map);
}
public void save(NamespaceInfo namespace) {
delegate.save(namespace);
}
public void save(ResourceInfo resource) {
delegate.save(unwrap(resource));
}
public void save(StoreInfo store) {
delegate.save(unwrap(store));
}
public void save(StyleInfo style) {
delegate.save(style);
}
public void save(WorkspaceInfo workspace) {
delegate.save(workspace);
}
public void setDefaultNamespace(NamespaceInfo defaultNamespace) {
delegate.setDefaultNamespace(defaultNamespace);
}
public void setDefaultWorkspace(WorkspaceInfo workspace) {
delegate.setDefaultWorkspace(workspace);
}
public void setResourcePool(ResourcePool resourcePool) {
delegate.setResourcePool(resourcePool);
}
public GeoServerResourceLoader getResourceLoader() {
return delegate.getResourceLoader();
}
public void setResourceLoader(GeoServerResourceLoader resourceLoader) {
delegate.setResourceLoader(resourceLoader);
}
public void accept(CatalogVisitor visitor) {
delegate.accept(visitor);
}
public DataStoreInfo getDefaultDataStore(WorkspaceInfo workspace) {
return checkAccess(user(), delegate.getDefaultDataStore(workspace));
}
public void setDefaultDataStore(WorkspaceInfo workspace, DataStoreInfo defaultStore) {
delegate.setDefaultDataStore(workspace, defaultStore);
}
}