/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at
* docs/licenses/cddl.txt
* or http://www.opensource.org/licenses/cddl1.php.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at
* docs/licenses/cddl.txt. If applicable,
* add the following below this CDDL HEADER, with the fields enclosed
* by brackets "[]" replaced with your own identifying information:
* Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
*
* Copyright 2013-2015 UnboundID Corp.
*/
package com.unboundid.directory.sdk.examples;
import com.unboundid.directory.sdk.broker.api.PolicyInformationProvider;
import com.unboundid.directory.sdk.broker.config.
PolicyInformationProviderConfig;
import com.unboundid.directory.sdk.broker.types.IdentityBrokerContext;
import com.unboundid.directory.sdk.broker.types.RequestAttribute;
import com.unboundid.directory.sdk.broker.types.RequestContext;
import com.unboundid.util.args.ArgumentException;
import com.unboundid.util.args.ArgumentParser;
import com.unboundid.util.args.FileArgument;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
/**
* Example of a third-party Policy Information Provider. This example
* implementation retrieves attributes from a Java properties file.
*/
public class ExamplePolicyInformationProvider
extends PolicyInformationProvider
{
/**
* The name of the argument that will be used to specify the path to the
* properties file in which to find attribute values.
*/
private static final String ARG_NAME_PATH = "properties-file-path";
private Properties properties;
/**
* Character used to delimit subject id from attribute id in the
* name portion of each java property line.
*/
public static final Character PROPERTY_NAME_DELIMITER = '$';
/**
* Creates a new instance of this policy information provider. All policy
* information provider implementations must include a default constructor,
* but any initialization should generally be performed in the
* {@code initializePolicyInformationProvider} method.
*/
public ExamplePolicyInformationProvider()
{
}
/**
* Retrieves a human-readable name for this extension.
* @return extension name
*/
@Override
public String getExtensionName()
{
return "Example Policy Information Provider";
}
/**
* Retrieves a human-readable description of this extension.
* @return text description string
*/
@Override
public String[] getExtensionDescription()
{
return new String[]
{
"This Policy Information Provider serves as an example that may" +
" be used to demonstrate the process for creating a third-party" +
" policy information provider. This example provider reads values" +
" from a Java properties file. The full path to the properties" +
" file is specified using the extension attribute with name " +
ARG_NAME_PATH + ". The Policy Information Provider" +
" must be configured with one or more XACML attribute Ids or " +
" wild cards that will funnel attribute requests to this provider."
};
}
/**
* Updates the provided argument parser to define any configuration arguments
* which may be used by this policy information provider. The argument parser
* may also be updated to define relationships between arguments (e.g., to
* specify required, exclusive, or dependent argument sets).
*
* @param parser The argument parser to be updated with the configuration
* arguments which may be used by this provider.
*
* @throws ArgumentException If a problem is encountered while updating the
* provided argument parser.
*/
@Override
public void defineConfigArguments(final ArgumentParser parser)
throws ArgumentException
{
// add argument used to specify the path to a properties file
Character shortIdentifier = null;
String longIdentifier = ARG_NAME_PATH;
boolean required = true;
int maxOccurrences = 1;
String placeholder = "{path}";
String description = "The full path to a java properties file" +
" containing name-value pairs. Each name-value pair must be in the" +
" following format: <subjectName>" + PROPERTY_NAME_DELIMITER +
"<xacmlAttributeId>=value where subjectName = subject property from" +
" the request context and xacmlAttributeId = the XACML attribute Id" +
" being requested. (Example: 'applicationX$urn:myorganization" +
PROPERTY_NAME_DELIMITER + "myattribute=myvalue'.)";
boolean fileMustExist = true;
boolean parentMustExist = true;
boolean mustBeFile = true;
boolean mustBeDirectory = false;
parser.addArgument(new FileArgument(shortIdentifier, longIdentifier,
required, maxOccurrences, placeholder, description, fileMustExist,
parentMustExist, mustBeFile, mustBeDirectory));
}
/**
* Initialize this Policy Information Provider. Loads the java properties
* file specified in its configuration.
* @param serverContext A handle to the server context for the server in
* which this extension is running.
* @param config The general configuration for this policy
* information provider.
* @param parser The argument parser which has been initialized from
* the configuration for this policy information
* provider.
*
* @throws IOException if an error occurs reading the properties file
*/
@Override
public void initializePolicyInformationProvider(
final IdentityBrokerContext serverContext,
final PolicyInformationProviderConfig config,
final ArgumentParser parser) throws IOException
{
FileArgument propFilePath =
(FileArgument)parser.getNamedArgument(ARG_NAME_PATH);
properties = new Properties();
FileInputStream stream = new FileInputStream(propFilePath.getValue());
properties.load(stream);
}
/**
* Retrieve an attribute value from the data store, which in the case of
* this example is a java properties file.
* @param categoryId XACML category identifier
* @param attributeId XACML attribute identifier
* @param context request context, can be used to retrieve other
* attributes from the request that may be needed
* in order to evaluate the requested attribute
* @return RequestAttribute object
* @throws Exception if an error occurs retrieving the attribute
*/
@Override
public RequestAttribute getAttribute(
final String categoryId,
final String attributeId,
final RequestContext context) throws Exception
{
// construct key using both subject and attribute Id
StringBuilder key = new StringBuilder(context.getSubject());
key.append(PROPERTY_NAME_DELIMITER);
key.append(attributeId);
String value = properties.getProperty(key.toString());
if (value == null)
{
throw new Exception(String.format(
"attribute %s not found for subject %s",
attributeId, context.getSubject()));
}
return new RequestAttribute("http://www.w3.org/2001/XMLSchema#string",
Arrays.asList(value));
}
/**
* Retrieves a map containing examples of configurations that may be used for
* this extension. The map key should be a list of sample arguments, and the
* corresponding value should be a description of the behavior that will be
* exhibited by the extension when used with that configuration.
*
* @return A map containing examples of configurations that may be used for
* this extension. It may be {@code null} or empty if there should
* not be any example argument sets.
*/
@Override()
public Map<List<String>,String> getExamplesArgumentSets()
{
final LinkedHashMap<List<String>,String> exampleMap =
new LinkedHashMap<List<String>,String>(1);
exampleMap.put(
Arrays.asList(ARG_NAME_PATH + "=/var/xacmlAttributes.properties"),
"Retrieve attribute values from the java properties file at path" +
"/var/xacmlAttributes.properties.");
return exampleMap;
}
}
|