001    /*
002     * CDDL HEADER START
003     *
004     * The contents of this file are subject to the terms of the
005     * Common Development and Distribution License, Version 1.0 only
006     * (the "License").  You may not use this file except in compliance
007     * with the License.
008     *
009     * You can obtain a copy of the license at
010     * docs/licenses/cddl.txt
011     * or http://www.opensource.org/licenses/cddl1.php.
012     * See the License for the specific language governing permissions
013     * and limitations under the License.
014     *
015     * When distributing Covered Code, include this CDDL HEADER in each
016     * file and include the License file at
017     * docs/licenses/cddl.txt.  If applicable,
018     * add the following below this CDDL HEADER, with the fields enclosed
019     * by brackets "[]" replaced with your own identifying information:
020     *      Portions Copyright [yyyy] [name of copyright owner]
021     *
022     * CDDL HEADER END
023     *
024     *
025     *      Copyright 2013 UnboundID Corp.
026     */
027    
028    package com.unboundid.directory.sdk.broker.api;
029    
030    import com.unboundid.directory.sdk.broker.internal.IdentityBrokerExtension;
031    import com.unboundid.directory.sdk.broker.types.IdentityBrokerContext;
032    import com.unboundid.directory.sdk.common.internal.ExampleUsageProvider;
033    import com.unboundid.directory.sdk.common.internal.Reconfigurable;
034    import com.unboundid.directory.sdk.common.internal.UnboundIDExtension;
035    import com.unboundid.directory.sdk.broker.config.
036        PolicyInformationProviderConfig;
037    import com.unboundid.directory.sdk.broker.types.RequestAttribute;
038    import com.unboundid.directory.sdk.broker.types.RequestContext;
039    import com.unboundid.ldap.sdk.ResultCode;
040    import com.unboundid.util.Extensible;
041    import com.unboundid.util.ThreadSafety;
042    import com.unboundid.util.ThreadSafetyLevel;
043    import com.unboundid.util.args.ArgumentException;
044    import com.unboundid.util.args.ArgumentParser;
045    
046    import java.util.Collections;
047    import java.util.List;
048    import java.util.Map;
049    
050    
051    /**
052     * This class defines an API that must be implemented by Identity Broker
053     * extensions that retrieve XACML attributes as part of the Policy Information
054     * Point (PIP).
055     *
056     * <H2>Configuring Policy Information Providers</H2>
057     * In order to configure a policy information provider created using this API,
058     * use a command like:
059     *
060     * <PRE>
061     *      dsconfig create-policy-information-provider \
062     *           --provider-name "<I>{name}</I>" \
063     *           --type third-party \
064     *           --set enabled:true \
065     *           --set "extension-class:<I>{class-name}</I>" \
066     *           --set "extension-argument:<I>{name=value}</I>" \
067     *           --set "xacml-attribute-id:<I>{attributeId}</I> \
068     *           --set "evaluation-order-index:<I>{index}</I>
069     * </PRE>
070     * where "<I>{name}</I>" is the name to use for the policy information provider
071     * instance, "<I>{class-name}</I>" is the fully-qualified name of the Java
072     * class that extends
073     * {@code com.unboundid.directory.sdk.broker.api.PolicyInformationProvider},
074     * "<I>{index}</I>" is an integer from 1 to 9999 that is used to determine the
075     * position of this Policy Information Provider in the order of evaluation
076     * among all Policy Information Providers, "<I>{attributeId}</I>" identifies
077     * the XACML attribute(s) that this provider knows how to retrieve, and
078     * "<I>{name=value}</I>" represents name-value pairs for any additional
079     * arguments to provide to the Policy Information Provider. If multiple
080     * arguments should be provided to extension, then the
081     * "<CODE>--set extension-argument:<I>{name=value}</I></CODE>" option should be
082     * provided multiple times.  If the Policy Information Provider can retrieve
083     * more than one attribute type, then the
084     * "<CODE>--set xacml-attribute-id:<I>{attributeId}</I></CODE>" option can also
085     * be provided multiple times.
086     */
087    @Extensible()
088    @IdentityBrokerExtension()
089    @ThreadSafety(level= ThreadSafetyLevel.INTERFACE_THREADSAFE)
090    public abstract class PolicyInformationProvider
091        implements UnboundIDExtension,
092           Reconfigurable<PolicyInformationProviderConfig>,
093           ExampleUsageProvider
094    {
095    
096      /**
097       * {@inheritDoc}
098       */
099      public abstract String getExtensionName();
100    
101      /**
102       * {@inheritDoc}
103       */
104      public abstract String[] getExtensionDescription();
105    
106    
107      /**
108       * {@inheritDoc}
109       */
110      public void defineConfigArguments(final ArgumentParser parser)
111          throws ArgumentException
112      {
113        // No arguments will be allowed by default.
114      }
115    
116    
117      /**
118       * Initializes this policy information provider.
119       *
120       * @param  serverContext  A handle to the server context for the server in
121       *                        which this extension is running.
122       * @param  config         The general configuration for this policy
123       *                        information provider.
124       * @param  parser         The argument parser which has been initialized from
125       *                        the configuration for this policy information
126       *                        provider.
127       *
128       * @throws Exception      If a problem occurs while initializing this
129       *                        policy information provider.
130       */
131      public void initializePolicyInformationProvider(
132          final IdentityBrokerContext serverContext,
133          final PolicyInformationProviderConfig config,
134          final ArgumentParser parser)
135          throws Exception
136      {
137        // No initialization will be performed by default.
138      }
139    
140    
141      /**
142       * {@inheritDoc}
143       */
144      public boolean isConfigurationAcceptable(
145          final PolicyInformationProviderConfig config,
146          final ArgumentParser parser,
147          final List<String> unacceptableReasons)
148      {
149    
150        // No extended validation will be performed by default.
151        return true;
152      }
153    
154    
155      /**
156       * {@inheritDoc}
157       */
158      public ResultCode applyConfiguration(
159          final PolicyInformationProviderConfig config,
160          final ArgumentParser parser,
161          final List<String> adminActionsRequired,
162          final List<String> messages)
163      {
164        // By default, no configuration changes will be applied.  If there are any
165        // arguments, then add an admin action message indicating that the
166        // extension needs to be restarted for any changes to take effect.
167        if (! parser.getNamedArguments().isEmpty())
168        {
169          adminActionsRequired.add(
170              "No configuration change has actually been applied.  The new " +
171                  "configuration will not take effect until this policy " +
172                  "information provider is disabled and re-enabled or until " +
173                  "the server is restarted.");
174        }
175        return ResultCode.SUCCESS;
176    
177      }
178    
179    
180      /**
181       * Performs any cleanup which may be necessary when this policy information
182       * provider is to be taken out of service.
183       */
184      public void finalizePolicyInformationProvider()
185      {
186        // no implementation is required
187      }
188    
189    
190      /**
191       * Retrieve an attribute that has been requested by the policy engine.
192       * @param categoryId XACML category identifier.  This is the category Id
193       *                   specified by the AttributeDesignator element in the
194       *                   policy that is requesting this attribute.
195       * @param attributeId XACML attribute identifier.  This will be one of the
196       *                   identifiers specified by the xacml-attribute-id
197       *                   property of the configuration for this Policy
198       *                   Information Provider.
199       * @param context request context, can be used to retrieve other
200       *                attributes from the request that may be needed
201       *                in order to evaluate the requested attribute
202       * @return RequestAttribute object containing the requested attribute,
203       *                never null.
204       * @throws Exception if an error occurs retrieving the attribute
205       */
206      public abstract RequestAttribute getAttribute(
207          final String categoryId,
208          final String attributeId,
209          RequestContext context) throws Exception;
210    
211    
212      /**
213       * {@inheritDoc}
214       */
215      public Map<List<String>,String> getExamplesArgumentSets()
216      {
217        return Collections.emptyMap();
218      }
219    }
220