/* (c) 2017 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.rest.catalog; import org.geoserver.catalog.Catalog; import org.geoserver.catalog.CatalogBuilder; import org.geoserver.catalog.ResourceInfo; import org.geoserver.config.GeoServerDataDirectory; import org.geoserver.platform.GeoServerExtensions; import org.geoserver.rest.RestBaseController; import org.geoserver.rest.RestException; import org.geoserver.security.GeoServerSecurityManager; import org.geotools.referencing.CRS; import org.opengis.referencing.crs.CoordinateReferenceSystem; import org.springframework.http.HttpStatus; import org.springframework.security.core.context.SecurityContextHolder; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * Base controller for catalog info requests */ public abstract class AbstractCatalogController extends RestBaseController { protected final Catalog catalog; protected final GeoServerDataDirectory dataDir; protected final List<String> validImageFileExtensions; public AbstractCatalogController(Catalog catalog) { super(); this.catalog = catalog; this.dataDir = new GeoServerDataDirectory(catalog.getResourceLoader()); this.validImageFileExtensions = Arrays.asList("svg", "png", "jpg"); } /** * Uses messages as a template to update resource. * @param message Possibly incomplete ResourceInfo used to update resource * @param resource Original resource (to be saved in catalog after modification) */ protected void calculateOptionalFields(ResourceInfo message, ResourceInfo resource, String calculate) { List<String> fieldsToCalculate; if (calculate == null || calculate.isEmpty()) { boolean changedProjection = message.getSRS() == null || !message.getSRS().equals(resource.getSRS()); boolean changedProjectionPolicy = message.getProjectionPolicy() == null || !message.getProjectionPolicy().equals(resource.getProjectionPolicy()); boolean changedNativeBounds = message.getNativeBoundingBox() == null || !message.getNativeBoundingBox().equals(resource.getNativeBoundingBox()); boolean changedLatLonBounds = message.getLatLonBoundingBox() == null || !message.getLatLonBoundingBox().equals(resource.getLatLonBoundingBox()); boolean changedNativeInterpretation = changedProjectionPolicy || changedProjection; fieldsToCalculate = new ArrayList<>(); if (changedNativeInterpretation && !changedNativeBounds) { fieldsToCalculate.add("nativebbox"); } if ((changedNativeInterpretation || changedNativeBounds) && !changedLatLonBounds) { fieldsToCalculate.add("latlonbbox"); } } else { fieldsToCalculate = Arrays.asList(calculate.toLowerCase().split(",")); } if (fieldsToCalculate.contains("nativebbox")) { CatalogBuilder builder = new CatalogBuilder(catalog); try { message.setNativeBoundingBox(builder.getNativeBounds(message)); } catch (IOException e) { String errorMessage = "Error while calculating native bounds for layer: " + message; throw new RestException(errorMessage, HttpStatus.INTERNAL_SERVER_ERROR, e); } } if (fieldsToCalculate.contains("latlonbbox")) { CatalogBuilder builder = new CatalogBuilder(catalog); try { message.setLatLonBoundingBox(builder.getLatLonBounds( message.getNativeBoundingBox(), resolveCRS(message.getSRS()))); } catch (IOException e) { String errorMessage = "Error while calculating lat/lon bounds for featuretype: " + message; throw new RestException(errorMessage, HttpStatus.INTERNAL_SERVER_ERROR, e); } } } private CoordinateReferenceSystem resolveCRS(String srs) { if ( srs == null ) { return null; } try { return CRS.decode(srs); } catch(Exception e) { throw new RuntimeException("This is unexpected, the layer seems to be mis-configured", e); } } /** * Determines if the current user is authenticated as full administrator. */ protected boolean isAuthenticatedAsAdmin() { return SecurityContextHolder.getContext() != null && GeoServerExtensions.bean(GeoServerSecurityManager.class).checkAuthenticationForAdminRole(); } /** * Validates the current user can edit the resource (full admin required if workspaceName is null) * @param workspaceName */ protected void checkFullAdminRequired(String workspaceName) { // global workspaces/styles can only be edited by a full admin if (workspaceName == null && !isAuthenticatedAsAdmin()) { throw new RestException("Cannot edit global resource , full admin credentials required", HttpStatus.METHOD_NOT_ALLOWED); } } }