/* * Copyright (c) 2008, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.wso2.carbon.registry.extensions.handlers; import org.apache.axiom.om.OMElement; import org.apache.axiom.om.util.AXIOMUtil; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.registry.common.utils.artifact.manager.ArtifactManager; import org.wso2.carbon.registry.core.*; import org.wso2.carbon.registry.core.config.RegistryContext; import org.wso2.carbon.registry.core.exceptions.RegistryException; import org.wso2.carbon.registry.core.jdbc.handlers.Handler; import org.wso2.carbon.registry.core.jdbc.handlers.RequestContext; import org.wso2.carbon.registry.core.session.CurrentSession; import org.wso2.carbon.registry.core.utils.RegistryUtils; import org.wso2.carbon.registry.extensions.services.Utils; import org.wso2.carbon.registry.extensions.utils.CommonConstants; import org.wso2.carbon.registry.extensions.utils.CommonUtil; import javax.xml.namespace.QName; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.*; public class PolicyMediaTypeHandler extends Handler { private static final Log log = LogFactory.getLog(PolicyMediaTypeHandler.class); private String location = "/policies/"; private String locationTag = "location"; private OMElement locationConfiguration; private String identityPolicyPath = "/_system/config/repository/components/org.wso2.carbon.security.mgt/policy"; public OMElement getPolicyLocationConfiguration() { return locationConfiguration; } public void setPolicyLocationConfiguration(OMElement locationConfiguration) throws RegistryException { Iterator confElements = locationConfiguration.getChildElements(); while (confElements.hasNext()) { OMElement confElement = (OMElement)confElements.next(); if (confElement.getQName().equals(new QName(locationTag))) { location = confElement.getText(); if (!location.startsWith(RegistryConstants.PATH_SEPARATOR)) { location = RegistryConstants.PATH_SEPARATOR + location; } if (!location.endsWith(RegistryConstants.PATH_SEPARATOR)) { location = location + RegistryConstants.PATH_SEPARATOR; } } } this.locationConfiguration = locationConfiguration; } public void put(RequestContext requestContext) throws RegistryException { if (!CommonUtil.isUpdateLockAvailable()) { return; } CommonUtil.acquireUpdateLock(); try { if (requestContext == null) { throw new RegistryException("The request context is not available."); } String path = requestContext.getResourcePath().getPath(); Resource resource = requestContext.getResource(); Registry registry = requestContext.getRegistry(); Object resourceContentObj = resource.getContent(); String resourceContent; // here the resource content is url if (resourceContentObj instanceof String) { resourceContent = (String)resourceContentObj; resource.setContent(RegistryUtils.encodeString(resourceContent)); } else { resourceContent = RegistryUtils.decodeBytes((byte[])resourceContentObj); } try { if (registry.resourceExists(path)) { Resource oldResource = registry.get(path); byte[] oldContent = (byte[])oldResource.getContent(); if (oldContent != null && RegistryUtils.decodeBytes(oldContent).equals(resourceContent)) { // this will continue adding from the default path. return; } } } catch (Exception e) { String msg = "Error in comparing the policy content updates. policy path: " + path + "."; log.error(msg, e); throw new RegistryException(msg, e); } Object newContent = RegistryUtils.encodeString((String)resourceContent); if (newContent != null) { InputStream inputStream = new ByteArrayInputStream((byte[])newContent); addPolicyToRegistry(requestContext, inputStream); } ArtifactManager.getArtifactManager().getTenantArtifactRepository().addArtifact(path); } finally { CommonUtil.releaseUpdateLock(); } } public void importResource(RequestContext requestContext) throws RegistryException { if (!CommonUtil.isUpdateLockAvailable()) { return; } CommonUtil.acquireUpdateLock(); try { String sourceURL = requestContext.getSourceURL(); InputStream inputStream; try { if (sourceURL != null && sourceURL.toLowerCase().startsWith("file:")) { String msg = "The source URL must not be file in the server's local file system"; throw new RegistryException(msg); } inputStream = new URL(sourceURL).openStream(); } catch (IOException e) { throw new RegistryException("The URL " + sourceURL + " is incorrect.", e); } addPolicyToRegistry(requestContext, inputStream); } finally { CommonUtil.releaseUpdateLock(); } } private void addPolicyToRegistry(RequestContext requestContext, InputStream inputStream) throws RegistryException { Resource policyResource; if (requestContext.getResource() == null) { policyResource = new ResourceImpl(); policyResource.setMediaType("application/policy+xml"); } else { policyResource = requestContext.getResource(); } String version = requestContext.getResource().getProperty(RegistryConstants.VERSION_PARAMETER_NAME); if (version == null) { version = CommonConstants.POLICY_VERSION_DEFAULT_VALUE; requestContext.getResource().setProperty(RegistryConstants.VERSION_PARAMETER_NAME, version); } Registry registry = requestContext.getRegistry(); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); int nextChar; try { while ((nextChar = inputStream.read()) != -1) { outputStream.write(nextChar); } outputStream.flush(); } catch (IOException e) { throw new RegistryException("Exception occured while reading policy content", e); } try { AXIOMUtil.stringToOM(RegistryUtils.decodeBytes(outputStream.toByteArray())).toString(); } catch (Exception e) { throw new RegistryException("The given policy file does not contain valid XML."); } String resourcePath = requestContext.getResourcePath().getPath(); String policyFileName = resourcePath.substring(resourcePath.lastIndexOf(RegistryConstants.PATH_SEPARATOR) + 1); Registry systemRegistry = CommonUtil.getUnchrootedSystemRegistry(requestContext); RegistryContext registryContext = requestContext.getRegistryContext(); String commonLocation = getChrootedLocation(registryContext); if (!systemRegistry.resourceExists(commonLocation)) { systemRegistry.put(commonLocation, systemRegistry.newCollection()); } String policyPath; // This logic to handle IS related policy location if (isIdentityPolicyPath(requestContext)){ policyPath = requestContext.getResourcePath().getCompletePath(); } else{ policyPath = getPolicyLocation(requestContext, policyFileName,commonLocation, resourcePath,version); } // CommonUtil.addGovernanceArtifactEntryWithAbsoluteValues( // CommonUtil.getUnchrootedSystemRegistry(requestContext), // policyId, policyPath); String relativeArtifactPath = RegistryUtils.getRelativePath(registry.getRegistryContext(), policyPath); // adn then get the relative path to the GOVERNANCE_BASE_PATH relativeArtifactPath = RegistryUtils.getRelativePathToOriginal(relativeArtifactPath, RegistryConstants.GOVERNANCE_REGISTRY_BASE_PATH); Resource newResource; if (registry.resourceExists(policyPath)) { newResource = registry.get(policyPath); } else { newResource = new ResourceImpl(); Properties properties = policyResource.getProperties(); if (properties != null) { List<String> linkProperties = Arrays.asList( RegistryConstants.REGISTRY_LINK, RegistryConstants.REGISTRY_USER, RegistryConstants.REGISTRY_MOUNT, RegistryConstants.REGISTRY_AUTHOR, RegistryConstants.REGISTRY_MOUNT_POINT, RegistryConstants.REGISTRY_TARGET_POINT, RegistryConstants.REGISTRY_ACTUAL_PATH, RegistryConstants.REGISTRY_REAL_PATH); for (Map.Entry<Object, Object> e : properties.entrySet()) { String key = (String) e.getKey(); if (!linkProperties.contains(key)) { newResource.setProperty(key, (List<String>) e.getValue()); } } } } newResource.setMediaType("application/policy+xml"); if (policyResource.getProperty(CommonConstants.SOURCE_PROPERTY) == null){ newResource.setProperty(CommonConstants.SOURCE_PROPERTY, CommonConstants.SOURCE_AUTO); }else { newResource.setProperty(CommonConstants.SOURCE_PROPERTY, policyResource.getProperty(CommonConstants.SOURCE_PROPERTY)); } String policyId = policyResource.getUUID(); if (policyId == null) { // generate a service id policyId = UUID.randomUUID().toString(); } newResource.setUUID(policyId); newResource.setContent(outputStream.toByteArray()); addPolicyToRegistry(requestContext, policyPath, requestContext.getSourceURL(), newResource, registry); ((ResourceImpl)newResource).setPath(relativeArtifactPath); String symlinkLocation = RegistryUtils.getAbsolutePath(registryContext, newResource.getProperty(RegistryConstants.SYMLINK_PROPERTY_NAME)); if (symlinkLocation != null) { Resource resource = requestContext.getRegistry().get(symlinkLocation); if (resource != null) { String isLink = resource.getProperty("registry.link"); String mountPoint = resource.getProperty("registry.mountpoint"); String targetPoint = resource.getProperty("registry.targetpoint"); String actualPath = resource.getProperty("registry.actualpath"); if (isLink != null && mountPoint != null && targetPoint != null) { symlinkLocation = actualPath + RegistryConstants.PATH_SEPARATOR; } } requestContext.getSystemRegistry().createLink(symlinkLocation + policyFileName, policyPath); } requestContext.setResource(newResource); requestContext.setProcessingComplete(true); } private String getPolicyLocation(RequestContext requestContext, String policyFileName, String commonLocation, String resourcePath,String version ) { if (Utils.getRxtService() != null && Utils.getRxtService().getStoragePath(RegistryConstants.POLICY_MEDIA_TYPE) != null) { String pathExpression = Utils.getRxtService().getStoragePath(RegistryConstants.POLICY_MEDIA_TYPE); pathExpression = CommonUtil.getPathFromPathExpression(pathExpression, requestContext.getResource().getProperties(), null); pathExpression = RegistryUtils.getAbsolutePath(requestContext.getRegistryContext(), CommonUtil.replaceExpressionOfPath(pathExpression, "name", extractResourceFromURL(policyFileName, ".xml"))); String policyPath = pathExpression; /** * Fix for the REGISTRY-3052 : validation is to check the whether this invoked by ZIPWSDLMediaTypeHandler * Setting the registry and absolute paths to current session to avoid incorrect resource path entry in REG_LOG table */ if (CurrentSession.getLocalPathMap() != null && !Boolean.valueOf(CurrentSession.getLocalPathMap().get(CommonConstants.ARCHIEVE_UPLOAD))) { policyPath = CommonUtil.getRegistryPath(requestContext.getRegistry().getRegistryContext(), pathExpression); if (log.isDebugEnabled()) { log.debug("Saving current session local paths, key: " + policyPath + " | value: " + pathExpression); } CurrentSession.getLocalPathMap().put(policyPath, pathExpression); } return policyPath; } else { String policyPath; if (!resourcePath.startsWith(commonLocation) && !resourcePath.equals(RegistryUtils.getAbsolutePath( requestContext.getRegistryContext(), RegistryConstants.PATH_SEPARATOR + policyFileName)) && !resourcePath.equals(RegistryUtils.getAbsolutePath(requestContext.getRegistryContext(), RegistryConstants.GOVERNANCE_REGISTRY_BASE_PATH + RegistryConstants.PATH_SEPARATOR + policyFileName))) { policyPath = resourcePath; }else{ policyPath = commonLocation + version + "/" + extractResourceFromURL(policyFileName, ".xml"); } return policyPath; } } /** * Method that gets called instructing a policy to be added the registry. * * @param context the request context for this request. * @param path the path to add the resource to. * @param url the path from which the resource was imported from. * @param resource the resource to be added. * @param registry the registry instance to use. * * @throws RegistryException if the operation failed. */ protected void addPolicyToRegistry(RequestContext context, String path, String url, Resource resource, Registry registry) throws RegistryException { context.setActualPath(path); registry.put(path, resource); } private String extractResourceFromURL(String policyURL, String suffix) { String resourceName = policyURL; if (policyURL.lastIndexOf("?") > 0) { resourceName = policyURL.substring(0, policyURL.indexOf("?")) + suffix; } else if (policyURL.indexOf(".") > 0) { resourceName = policyURL.substring(0, policyURL.lastIndexOf(".")) + suffix; } else if (!policyURL.endsWith(suffix)) { resourceName = policyURL + suffix; } return resourceName; } private String getChrootedLocation(RegistryContext registryContext) { return RegistryUtils.getAbsolutePath(registryContext, RegistryConstants.GOVERNANCE_REGISTRY_BASE_PATH + location); } private boolean isIdentityPolicyPath(RequestContext requestContext) { if (requestContext.getResourcePath() != null && requestContext.getResourcePath().getCompletePath().contains(identityPolicyPath)) { return true; } return false; } }