/* (c) 2013-2016 Open Source Geospatial Foundation - all rights reserved
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.geofence;
import java.util.*;
import org.springframework.mock.web.MockHttpServletRequest;
import org.geoserver.catalog.*;
import org.geoserver.catalog.impl.*;
import org.geoserver.data.test.MockData;
import org.geoserver.ows.Dispatcher;
import org.geoserver.ows.Request;
import org.geoserver.security.VectorAccessLimits;
import org.geoserver.security.WorkspaceAccessLimits;
import org.geoserver.wms.GetMapRequest;
import org.geoserver.wms.MapLayerInfo;
import org.geotools.factory.CommonFactoryFinder;
import org.opengis.filter.Filter;
import org.opengis.filter.FilterFactory2;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.io.WKTReader;
import org.junit.Test;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.RequestContextListener;
import org.springframework.web.context.request.ServletRequestAttributes;
public class AccessManagerTest extends GeofenceBaseTest
{
/**
* Override to have the code access the raw catalog
*/
protected Catalog getCatalog()
{
return (Catalog) applicationContext.getBean("rawCatalog");
}
public void testAdmin()
{
UsernamePasswordAuthenticationToken user = new UsernamePasswordAuthenticationToken("admin",
"geoserver",
Arrays.asList(
new GrantedAuthority[] { new SimpleGrantedAuthority("ROLE_ADMINISTRATOR") } ));
// check workspace access
WorkspaceInfo citeWS = getCatalog().getWorkspaceByName(MockData.CITE_PREFIX);
WorkspaceAccessLimits wl = accessManager.getAccessLimits(user, citeWS);
assertTrue(wl.isReadable());
assertTrue(wl.isWritable());
// check layer access
LayerInfo layer = getCatalog().getLayerByName(getLayerId(MockData.BASIC_POLYGONS));
VectorAccessLimits vl = (VectorAccessLimits) accessManager.getAccessLimits(user, layer);
assertEquals(Filter.INCLUDE, vl.getReadFilter());
assertEquals(Filter.INCLUDE, vl.getWriteFilter());
assertNull(vl.getReadAttributes());
assertNull(vl.getWriteAttributes());
}
public void testCiteCannotWriteOnWorkspace()
{
configManager.getConfiguration().setGrantWriteToWorkspacesToAuthenticatedUsers(false);
UsernamePasswordAuthenticationToken user = new UsernamePasswordAuthenticationToken("cite",
"cite",
Arrays.asList(
new GrantedAuthority[] { new SimpleGrantedAuthority("ROLE_AUTHENTICATED") } ));
// check workspace access
WorkspaceInfo citeWS = getCatalog().getWorkspaceByName(MockData.CITE_PREFIX);
WorkspaceAccessLimits wl = accessManager.getAccessLimits(user, citeWS);
assertTrue(wl.isReadable());
assertFalse(wl.isWritable());
}
public void testCiteCanWriteOnWorkspace()
{
configManager.getConfiguration().setGrantWriteToWorkspacesToAuthenticatedUsers(true);
UsernamePasswordAuthenticationToken user = new UsernamePasswordAuthenticationToken("cite",
"cite",
Arrays.asList(
new GrantedAuthority[] { new SimpleGrantedAuthority("ROLE_AUTHENTICATED") } ));
// check workspace access
WorkspaceInfo citeWS = getCatalog().getWorkspaceByName(MockData.CITE_PREFIX);
WorkspaceAccessLimits wl = accessManager.getAccessLimits(user, citeWS);
assertTrue(wl.isReadable());
assertTrue(wl.isWritable());
configManager.getConfiguration().setGrantWriteToWorkspacesToAuthenticatedUsers(false);
}
@Test
public void testAnonymousUser()
{
// check workspace access
// WorkspaceInfo citeWS = getCatalog().getWorkspaceByName(MockData.CITE_PREFIX);
// WorkspaceAccessLimits wl = manager.getAccessLimits(null, citeWS);
// assertFalse(wl.isReadable());
// assertFalse(wl.isWritable());
// check layer access
LayerInfo layer = getCatalog().getLayerByName(getLayerId(MockData.BASIC_POLYGONS));
VectorAccessLimits vl = (VectorAccessLimits) accessManager.getAccessLimits(null, layer);
assertEquals(Filter.EXCLUDE, vl.getReadFilter());
assertEquals(Filter.EXCLUDE, vl.getWriteFilter());
assertNull(vl.getReadAttributes());
assertNull(vl.getWriteAttributes());
}
public void IGNOREtestCiteWorkspaceAccess()
{
UsernamePasswordAuthenticationToken user = new UsernamePasswordAuthenticationToken("cite",
"cite");
// check workspace access on cite
WorkspaceInfo citeWS = getCatalog().getWorkspaceByName(MockData.CITE_PREFIX);
WorkspaceAccessLimits wl = accessManager.getAccessLimits(user, citeWS);
assertTrue(wl.isReadable());
assertTrue(wl.isWritable());
// check workspace access on any other but not cite and sf (should fail)
WorkspaceInfo cdfWS = getCatalog().getWorkspaceByName(MockData.CDF_PREFIX);
wl = accessManager.getAccessLimits(user, cdfWS);
assertFalse(wl.isReadable());
assertFalse(wl.isWritable());
// check workspace access on sf (should work, we can do at least a getmap)
WorkspaceInfo sfWS = getCatalog().getWorkspaceByName(MockData.SF_PREFIX);
wl = accessManager.getAccessLimits(user, sfWS);
assertTrue(wl.isReadable());
assertTrue(wl.isWritable());
}
public void testCiteLayerAccess()
{
UsernamePasswordAuthenticationToken user = new UsernamePasswordAuthenticationToken("cite",
"cite");
// check layer in the cite workspace
LayerInfo bpolygons = getCatalog().getLayerByName(getLayerId(MockData.BASIC_POLYGONS));
VectorAccessLimits vl = (VectorAccessLimits) accessManager.getAccessLimits(user, bpolygons);
assertEquals(Filter.INCLUDE, vl.getReadFilter());
assertEquals(Filter.INCLUDE, vl.getWriteFilter());
assertNull(vl.getReadAttributes());
assertNull(vl.getWriteAttributes());
// check layer in the sf workspace with a wfs request
Request request = new Request();
request.setService("WFS");
request.setRequest("GetFeature");
Dispatcher.REQUEST.set(request);
LayerInfo generic = getCatalog().getLayerByName(getLayerId(MockData.GENERICENTITY));
vl = (VectorAccessLimits) accessManager.getAccessLimits(user, generic);
assertEquals(Filter.EXCLUDE, vl.getReadFilter());
assertEquals(Filter.EXCLUDE, vl.getWriteFilter());
// now fake a getmap request (using a service and request with a different case than the
// geofenceService)
request = new Request();
request.setService("WmS");
request.setRequest("gETmAP");
Dispatcher.REQUEST.set(request);
vl = (VectorAccessLimits) accessManager.getAccessLimits(user, generic);
assertEquals(Filter.INCLUDE, vl.getReadFilter());
assertEquals(Filter.INCLUDE, vl.getWriteFilter());
}
public void testWmsLimited()
{
UsernamePasswordAuthenticationToken user = new UsernamePasswordAuthenticationToken(
"wmsuser", "wmsuser");
// check layer in the sf workspace with a wfs request
Request request = new Request();
request.setService("WFS");
request.setRequest("GetFeature");
Dispatcher.REQUEST.set(request);
LayerInfo generic = getCatalog().getLayerByName(getLayerId(MockData.GENERICENTITY));
VectorAccessLimits vl = (VectorAccessLimits) accessManager.getAccessLimits(user, generic);
assertEquals(Filter.EXCLUDE, vl.getReadFilter());
assertEquals(Filter.EXCLUDE, vl.getWriteFilter());
// now fake a getmap request (using a service and request with a different case than the
// geofenceService)
request = new Request();
request.setService("wms");
Dispatcher.REQUEST.set(request);
vl = (VectorAccessLimits) accessManager.getAccessLimits(user, generic);
assertEquals(Filter.INCLUDE, vl.getReadFilter());
assertEquals(Filter.INCLUDE, vl.getWriteFilter());
}
public void testAreaLimited() throws Exception
{
UsernamePasswordAuthenticationToken user = new UsernamePasswordAuthenticationToken(
"area", "area");
// check we have the geometry filter set
LayerInfo generic = getCatalog().getLayerByName(getLayerId(MockData.GENERICENTITY));
VectorAccessLimits vl = (VectorAccessLimits) accessManager.getAccessLimits(user, generic);
FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2(null);
Geometry limit = new WKTReader().read("MULTIPOLYGON(((48 62, 48 63, 49 63, 49 62, 48 62)))");
Filter filter = ff.intersects(ff.property(""), ff.literal(limit));
assertEquals(filter, vl.getReadFilter());
assertEquals(filter, vl.getWriteFilter());
}
/**
* This test is very similar to testAreaLimited(), but the source resource is set to have the 900913 SRS.
* We expect that the allowedarea is projected into the resource CRS.
*
*/
public void testArea900913() throws Exception
{
UsernamePasswordAuthenticationToken user = new UsernamePasswordAuthenticationToken(
"area", "area");
LayerInfo generic = getCatalog().getLayerByName(getLayerId(MockData.GENERICENTITY));
// Create a layer using as much as info from the Mock instance, making sure we're declaring the 900913 SRS.
WorkspaceInfoImpl ws = new WorkspaceInfoImpl();
ws.setName(generic.getResource().getStore().getWorkspace().getName());
StoreInfo store = new DataStoreInfoImpl(getCatalog());
store.setWorkspace(ws);
FeatureTypeInfoImpl resource = new FeatureTypeInfoImpl(getCatalog());
resource.setNamespace(generic.getResource().getNamespace());
resource.setSRS("EPSG:900913");
resource.setName(generic.getResource().getName());
resource.setStore(store);
LayerInfoImpl layerInfo = new LayerInfoImpl();
layerInfo.setResource(resource);
layerInfo.setName(generic.getName());
// Check we have the geometry filter set
VectorAccessLimits vl = (VectorAccessLimits) accessManager.getAccessLimits(user, resource);
FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2(null);
Geometry limit = new WKTReader().read(" MULTIPOLYGON (((5343335.558077131 8859142.800565697, 5343335.558077131 9100250.907059547, 5454655.048870404 9100250.907059547, 5454655.048870404 8859142.800565697, 5343335.558077131 8859142.800565697)))");
Filter filter = ff.intersects(ff.property(""), ff.literal(limit));
assertEquals(filter, vl.getReadFilter());
assertEquals(filter, vl.getWriteFilter());
}
@Test
public void testWmsGetMapRequestWithLayerGroupAndNormalLayerAndStyles() {
MockHttpServletRequest request = new MockHttpServletRequest();
RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request));
List<PublishedInfo> layers = new ArrayList<>();
layers.add(getCatalog().getLayerByName("Buildings"));
layers.add(getCatalog().getLayerByName("DividedRoutes"));
List<StyleInfo> styles = new ArrayList<>();
styles.add(getCatalog().getLayerByName("Buildings").getDefaultStyle());
styles.add(getCatalog().getLayerByName("DividedRoutes").getDefaultStyle());
LayerGroupInfoImpl layerGroup = new LayerGroupInfoImpl();
layerGroup.setName("layer_group");
layerGroup.setLayers(layers);
layerGroup.setStyles(styles);
getCatalog().add(layerGroup);
Map kvp = new HashMap<>();
kvp.put("LAYERS", "layer_group,Bridges");
kvp.put("layers", "layer_group,Bridges");
kvp.put("STYLES", ",lines");
Request gsRequest = new Request();
gsRequest.setKvp(kvp);
gsRequest.setRawKvp(kvp);
String service = "WMS";
String requestName = "GetMap";
Authentication user = new UsernamePasswordAuthenticationToken("admin", "geoserver", Arrays.asList(
new GrantedAuthority[] { new SimpleGrantedAuthority("ROLE_ADMINISTRATOR") } ));
SecurityContextHolder.getContext().setAuthentication(user);
List<MapLayerInfo> mapLayersInfos = new ArrayList<>();
mapLayersInfos.add(new MapLayerInfo(getCatalog().getLayerByName("Buildings")));
mapLayersInfos.add(new MapLayerInfo(getCatalog().getLayerByName("DividedRoutes")));
mapLayersInfos.add(new MapLayerInfo(getCatalog().getLayerByName("Bridges")));
GetMapRequest getMap = new GetMapRequest();
getMap.setLayers(mapLayersInfos);
accessManager.overrideGetMapRequest(gsRequest, service, requestName, user, getMap);
}
}