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 2021 Ping Identity Corporation 026 */ 027package com.unboundid.directory.sdk.ds.types; 028 029 030 031import java.util.Iterator; 032import java.util.LinkedHashMap; 033import java.util.Map; 034 035import com.unboundid.util.Mutable; 036import com.unboundid.util.NotNull; 037import com.unboundid.util.Nullable; 038import com.unboundid.util.ThreadSafety; 039import com.unboundid.util.ThreadSafetyLevel; 040import com.unboundid.util.Validator; 041 042 043 044/** 045 * This class provides a data structure that holds information about the result 046 * of an attempt to pass through authentication to an external service. 047 */ 048@Mutable() 049@ThreadSafety(level=ThreadSafetyLevel.NOT_THREADSAFE) 050public final class PassThroughAuthenticationResult 051{ 052 // A set of custom log elements that should be included in the server's access 053 // log message for the bind operation. 054 @NotNull private final Map<String,Object> customLogElements; 055 056 // A result code that provides a general classification for the result of the 057 // pass-through authentication attempt. 058 @NotNull private final PassThroughAuthenticationResultCode resultCode; 059 060 // A diagnostic message that should be included in the response to the client 061 // (and also included in the server's access log message). 062 @Nullable private String diagnosticMessageForClient; 063 064 // An identifier for the user's account in the external service. 065 @Nullable private String remoteUserIdentifier; 066 067 068 069 /** 070 * Creates a new pass-through authentication result with the provided 071 * result code. 072 * 073 * @param resultCode A result code that provides a general classification 074 * for the result of the pass-through authentication 075 * attempt. It must not be {@code null}. 076 */ 077 public PassThroughAuthenticationResult( 078 @NotNull final PassThroughAuthenticationResultCode resultCode) 079 { 080 Validator.ensureNotNullWithMessage(resultCode, 081 "PassThroughAuthenticationResult.resultCode must not be null."); 082 083 this.resultCode = resultCode; 084 085 customLogElements = new LinkedHashMap<>(); 086 diagnosticMessageForClient = null; 087 remoteUserIdentifier = null; 088 } 089 090 091 092 /** 093 * Retrieves a result code that provides a general classification for the 094 * result of the pass-through authentication attempt. 095 * 096 * @return A result code that provides a general classification for the 097 * result of the pass-through authentication attempt. 098 */ 099 @NotNull() 100 public PassThroughAuthenticationResultCode getResultCode() 101 { 102 return resultCode; 103 } 104 105 106 107 /** 108 * Retrieves an identifier for the user's account in the external service. 109 * 110 * @return An identifier for the user's account in the external service, or 111 * {@code null} if the user could not be identified or no identifier 112 * is available. 113 */ 114 @Nullable() 115 public String getRemoteUserIdentifier() 116 { 117 return remoteUserIdentifier; 118 } 119 120 121 122 /** 123 * Sets an identifier for the user's account in the external service. 124 * 125 * @param remoteUserIdentifier An identifier for the user's account in the 126 * external service. It may be {@code null} if 127 * the user could not be identified or if no 128 * identifier is available. 129 */ 130 public void setRemoteUserIdentifier( 131 @Nullable final String remoteUserIdentifier) 132 { 133 this.remoteUserIdentifier = remoteUserIdentifier; 134 } 135 136 137 138 /** 139 * Retrieves a diagnostic message that should be included in the response to 140 * the client. If provided, it will also be included in the bind result 141 * access log message. 142 * 143 * @return A diagnostic message that should be included in the response to 144 * the client, or {@code null} if there should be no client-side 145 * diagnostic message. 146 */ 147 @Nullable() 148 public String getDiagnosticMessageForClient() 149 { 150 return diagnosticMessageForClient; 151 } 152 153 154 155 /** 156 * Sets a diagnostic message that should be included in the response to the 157 * client. If provided, it will also be included in the bind result access 158 * log message. 159 * 160 * @param diagnosticMessageForClient A diagnostic message that should be 161 * included in the response to the client. 162 * It may be {@code null} if no client 163 * diagnostic message should be used. 164 */ 165 public void setDiagnosticMessageForClient( 166 @Nullable final String diagnosticMessageForClient) 167 { 168 this.diagnosticMessageForClient = diagnosticMessageForClient; 169 } 170 171 172 173 /** 174 * Retrieves a map containing name-value pairs for custom elements that should 175 * be included in the bind result access log message. 176 * 177 * @return A map containing name-value pairs for custom elements that should 178 * be included in the bind result access log message. It will not be 179 * {@code null} but may be empty. 180 */ 181 @NotNull() 182 public Map<String,Object> getCustomLogElements() 183 { 184 return customLogElements; 185 } 186 187 188 189 /** 190 * Sets a custom name-value pair that should be included in the bind result 191 * access log message. 192 * 193 * @param name The name for the log element. It must not be {@code null}. 194 * @param value The value for the log element. It may be {@code null} if 195 * any existing log element with the provided name should be 196 * removed. 197 */ 198 public void setCustomLogElement(@NotNull final String name, 199 @Nullable final Object value) 200 { 201 if (value == null) 202 { 203 customLogElements.remove(name); 204 } 205 else 206 { 207 customLogElements.put(name, value); 208 } 209 } 210 211 212 213 /** 214 * Retrieves a string representation of this pass-through authentication 215 * result. 216 * 217 * @return A string representation of this pass-through authentication 218 * result. 219 */ 220 @Override() 221 @NotNull() 222 public String toString() 223 { 224 final StringBuilder buffer = new StringBuilder(); 225 toString(buffer); 226 return buffer.toString(); 227 } 228 229 230 231 /** 232 * Appends a string representation of this pass-through authentication result 233 * to the provided buffer. 234 * 235 * @param buffer The buffer to which the string representation should be 236 * appended. It must not be {@code null}. 237 */ 238 public void toString(@NotNull final StringBuilder buffer) 239 { 240 buffer.append("PassThroughAuthenticationResult(resultCode="); 241 buffer.append(resultCode.getName()); 242 243 if (remoteUserIdentifier != null) 244 { 245 buffer.append(", remoteUserIdentifier='"); 246 buffer.append(remoteUserIdentifier); 247 buffer.append('\''); 248 } 249 250 if (diagnosticMessageForClient != null) 251 { 252 buffer.append(", diagnosticMessageForClient='"); 253 buffer.append(diagnosticMessageForClient); 254 buffer.append('\''); 255 } 256 257 if (! customLogElements.isEmpty()) 258 { 259 buffer.append(", customLogElements={"); 260 261 final Iterator<Map.Entry<String,Object>> iterator = 262 customLogElements.entrySet().iterator(); 263 while (iterator.hasNext()) 264 { 265 final Map.Entry<String,Object> e = iterator.next(); 266 buffer.append(" '"); 267 buffer.append(e.getKey()); 268 buffer.append("'='"); 269 buffer.append(e.getValue()); 270 buffer.append('\''); 271 272 if (iterator.hasNext()) 273 { 274 buffer.append(", "); 275 } 276 } 277 278 buffer.append(" }"); 279 } 280 281 buffer.append(')'); 282 } 283}