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 2017-2018 Ping Identity Corporation 026 */ 027 028 029package com.unboundid.directory.sdk.broker.api; 030 031import com.unboundid.directory.sdk.broker.config.PolicyAdviceConfig; 032import com.unboundid.directory.sdk.broker.internal.BrokerExtension; 033import com.unboundid.directory.sdk.broker.types.AdviceContext; 034import com.unboundid.directory.sdk.broker.types.BrokerContext; 035import com.unboundid.directory.sdk.common.internal.ExampleUsageProvider; 036import com.unboundid.directory.sdk.common.internal.UnboundIDExtension; 037import com.unboundid.scim2.common.exceptions.ScimException; 038import com.unboundid.scim2.common.messages.ErrorResponse; 039import com.unboundid.util.Extensible; 040import com.unboundid.util.ThreadSafety; 041import com.unboundid.util.ThreadSafetyLevel; 042import com.unboundid.util.args.ArgumentException; 043import com.unboundid.util.args.ArgumentParser; 044 045import java.util.Collections; 046import java.util.List; 047import java.util.Map; 048 049 050/** 051 * This class defines an API that must be implemented by extensions that 052 * implement custom Policy Advice. This advice is invoked when policy 053 * evaluation results in this type of advice being returned to the Policy 054 * Enforcement Point. 055 * 056 * <H2>Configuring Policy Advice</H2> 057 * In order to configure policy advice created using this API, 058 * use a command like: 059 * 060 * <PRE> 061 * dsconfig create-policy-advice \ 062 * --advice-name "<I>{name}</I>" \ 063 * --type third-party \ 064 * --policy-name "<I>{policy-name}</I>" \ 065 * --rule-name "<I>{rule-name}</I>" \ 066 * --set "extension-class:<I>{class-name}</I>" \ 067 * --set "extension-argument:<I>{name=value}</I>" \ 068 * --set "advice-arguments:<I>{name=jexlExpression}</I>" \ 069 * --set "evaluation-order-index:<I>{index}</I> 070 * </PRE> 071 * where "<I>{name}</I>" is the name to use for the policy advice 072 * instance, "<I>{class-name}</I>" is the fully-qualified name of the Java 073 * class that extends 074 * {@code com.unboundid.directory.sdk.broker.api.PolicyAdvice}, 075 * "<I>{policy-name}</I>" and <I>{rule-name}</I>" identify the policy and 076 * policy rule, respectively, that will contain this advice expression. 077 * <I>{name=jexlExpression}</I> pairs specified using advice-arguments identify 078 * arguments whose value may be specified or computed during policy evaluation 079 * before being passed into this advice implementation. 080 * "<I>{index}</I>" is an integer from 1 to 9999 that is used to determine the 081 * order in which this type of advice should be invoked relative to other advice 082 * that may be returned from the same policy evaluation. 083 * "<I>{name=value}</I>" pairs specified using extension-arguments are values 084 * that are provided to the advice implementation at initialization time. 085 * If multiple advice arguments should be provided at each invocation, then the 086 * "<CODE>--set advice-argument:<I>{name=jexlExpression}</I></CODE>" option 087 * should be provided multiple times. 088 * If multiple initialization arguments should be provided to the extension, 089 * then the "<CODE>--set extension-argument:<I>{name=value}</I></CODE>" option 090 * should be provided multiple times. 091 */ 092@Extensible() 093@BrokerExtension 094@ThreadSafety(level= ThreadSafetyLevel.INTERFACE_THREADSAFE) 095public abstract class PolicyAdvice 096 implements UnboundIDExtension, 097 ExampleUsageProvider { 098 099 /** 100 * No-args constructor. 101 */ 102 public PolicyAdvice() { 103 // no implementation required. 104 } 105 106 107 /** 108 * {@inheritDoc} 109 */ 110 @Override 111 public abstract String getExtensionName(); 112 113 114 /** 115 * {@inheritDoc} 116 */ 117 @Override 118 public abstract String[] getExtensionDescription(); 119 120 121 /** 122 * {@inheritDoc} 123 */ 124 @Override 125 public Map<List<String>,String> getExamplesArgumentSets() { 126 return Collections.emptyMap(); 127 } 128 129 130 /** 131 * {@inheritDoc} 132 */ 133 @Override 134 public void defineConfigArguments(final ArgumentParser parser) 135 throws ArgumentException { 136 // No arguments will be allowed by default. 137 } 138 139 140 /** 141 * Initializes this Policy Advice implementation. 142 * @param serverContext A handle to the server context for the server in 143 * which this extension is running. 144 * @param adviceCfg The general configuration for this policy advice. 145 * @param parser The argument parser which has been initialized from 146 * the configuration for this policy advice. 147 * 148 * @throws Exception If a problem occurs while initializing this 149 * policy advice. 150 */ 151 public void initializePolicyAdvice( 152 final BrokerContext serverContext, 153 final PolicyAdviceConfig adviceCfg, 154 final ArgumentParser parser) throws Exception { 155 // No initialization will be performed by default. 156 } 157 158 159 /** 160 * Performs any cleanup which may be necessary when this policy advice 161 * is to be taken out of service. 162 */ 163 public void finalizePolicyAdvice() { 164 // no implementation is required 165 } 166 167 168 /** 169 * This method is called if this advice is returned by policy when a SCIM 170 * request is denied. 171 * @param context AdviceContext containing any arguments passed 172 * from policy. 173 * @param errorInfo the default error information that will be 174 * returned if nothing is done by the advice 175 * implementation. 176 * @return the modified error info 177 * @throws ScimException if an internal error occurs trying to generate 178 * the advice. 179 */ 180 public ErrorResponse onScimDeny( 181 final AdviceContext context, 182 final ErrorResponse errorInfo) throws ScimException { 183 184 // default implementation: no-op. 185 return errorInfo; 186 } 187}