UnboundID Server SDK

Ping Identity
UnboundID Server SDK Documentation

ExamplePolicyAdvice.java

/*
 * 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 2017-2019 Ping Identity Corporation
 */


package com.unboundid.directory.sdk.examples;

import com.unboundid.directory.sdk.broker.api.PolicyAdvice;
import com.unboundid.directory.sdk.broker.config.PolicyAdviceConfig;
import com.unboundid.directory.sdk.broker.types.AdviceContext;
import com.unboundid.directory.sdk.broker.types.BrokerContext;
import com.unboundid.scim2.common.exceptions.ScimException;
import com.unboundid.scim2.common.messages.ErrorResponse;
import com.unboundid.util.args.Argument;
import com.unboundid.util.args.ArgumentException;
import com.unboundid.util.args.ArgumentParser;
import com.unboundid.util.args.StringArgument;

import java.util.List;

/**
 * Example of third-party Policy Advice.  This example may be used on
 * any SCIM request.  When a request is denied by policy, this advice
 * populates the 'scimType' portion of the SCIM error response with a value
 * configured directly in the extension, while the detail message is
 * evaluated during policy evaluation.
 */
public class ExamplePolicyAdvice extends PolicyAdvice {

  /**
   * The name of the extension argument that will be used to specify the
   * 'scimType' portion of a SCIM error response.
   */
  private static final String EXT_ARG_SCIM_TYPE = "extScimType";

  /**
   * The name of the advice argument that will be used to specify the
   * 'detail' portion of a SCIM error response.
   */
  private static final String ADVICE_ARG_DETAIL = "detail";


  /**
   * Handle to the ServerContext object.
   */
  private BrokerContext serverContext;

  /**
   * The value to use for scimType.
   */
  private String scimType;


  /**
   * Creates a new instance of this policy advice.  All policy
   * advice implementations must include a default constructor,
   * but any initialization should generally be performed in the
   * {@code initializePolicyAdvice} method.
   */
  public ExamplePolicyAdvice()
  {
  }


  /**
   * Initialize this Policy Advice.
   * @param  serverContext  A handle to the server context for the server in
   *                        which this extension is running.
   * @param  adviceCfg      The general configuration for this policy advice.
   * @param  parser         The argument parser which has been initialized from
   *                        the configuration for this policy advice.
   * @throws Exception      if an error occurs during initialization.
   */
  @Override
  public void initializePolicyAdvice(
      final BrokerContext serverContext,
      final PolicyAdviceConfig adviceCfg,
      final ArgumentParser parser) throws Exception
  {
    super.initializePolicyAdvice(serverContext, adviceCfg, parser);

    this.serverContext = serverContext;
    this.scimType = parser.getStringArgument(EXT_ARG_SCIM_TYPE).getValue();
  }


  /**
   * Retrieves a human-readable name for this extension.
   * @return extension name
   */
  @Override
  public String getExtensionName() {
    return "Example Policy Advice";
  }


  /**
   * Retrieves a human-readable description of this extension.
   * @return text description string
   */
  @Override
  public String[] getExtensionDescription() {
    return new String[]
    {
        "This Policy Advice implementation serves as an example that may" +
            " be used to demonstrate the process for creating a third-party" +
            " Policy Advice.  It demonstrates how to use a combination of" +
            " extension arguments and advice arguments to populate a SCIM" +
            " error response."
    };
  }

  /**
   * Updates the provided argument parser to define any configuration arguments
   * which may be used by this policy advice. 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 {

    final Argument scimTypeArg = new StringArgument(null,
        EXT_ARG_SCIM_TYPE,
        true,
        1,
        null,
        "The value of the scimType portion of an error response",
        "not specified");

    parser.addArgument(scimTypeArg);
  }


    /**
     * This method is called when a SCIM request is denied by policy.
     * @param context     AdviceContext containing any arguments passed
     *                    from policy.
     * @param defaultError   the default error information that will be
     *                    returned if nothing is done by the advice
     *                    implementation.
     * @return the modified error info, as directed by policy.
     * @throws ScimException if an internal error occurs trying to generate
     *                    the advice.
     */
  @Override
  public ErrorResponse onScimDeny(
      final AdviceContext context,
      final ErrorResponse defaultError) throws ScimException {

    ErrorResponse errorInfo = new ErrorResponse(defaultError.getStatus());
    errorInfo.setScimType(scimType);

    List<String> errorDescription = context.getArgumentValue(ADVICE_ARG_DETAIL);
    if (errorDescription.size() > 0) {
      errorInfo.setDetail(errorDescription.get(0));
    }
    return errorInfo;
  }

}