/* * 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; } }