/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright (c) 2012-2015 ForgeRock AS. All Rights Reserved * * The contents of this file are subject to the terms * of the Common Development and Distribution License * (the License). You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://forgerock.org/license/CDDLv1.0.html * See the License for the specific language governing * permission and limitations under the License. * * When distributing Covered Code, include this CDDL * Header Notice in each file and include the License file * at http://forgerock.org/license/CDDLv1.0.html * If applicable, add the following below the CDDL Header, * with the fields enclosed by brackets [] replaced by * your own identifying information: * "Portions Copyrighted [year] [name of copyright owner]" */ package org.forgerock.openidm.policy; import java.util.ArrayList; import java.util.Dictionary; import java.util.EnumSet; import java.util.List; import java.util.Map; import javax.script.Bindings; import org.apache.felix.scr.annotations.Activate; import org.apache.felix.scr.annotations.Component; import org.apache.felix.scr.annotations.ConfigurationPolicy; import org.apache.felix.scr.annotations.Deactivate; import org.apache.felix.scr.annotations.Modified; import org.apache.felix.scr.annotations.Properties; import org.apache.felix.scr.annotations.Property; import org.apache.felix.scr.annotations.Reference; import org.apache.felix.scr.annotations.ReferencePolicy; import org.forgerock.services.context.Context; import org.forgerock.json.JsonValue; import org.forgerock.json.resource.ActionRequest; import org.forgerock.json.resource.ReadRequest; import org.forgerock.json.resource.RequestType; import org.forgerock.json.resource.ResourceException; import org.forgerock.openidm.config.enhanced.EnhancedConfig; import org.forgerock.openidm.core.IdentityServer; import org.forgerock.openidm.core.ServerConstants; import org.forgerock.openidm.script.AbstractScriptedService; import org.forgerock.openidm.util.FileUtil; import org.osgi.framework.BundleContext; import org.osgi.framework.Constants; import org.osgi.service.component.ComponentContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * A Policy Service for policy validation. * */ @Component(name = PolicyService.PID, policy = ConfigurationPolicy.REQUIRE, metatype = true, description = "OpenIDM Policy Service", immediate = true) @Properties({ @Property(name = Constants.SERVICE_VENDOR, value = ServerConstants.SERVER_VENDOR_NAME), @Property(name = Constants.SERVICE_DESCRIPTION, value = "OpenIDM Policy Service"), @Property(name = ServerConstants.ROUTER_PREFIX, value = "/policy*") }) public class PolicyService extends AbstractScriptedService { public static final String PID = "org.forgerock.openidm.policy"; /** * Setup logging for the {@link PolicyService}. */ private static final Logger logger = LoggerFactory.getLogger(PolicyService.class); /** Enhanced configuration service. */ @Reference(policy = ReferencePolicy.DYNAMIC) private EnhancedConfig enhancedConfig; private ComponentContext context; private JsonValue configuration; public PolicyService() { super(EnumSet.of(RequestType.ACTION, RequestType.READ)); } public PolicyService(JsonValue configuration) { super(EnumSet.of(RequestType.ACTION, RequestType.READ)); init(configuration); } @Activate protected void activate(ComponentContext context) { this.context = context; Dictionary properties = context.getProperties(); setProperties(properties); configuration = getConfiguration(context); activate(context.getBundleContext(), null, configuration); logger.info("OpenIDM Policy Service component is activated."); } /** * Configuration modified handling Ensures the service stays registered even * whilst configuration changes */ @Modified void modified(ComponentContext context) throws Exception { configuration = getConfiguration(context); modified(null, configuration); logger.info("OpenIDM Policy Service component is modified."); } @Deactivate protected void deactivate(ComponentContext context) { deactivate(); this.context = null; logger.info("OpenIDM Policy Service component is deactivated."); } @Override protected Object getRouterPrefixes(String factoryPid, JsonValue configuration) { return null; } protected BundleContext getBundleContext() { return context.getBundleContext(); } private JsonValue getConfiguration(ComponentContext context) { JsonValue configuration = enhancedConfig.getConfigurationAsJson(context); init(configuration); return configuration; } private void init(JsonValue configuration) { JsonValue additionalPolicies = configuration.get("additionalFiles"); if (!additionalPolicies.isNull()) { configuration.remove("additionalFiles"); List<String> list = new ArrayList<String>(); for (JsonValue policy : additionalPolicies) { try { list.add(FileUtil.readFile(IdentityServer.getFileForProjectPath(policy.asString()))); } catch (Exception e) { logger.error("Error loading additional policy script " + policy.asString(), e); } } configuration.add("additionalPolicies", list); } } @Override public void handleAction(final Context context, final ActionRequest request, final Bindings handler) throws ResourceException { super.handleAction(context, request, handler); for (Map.Entry<String, String> entry : request.getAdditionalParameters().entrySet()) { if (handler.containsKey(entry.getKey())) { continue; } if (bindings != null) { bindings.put(entry.getKey(), entry.getValue()); } } handler.put("request", request); handler.put("resources", configuration.get("resources").copy().getObject()); } @Override public void handleRead(final Context context, final ReadRequest request, final Bindings handler) throws ResourceException { super.handleRead(context, request, handler); handler.put("request", request); handler.put("resources", configuration.get("resources").copy().getObject()); } }