/* (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.decorators;
import java.io.IOException;
import org.geoserver.catalog.FeatureTypeInfo;
import org.geoserver.security.Response;
import org.geoserver.security.SecureCatalogImpl;
import org.geoserver.security.WrapperPolicy;
import org.geotools.data.DataAccess;
import org.geotools.data.FeatureSource;
import org.geotools.data.FeatureStore;
import org.opengis.feature.Feature;
import org.opengis.feature.type.FeatureType;
import org.opengis.feature.type.Name;
/**
* Given a {@link DataAccess} subclass makes sure no write operations can be
* performed through it. Regardless of the policy the data access is kept read only as
* services are supposed to perform writes via {@link FeatureStore} instances returned
* by {@link FeatureTypeInfo} and not via direct calls to data access.
*
* @author Andrea Aime - TOPP
*
* @param <T>
* @param <F>
*/
public class ReadOnlyDataAccess<T extends FeatureType, F extends Feature> extends
DecoratingDataAccess<T, F> {
static final String READ_ONLY = "This data access is read only";
private WrapperPolicy policy;
ReadOnlyDataAccess(DataAccess<T, F> delegate, WrapperPolicy policy) {
super(delegate);
this.policy = policy;
}
@Override
public FeatureSource<T, F> getFeatureSource(Name typeName) throws IOException {
final FeatureSource<T, F> fs = super.getFeatureSource(typeName);
if (fs == null)
return null;
return (FeatureSource) SecuredObjects.secure(fs, policy);
}
@Override
public void createSchema(T featureType) throws IOException {
throw notifyUnsupportedOperation();
}
@Override
public void updateSchema(Name typeName, T featureType) throws IOException {
throw notifyUnsupportedOperation();
}
@Override
public void removeSchema(Name typeName) throws IOException {
throw notifyUnsupportedOperation();
}
/**
* Notifies the caller the requested operation is not supported, using a plain {@link UnsupportedOperationException}
* in case we have to conceal the fact the data is actually writable, using an Spring Security security exception otherwise
* to force an authentication from the user
*/
RuntimeException notifyUnsupportedOperation() {
if(policy.response == Response.CHALLENGE) {
return SecureCatalogImpl.unauthorizedAccess();
} else
return new UnsupportedOperationException("This data access is read only, service code is supposed to perform writes via FeatureStore instead");
}
}