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}