/* Copyright (c) 2001 - 2007 TOPP - www.openplans.org. All rights reserved. * This code is licensed under the GPL 2.0 license, availible at the root * application directory. */ package org.geoserver.xacml.geoxacml; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.net.URL; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import org.geoserver.platform.GeoServerExtensions; import org.geoserver.xacml.request.RequestCtxBuilderFactory; import org.geoserver.xacml.request.RequestCtxBuilderFactoryImpl; import org.geoserver.xacml.role.XACMLDefaultRoleAuthority; import org.geoserver.xacml.role.XACMLRoleAuthority; import org.geotools.xacml.geoxacml.config.GeoXACML; import org.geotools.xacml.geoxacml.finder.impl.GeoSelectorModule; import org.geotools.xacml.transport.XACMLLocalTransportFactory; import org.geotools.xacml.transport.XACMLTransport; import org.geotools.xacml.transport.XACMLTransportFactory; import org.vfny.geoserver.global.GeoserverDataDirectory; import com.sun.xacml.PDP; import com.sun.xacml.PDPConfig; import com.sun.xacml.finder.AttributeFinder; import com.sun.xacml.finder.AttributeFinderModule; import com.sun.xacml.finder.PolicyFinder; import com.sun.xacml.finder.PolicyFinderModule; import com.sun.xacml.finder.impl.CurrentEnvModule; /** * @author Christian Mueller * * GeoXAMCL Configuration for Geoserver environment * */ public class GeoXACMLConfig { private static PDP pdp; private static Object pdpLock = new Object(); private static XACMLTransportFactory transportFactory; private static Object transportFactoryLock = new Object(); private static XACMLRoleAuthority raa; private static Object raaLock = new Object(); private static RequestCtxBuilderFactory requstCtxBuilderFactory; private static Object requstCtxBuilderFactoryLock = new Object(); private static String repositoryBaseDir = null; static public void reset() { synchronized (pdpLock) { pdp = null; } synchronized (transportFactoryLock) { transportFactory = null; } } static public void reload() { reset(); getPDP(); } static public void setPolicyRepsoitoryBaseDir(String baseDir) { repositoryBaseDir = baseDir; } /** * @return a XAMCL PDP (Policy Declision Point) for the geoserver environment */ static protected PDP getPDP() { synchronized (pdpLock) { if (pdp != null) return pdp; // initialize the geotools part GeoXACML.initialize(); DataDirPolicyFinderModlule policyModule = new DataDirPolicyFinderModlule(); if (repositoryBaseDir != null) policyModule.setBaseDir(repositoryBaseDir); PolicyFinder policyFinder = new PolicyFinder(); Set<PolicyFinderModule> policyModules = new HashSet<PolicyFinderModule>(); policyModules.add(policyModule); policyFinder.setModules(policyModules); // for current time, current date .... CurrentEnvModule envModule = new CurrentEnvModule(); // xpath support GeoSelectorModule selectorModule = new GeoSelectorModule(); AttributeFinder attrFinder = new AttributeFinder(); List<AttributeFinderModule> attrModules = new ArrayList<AttributeFinderModule>(); attrModules.add(envModule); attrModules.add(selectorModule); attrFinder.setModules(attrModules); pdp = new PDP(new PDPConfig(attrFinder, policyFinder, null)); XACMLUtil.getXACMLLogger().info("GeoXACML repository loaded "); return pdp; } } /** * Use GeoserverExtensions to create a {@link XACMLRoleAuthority} If nothing is configured, use * {@link XACMLDefaultRoleAuthority} * * @return a RoleAssignmentAuthorty */ static public XACMLRoleAuthority getXACMLRoleAuthority() { synchronized (raaLock) { if (raa != null) return raa; raa = GeoServerExtensions.bean(XACMLRoleAuthority.class); if (raa == null) { raa = new XACMLDefaultRoleAuthority(); } return raa; } } static public XACMLTransport getXACMLTransport() { return getXACMLTransportFacytory().getXACMLTransport(); } static private XACMLTransportFactory getXACMLTransportFacytory() { if (transportFactory != null) return transportFactory; synchronized (transportFactoryLock) { if (transportFactory != null) return transportFactory; transportFactory = GeoServerExtensions.bean(XACMLTransportFactory.class); if (transportFactory == null) transportFactory = new XACMLLocalTransportFactory(getPDP(), true); return transportFactory; } } static public RequestCtxBuilderFactory getRequestCtxBuilderFactory() { if (requstCtxBuilderFactory != null) return requstCtxBuilderFactory; synchronized (requstCtxBuilderFactoryLock) { if (requstCtxBuilderFactory != null) return requstCtxBuilderFactory; requstCtxBuilderFactory = GeoServerExtensions.bean(RequestCtxBuilderFactory.class); if (requstCtxBuilderFactory == null) requstCtxBuilderFactory = new RequestCtxBuilderFactoryImpl(); ; return requstCtxBuilderFactory; } } public static void createDefaultRepositoryIfNotExisting() { File geoServerDataDir = GeoserverDataDirectory.getGeoserverDataDirectory(); if (geoServerDataDir == null) { return; } createDirectoryIfNotExisting(new File(geoServerDataDir, DataDirPolicyFinderModlule.BASE_DIR)); String byRequestDir = DataDirPolicyFinderModlule.BASE_DIR + "/" + DataDirPolicyFinderModlule.BY_REQUEST_DIR; String byReferenceDir = DataDirPolicyFinderModlule.BASE_DIR + "/" + DataDirPolicyFinderModlule.BY_REFERENCE_DIR; String commonDir = byReferenceDir + "/common"; String anonymousDir = byReferenceDir + "/anonymous"; String authenticatedDir = byReferenceDir + "/authenticated"; String roleDir = byReferenceDir + "/role"; String demoDir = "demo"; createDirectoryIfNotExisting(new File(geoServerDataDir, byRequestDir)); createDirectoryIfNotExisting(new File(geoServerDataDir, byReferenceDir)); createDirectoryIfNotExisting(new File(geoServerDataDir, commonDir)); createDirectoryIfNotExisting(new File(geoServerDataDir, anonymousDir)); createDirectoryIfNotExisting(new File(geoServerDataDir, authenticatedDir)); createDirectoryIfNotExisting(new File(geoServerDataDir, roleDir)); copyFileIfNotExisting(geoServerDataDir, commonDir + "/PermitAll.xml"); copyFileIfNotExisting(geoServerDataDir, commonDir + "/DenyAll.xml"); copyFileIfNotExisting(geoServerDataDir, anonymousDir + "/PAnonymous.xml"); copyFileIfNotExisting(geoServerDataDir, anonymousDir + "/URLAnonymous.xml"); copyFileIfNotExisting(geoServerDataDir, authenticatedDir + "/PAuthenticated.xml"); copyFileIfNotExisting(geoServerDataDir, authenticatedDir + "/URLAuthenticated.xml"); copyFileIfNotExisting(geoServerDataDir, roleDir + "/PRole.xml"); copyFileIfNotExisting(geoServerDataDir, byRequestDir + "/Admin.xml"); copyFileIfNotExisting(geoServerDataDir, byRequestDir + "/Catalog.xml"); copyFileIfNotExisting(geoServerDataDir, byRequestDir + "/Role.xml"); copyFileIfNotExisting(geoServerDataDir, byRequestDir + "/Anonymous.xml"); copyFileIfNotExisting(geoServerDataDir, byRequestDir + "/Authenticated.xml"); // copy demo urls if demo dir exists if (new File(geoServerDataDir, demoDir).exists()) { copyFileIfNotExisting(geoServerDataDir, demoDir + "/XACML_reloadRepository.url"); } } private static void createDirectoryIfNotExisting(File dir) { if (dir.exists()) return; dir.mkdir(); } private static void copyFileIfNotExisting(File geoServerDataDir, String relativePath) { File file = new File(geoServerDataDir, relativePath); if (file.exists()) return; URL sourceURL = GeoXACMLConfig.class.getResource("/geoserverdatadir/" + relativePath); try { InputStream in = sourceURL.openStream(); OutputStream out = new FileOutputStream(file); byte[] buffer = new byte[4096]; int bytesread = 0; while ((bytesread = in.read(buffer)) > 0) out.write(buffer, 0, bytesread); in.close(); out.close(); } catch (Exception e) { XACMLUtil.getXACMLLogger().severe( "Could not create default repository file " + relativePath); throw new RuntimeException(e); } } }