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 * Portions Copyright 2010-2024 Ping Identity Corporation 026 */ 027package com.unboundid.directory.sdk.broker.api; 028 029import com.unboundid.directory.sdk.broker.internal.BrokerExtension; 030import com.unboundid.directory.sdk.broker.config.PolicyDecisionLoggerConfig; 031import com.unboundid.directory.sdk.common.internal.ExampleUsageProvider; 032import com.unboundid.directory.sdk.common.internal.Reconfigurable; 033import com.unboundid.directory.sdk.common.internal.UnboundIDExtension; 034import com.unboundid.directory.sdk.broker.types.PolicyMessageType; 035import com.unboundid.directory.sdk.common.types.ServerContext; 036import com.unboundid.ldap.sdk.LDAPException; 037import com.unboundid.ldap.sdk.ResultCode; 038import com.unboundid.util.Extensible; 039import com.unboundid.util.ThreadSafety; 040import com.unboundid.util.ThreadSafetyLevel; 041import com.unboundid.util.args.ArgumentException; 042import com.unboundid.util.args.ArgumentParser; 043 044import java.util.Collections; 045import java.util.List; 046import java.util.Map; 047 048/** 049 * This class defines an API that must be implemented by extensions which 050 * record information about PingAuthorize policy enforcement point 051 * (PEP) and policy decision point (PDP) activity 052 * <BR><BR> 053 * Each policy decision logger may be configured to indicate whether to 054 * include the PDP response or exclude log messages based on their Policy 055 * Message Type. This is handled automatically by the server, so individual 056 * policy decision logger implementations do not need to attempt to perform that 057 * filtering on their own. However, they may perform additional processing 058 * if desired to further narrow the set of messages that should be logged. 059 * <BR> 060 * <H2>Configuring Policy Decision Loggers</H2> 061 * To configure a policy decision created using this API, use a command 062 * like: 063 * <PRE> 064 * dsconfig create-log-publisher \ 065 * --publisher-name "<I>{logger-name}</I>" \ 066 * --type third-party-policy-decision \ 067 * --set enabled:true \ 068 * --set "extension-class:<I>{class-name}</I>" \ 069 * --set "extension-argument:<I>{name=value}</I>" 070 * </PRE> 071 * where "<I>{logger-name}</I>" is the name 072 * to use for the policy decision logger 073 * instance, "<I>{class-name}</I>" is the fully-qualified name of the Java class 074 * that extends {@code com.unboundid.directory.sdk.common.api 075 * .PolicyDecisionLogger}, 076 * and "<I>{name=value}</I>" represents name-value pairs for any arguments to 077 * provide to the logger. If multiple arguments should be provided to the 078 * logger, then the "<CODE>--set extension-argument:<I>{name=value}</I></CODE>" 079 * option should be provided multiple times. 080 * 081 */ 082@Extensible() 083@BrokerExtension() 084@ThreadSafety(level= ThreadSafetyLevel.INTERFACE_THREADSAFE) 085public abstract class PolicyDecisionLogger implements UnboundIDExtension, 086 Reconfigurable<PolicyDecisionLoggerConfig>, ExampleUsageProvider { 087 088 /** 089 * Creates a new instance of this policy decision logger. 090 * All policy decision logger implementations must include a default 091 * constructor, but any initialization should generally be done in 092 * the {@code initializePolicyDecisionLogger} method. 093 */ 094 public PolicyDecisionLogger() 095 { 096 // No implementation is required. 097 } 098 099 /** 100 * {@inheritDoc} 101 */ 102 public abstract String getExtensionName(); 103 104 /** 105 * {@inheritDoc} 106 */ 107 public abstract String[] getExtensionDescription(); 108 109 /** 110 * {@inheritDoc} 111 */ 112 public void defineConfigArguments(final ArgumentParser parser) 113 throws ArgumentException 114 { 115 // No arguments will be allowed by default. 116 } 117 118 /** 119 * Initializes this policy decision logger. 120 * 121 * @param serverContext A handle to the server context for the server in 122 * which this extension is running. 123 * @param config The general configuration for 124 * this policy decision logger. 125 * @param parser The argument parser which 126 * has been initialized from the configuration 127 * for this policy decision logger. 128 * 129 * @throws LDAPException If a problem occurs while initializing 130 * this policy decision logger. 131 */ 132 public void initializePolicyDecisionLogger( 133 final ServerContext serverContext, 134 final PolicyDecisionLoggerConfig config, 135 final ArgumentParser parser) 136 throws LDAPException 137 { 138 // No initialization will be performed by default. 139 } 140 141 /** 142 * {@inheritDoc} 143 */ 144 public boolean isConfigurationAcceptable( 145 final PolicyDecisionLoggerConfig config, 146 final ArgumentParser parser, 147 final List<String> unacceptableReasons) 148 { 149 // No extended validation will be performed by default. 150 return true; 151 } 152 153 154 155 /** 156 * {@inheritDoc} 157 */ 158 public ResultCode applyConfiguration( 159 final PolicyDecisionLoggerConfig 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. 165 // If there are any arguments, 166 // then add an admin action message indicating that the extension 167 // needs to be restarted for any changes to take effect. 168 if (! parser.getNamedArguments().isEmpty()) 169 { 170 adminActionsRequired.add( 171 "No configuration change has actually been applied." + 172 " The new configuration will not take effect" + 173 " until this policy decision logger is disabled" + 174 " and re-enabled or until the server is restarted."); 175 } 176 return ResultCode.SUCCESS; 177 } 178 179 /** 180 * Performs any cleanup which may be necessary when this 181 * policy decision logger is to be taken out of service. 182 */ 183 public void finalizePolicyDecisionLogger() 184 { 185 // No implementation is required. 186 } 187 188 /** 189 * Logs a message. 190 * 191 * @param messageType The {@link PolicyMessageType}. 192 * This is an indication of what stage in the decision 193 * processing lifecycle is being logged. 194 * <p> 195 * This can be either {@link PolicyMessageType#ADVICE} 196 * or {@link PolicyMessageType#DECISION} 197 * </p> 198 * @param logContext A set of key/value pairs summarizing and providing 199 * context for the policy decision or advice. 200 * @param message This is {@code null} when include-pdp-response 201 * is disabled and for message types that do not record 202 * a policy decision response 203 * (like {@link PolicyMessageType#ADVICE}). 204 */ 205 public abstract void log( 206 final PolicyMessageType messageType, 207 final Map<String, String> logContext, 208 final String message); 209 210 211 212 /** 213 * {@inheritDoc} 214 */ 215 public Map<List<String>,String> getExamplesArgumentSets() 216 { 217 return Collections.emptyMap(); 218 } 219}