/* * Copyright (c) WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * * WSO2 Inc. licenses this file to you 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.identity.entitlement.policy.publisher; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.context.CarbonContext; import org.wso2.carbon.core.util.CryptoException; import org.wso2.carbon.core.util.CryptoUtil; import org.wso2.carbon.identity.entitlement.EntitlementException; import org.wso2.carbon.identity.entitlement.PAPStatusDataHandler; import org.wso2.carbon.identity.entitlement.PDPConstants; import org.wso2.carbon.identity.entitlement.common.EntitlementConstants; import org.wso2.carbon.identity.entitlement.dto.PublisherDataHolder; import org.wso2.carbon.identity.entitlement.dto.PublisherPropertyDTO; import org.wso2.carbon.identity.entitlement.internal.EntitlementServiceComponent; import org.wso2.carbon.registry.core.Collection; import org.wso2.carbon.registry.core.Registry; import org.wso2.carbon.registry.core.RegistryConstants; import org.wso2.carbon.registry.core.Resource; import org.wso2.carbon.registry.core.exceptions.RegistryException; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * This is policy publisher. There can be different modules that have been plugged with this. * This module currently is bound with the WSO2 registry, as some meta data is store there, */ public class PolicyPublisher { public static final String SUBSCRIBER_ID = "subscriberId"; public static final String SUBSCRIBER_DISPLAY_NAME = "Subscriber Id"; private static Log log = LogFactory.getLog(PolicyPublisher.class); private static ExecutorService threadPool = Executors.newFixedThreadPool(2); /** * set of publisher modules */ Set<PolicyPublisherModule> publisherModules = new HashSet<PolicyPublisherModule>(); /** * set of post publisher modules */ Set<PAPStatusDataHandler> papStatusDataHandlers = new HashSet<PAPStatusDataHandler>(); /** * Verification publisher modules */ PublisherVerificationModule verificationModule = null; private Registry registry; /** * Creates PolicyPublisher instance */ public PolicyPublisher() { this.registry = EntitlementServiceComponent. getGovernanceRegistry(CarbonContext.getThreadLocalCarbonContext().getTenantId()); Map<PolicyPublisherModule, Properties> publisherModules = EntitlementServiceComponent. getEntitlementConfig().getPolicyPublisherModules(); if (publisherModules != null && !publisherModules.isEmpty()) { this.publisherModules.addAll(publisherModules.keySet()); } Map<PublisherVerificationModule, Properties> prePublisherModules = EntitlementServiceComponent. getEntitlementConfig().getPublisherVerificationModule(); if (prePublisherModules != null && !prePublisherModules.isEmpty()) { this.verificationModule = prePublisherModules.keySet().iterator().next(); } // creating default subscriber to publish policies to PDP CarbonPDPPublisher publisher = new CarbonPDPPublisher(); this.publisherModules.add(publisher); PublisherDataHolder holder = new PublisherDataHolder(publisher.getModuleName()); PublisherPropertyDTO dto = new PublisherPropertyDTO(); dto.setId(SUBSCRIBER_ID); dto.setDisplayName(SUBSCRIBER_DISPLAY_NAME); dto.setValue(EntitlementConstants.PDP_SUBSCRIBER_ID); holder.setPropertyDTOs(new PublisherPropertyDTO[]{dto}); try { PublisherDataHolder pdpDataHolder = null; try { pdpDataHolder = retrieveSubscriber(EntitlementConstants.PDP_SUBSCRIBER_ID, false); } catch (Exception e) { // ignore } if (pdpDataHolder == null) { persistSubscriber(holder, false); } } catch (EntitlementException e) { // ignore } } /** * publish policy * * @param policyIds policy ids to publish, * @param version * @param action * @param enabled * @param order * @param subscriberIds subscriber ids to publish, * @param verificationCode verificationCode as String * @throws EntitlementException throws if can not be created PolicyPublishExecutor instant */ public void publishPolicy(String[] policyIds, String version, String action, boolean enabled, int order, String[] subscriberIds, String verificationCode) throws EntitlementException { boolean toPDP = false; if (subscriberIds == null) { toPDP = true; } PolicyPublishExecutor executor = new PolicyPublishExecutor(policyIds, version, action, enabled, order, subscriberIds, this, toPDP, verificationCode); executor.setTenantDomain(CarbonContext.getThreadLocalCarbonContext().getTenantDomain()); executor.setTenantId(CarbonContext.getThreadLocalCarbonContext().getTenantId()); executor.setUserName(CarbonContext.getThreadLocalCarbonContext().getUsername()); threadPool.execute(executor); } public void persistSubscriber(PublisherDataHolder holder, boolean update) throws EntitlementException { Collection policyCollection; String subscriberPath; String subscriberId = null; if (holder == null || holder.getPropertyDTOs() == null) { log.error("Publisher data can not be null"); throw new EntitlementException("Publisher data can not be null"); } for (PublisherPropertyDTO dto : holder.getPropertyDTOs()) { if (SUBSCRIBER_ID.equals(dto.getId())) { subscriberId = dto.getValue(); } } if (subscriberId == null) { log.error("Subscriber Id can not be null"); throw new EntitlementException("Subscriber Id can not be null"); } try { if (registry.resourceExists(PDPConstants.ENTITLEMENT_POLICY_PUBLISHER)) { policyCollection = registry.newCollection(); registry.put(PDPConstants.ENTITLEMENT_POLICY_PUBLISHER, policyCollection); } subscriberPath = PDPConstants.ENTITLEMENT_POLICY_PUBLISHER + RegistryConstants.PATH_SEPARATOR + subscriberId; Resource resource; PublisherDataHolder oldHolder = null; if (registry.resourceExists(subscriberPath)) { if (update) { resource = registry.get(subscriberPath); oldHolder = new PublisherDataHolder(resource, false); } else { throw new EntitlementException("Subscriber ID already exists"); } } else { resource = registry.newResource(); } populateProperties(holder, oldHolder, resource); registry.put(subscriberPath, resource); } catch (RegistryException e) { log.error("Error while persisting subscriber details", e); throw new EntitlementException("Error while persisting subscriber details", e); } } public void deleteSubscriber(String subscriberId) throws EntitlementException { String subscriberPath; if (subscriberId == null) { log.error("Subscriber Id can not be null"); throw new EntitlementException("Subscriber Id can not be null"); } if (EntitlementConstants.PDP_SUBSCRIBER_ID.equals(subscriberId.trim())) { log.error("Can not delete PDP publisher"); throw new EntitlementException("Can not delete PDP publisher"); } try { subscriberPath = PDPConstants.ENTITLEMENT_POLICY_PUBLISHER + RegistryConstants.PATH_SEPARATOR + subscriberId; if (registry.resourceExists(subscriberPath)) { registry.delete(subscriberPath); } } catch (RegistryException e) { log.error("Error while deleting subscriber details", e); throw new EntitlementException("Error while deleting subscriber details", e); } } public PublisherDataHolder retrieveSubscriber(String id, boolean returnSecrets) throws EntitlementException { try { if (registry.resourceExists(PDPConstants.ENTITLEMENT_POLICY_PUBLISHER + RegistryConstants.PATH_SEPARATOR + id)) { Resource resource = registry.get(PDPConstants.ENTITLEMENT_POLICY_PUBLISHER + RegistryConstants.PATH_SEPARATOR + id); return new PublisherDataHolder(resource, returnSecrets); } } catch (RegistryException e) { log.error("Error while retrieving subscriber detail of id : " + id, e); throw new EntitlementException("Error while retrieving subscriber detail of id : " + id, e); } throw new EntitlementException("No Subscriber is defined for given Id"); } public String[] retrieveSubscriberIds(String searchString) throws EntitlementException { try { if (registry.resourceExists(PDPConstants.ENTITLEMENT_POLICY_PUBLISHER + RegistryConstants.PATH_SEPARATOR)) { Resource resource = registry.get(PDPConstants.ENTITLEMENT_POLICY_PUBLISHER + RegistryConstants.PATH_SEPARATOR); Collection collection = (Collection) resource; List<String> list = new ArrayList<String>(); if (collection.getChildCount() > 0) { searchString = searchString.replace("*", ".*"); Pattern pattern = Pattern.compile(searchString, Pattern.CASE_INSENSITIVE); for (String path : collection.getChildren()) { String id = path.substring(path.lastIndexOf(RegistryConstants.PATH_SEPARATOR) + 1); Matcher matcher = pattern.matcher(id); if (!matcher.matches()) { continue; } Resource childResource = registry.get(path); if (childResource != null && childResource.getProperty(SUBSCRIBER_ID) != null) { list.add(childResource.getProperty(SUBSCRIBER_ID)); } } } return list.toArray(new String[list.size()]); } } catch (RegistryException e) { log.error("Error while retrieving subscriber of ids", e); throw new EntitlementException("Error while retrieving subscriber ids", e); } return null; } private void populateProperties(PublisherDataHolder holder, PublisherDataHolder oldHolder, Resource resource) { PublisherPropertyDTO[] propertyDTOs = holder.getPropertyDTOs(); for (PublisherPropertyDTO dto : propertyDTOs) { if (dto.getId() != null && dto.getValue() != null && dto.getValue().trim().length() > 0) { ArrayList<String> list = new ArrayList<String>(); if (dto.isSecret()) { PublisherPropertyDTO propertyDTO = null; if (oldHolder != null) { propertyDTO = oldHolder.getPropertyDTO(dto.getId()); } if (propertyDTO == null || !propertyDTO.getValue().equalsIgnoreCase(dto.getValue())) { try { String encryptedValue = CryptoUtil.getDefaultCryptoUtil(). encryptAndBase64Encode(dto.getValue().getBytes()); dto.setValue(encryptedValue); } catch (CryptoException e) { log.error("Error while encrypting secret value of subscriber. " + "Secret would not be persist.", e); continue; } } } list.add(dto.getValue()); list.add(dto.getDisplayName()); list.add(Integer.toString(dto.getDisplayOrder())); list.add(Boolean.toString(dto.isRequired())); list.add(Boolean.toString(dto.isSecret())); resource.setProperty(dto.getId(), list); } } resource.setProperty(PublisherDataHolder.MODULE_NAME, holder.getModuleName()); } public Set<PolicyPublisherModule> getPublisherModules() { return publisherModules; } public Set<PAPStatusDataHandler> getPapStatusDataHandlers() { return papStatusDataHandlers; } public void setPapStatusDataHandlers(Set<PAPStatusDataHandler> papStatusDataHandlers) { this.papStatusDataHandlers = papStatusDataHandlers; } public PublisherVerificationModule getVerificationModule() { return verificationModule; } }