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 2016-2019 Ping Identity Corporation
026 */
027
028
029package com.unboundid.directory.sdk.common.types;
030
031import com.unboundid.util.NotExtensible;
032
033import java.util.Collections;
034import java.util.Map;
035import java.util.Set;
036import java.util.concurrent.TimeUnit;
037
038/**
039 * Object returned from a request to an AccessTokenValidator to validate a
040 * token. The fields of this object are derived from the IETF OAuth 2.0 Token
041 * Introspection specification (RFC7662).
042 * <p>
043 * The decision as to whether an access token is accepted or not varies by
044 * product. For the Directory Server, Directory Proxy Server,
045 * Data Sync Server, or Data Metrics Server, different REST APIs
046 * may enforce different authorization rules, depending on their configuration;
047 * please refer to the relevant documentation. In general, a token's
048 * {@code active} property must be true and its {@code tokenOwner} must not be
049 * null.
050 * <p>
051 * For the Data Governance Server, authorization decisions are made by the policy
052 * engine. All properties of the TokenValidationResult may be accessed by
053 * policies; however, the default policy may only examine a subset of those
054 * properties (e.g. especially the {@code active} property).
055 */
056@NotExtensible()
057public final class TokenValidationResult {
058
059
060  private final Boolean active;
061
062  private final Set<String> scope;
063
064  private final String clientId;
065
066  private final String username;
067
068  private final String tokenType;
069
070  private final Long expirationTime;
071
072  private final Long issuedAt;
073
074  private final Long notUsedBefore;
075
076  private final String tokenSubject;
077
078  private final String tokenOwner;
079
080  private final Set<String> audience;
081
082  private final String tokenIdentifier;
083
084  /**
085   * This field contains any extension values implemented by the
086   * Token Validator.
087   */
088  private final Map<String,Object> additionalProperties;
089
090  /**
091   * Private constructor for builder.
092   * @param builder Builder source for properties.
093   */
094  private TokenValidationResult(final Builder builder)
095  {
096    this.active = builder.active;
097    this.scope = builder.scope;
098    this.clientId = builder.clientId;
099    this.username = builder.username;
100    this.tokenType = builder.tokenType;
101    this.expirationTime = builder.expirationTime;
102    this.issuedAt = builder.issuedAt;
103    this.notUsedBefore = builder.notUsedBefore;
104    this.tokenSubject = builder.tokenSubject;
105    this.tokenOwner = builder.tokenOwner;
106    this.audience = builder.audience;
107    this.tokenIdentifier = builder.tokenIdentifier;
108    this.additionalProperties = (builder.additionalProperties == null) ?
109        Collections.<String,Object>emptyMap() :
110        builder.additionalProperties;
111  }
112
113  /**
114   * Get whether the token is active. Per RFC 7662, a value of true for this
115   * property indicates that the given token was issued by the Token
116   * Validator's associated authorization server, has not been revoked by the
117   * resource owner, and is within its given time window of validity
118   * (e.g. after its issuance time and before its expiration time).
119   * @return the active state.
120   */
121  public Boolean getActive() {
122    return active;
123  }
124
125  /**
126   * Get the scopes granted to this token.
127   * @return set of scope names.
128   */
129  public Set<String> getScope() {
130    return scope;
131  }
132
133  /**
134   * Get the OAuth2 client Id of the client that requested the token.
135   * @return client Id string.
136   */
137  public String getClientId() {
138    return clientId;
139  }
140
141  /**
142   * Get a human-readable user name for the resource owner that authorized
143   * the token.
144   * @return user name string.
145   */
146  public String getUsername() {
147    return username;
148  }
149
150  /**
151   * Get the token type.  The type of the token is defined in section 5.1 of
152   * OAuth 2.0 [RFC6749].
153   * @return token type string.
154   */
155  public String getTokenType() {
156    return tokenType;
157  }
158
159  /**
160   * Get the token expiration time in seconds since January 1 1970 UTC.
161   * @return expiration time in seconds.
162   */
163  public Long getExpirationTime() {
164    return expirationTime;
165  }
166
167  /**
168   * Get the token issue time in seconds since January 1 1970 UTC.
169   * @return token issue time in seconds.
170   */
171  public Long getIssuedAt() {
172    return issuedAt;
173  }
174
175  /**
176   * Get the not used before time in seconds since January 1 1070 UTC.
177   * @return not used before time in seconds.
178   */
179  public Long getNotUsedBefore() {
180    return notUsedBefore;
181  }
182
183  /**
184   * Get the token subject as defined in JWT [RFC7519].  This value should
185   * contain the subject ID as known to the external authorization server rather
186   * than the local server.
187   * @return token subject string.
188   */
189  public String getTokenSubject() {
190    return tokenSubject;
191  }
192
193  /**
194   * Get the token subject as defined in JWT [RFC7519].  This value should
195   * contain the subject ID as known to the Ping Identity server rather
196   * than the external authorization server.
197   * <p>
198   * It is the responsibility of the Token Validator to translate an external
199   * subject identifier into the local server's syntax.
200   * This syntax varies by product. For the Directory Server,
201   * Directory Proxy Server, Data Sync Server, or
202   * Data Metrics Server, the value should be an LDAP DN.
203   * The Data Governance Server uses a relative resource path as the subject ID,
204   * e.g. "Users/user_id", where user_id is the value of the subject's SCIM
205   * id property.
206   * @return token owner string.
207   */
208  public String getTokenOwner() {
209    return tokenOwner;
210  }
211
212  /**
213   * Get the token's intended audience(s).  The audience is a Service-specific
214   * identifier representing the intended audience(s) for this token, as
215   * defined in JWT [RFC7519].
216   * @return token audience.
217   */
218  public Set<String> getAudience() {
219    return audience;
220  }
221
222  /**
223   * Get the unique identifier for this token. as defined in section 4.1.7 of
224   * JWT [RFC7519].
225   * @return token unique identifier string.
226   */
227  public String getTokenIdentifier() {
228    return tokenIdentifier;
229  }
230
231  /**
232   * Get any extension properties associated with the token.
233   * @return Map of property names to values.
234   */
235  public Map<String, Object> getAdditionalProperties() {
236    return additionalProperties;
237  }
238
239  /**
240   * A Builder for TokenValidationResult.
241   */
242  public static class Builder
243  {
244    private Boolean active;
245    private Set<String> scope;
246    private String clientId;
247    private String username;
248    private String tokenType;
249    private Long expirationTime;
250    private Long issuedAt;
251    private Long notUsedBefore;
252    private String tokenSubject;
253    private String tokenOwner;
254    private Set<String> audience;
255    private String tokenIdentifier;
256    private Map<String,Object> additionalProperties;
257
258
259    /**
260     * Creates a new builder object.
261     * @param active true if the token is active, false if not.  Per RFC 7662,
262     *               a value of true for this property indicates that the given
263     *               token was issued by the Token Validator's associated
264     *               authorization server, has not been revoked by the resource
265     *               owner, and is within its given time window of validity
266     *               (e.g. after its issuance time and before its expiration
267     *               time).
268     */
269    public Builder(final boolean active)
270    {
271      this.active = active;
272      setScope(Collections.<String>emptySet());
273    }
274
275    /**
276     * Set the active field of the token validation result.
277     *
278     * @param active true if the token is active, false if not.  Per RFC 7662,
279     *               a value of true for this property indicates that the given
280     *               token was issued by the Token Validator's associated
281     *               authorization server, has not been revoked by the resource
282     *               owner, and is within its given time window of validity
283     *               (e.g. after its issuance time and before its expiration
284     *               time).
285     * @return this.
286     */
287    public Builder setActive(final boolean active)
288    {
289      this.active = active;
290      return this;
291    }
292
293    /**
294     * Set the optional scope field of the token validation result.
295     *
296     * @param scope A list of strings representing the scopes associated with
297     *              this token.
298     * @return this.
299     */
300    public Builder setScope(final Set<String> scope)
301    {
302      this.scope = (scope == null) ? Collections.<String>emptySet() : scope;
303      return this;
304    }
305
306    /**
307     * Set the optional clientId field of the token validation result.
308     *
309     * @param clientId Client identifier for the OAuth 2.0 client that
310     *                 requested this token.
311     * @return this.
312     */
313    public Builder setClientId(final String clientId)
314    {
315      this.clientId = clientId;
316      return this;
317    }
318
319    /**
320     * Set the optional username field of the token validation result.
321     *
322     * @param username Human-readable identifier for the resource owner who
323     *                 authorized this token.
324     * @return this.
325     */
326    public Builder setUsername(final String username)
327    {
328      this.username = username;
329      return this;
330    }
331
332    /**
333     * Set the optional tokenType field of the token validation result.
334     *
335     * @param tokenType Type of the token as defined in section 5.1 of OAuth
336     *                  2.0 [RFC6749].
337     * @return this.
338     */
339    public Builder setTokenType(final String tokenType)
340    {
341      this.tokenType = tokenType;
342      return this;
343    }
344
345    /**
346     * Set the optional expirationTime field of the token validation result.
347     *
348     * @param expirationTime Integer timestamp, measured in the number of
349     *                       time units since January 1 1970 UTC, indicating
350     *                       when this token will expire.
351     * @param timeUnit the time units of the specified expiration time.
352     * @return this.
353     */
354    public Builder setExpirationTime(
355        final long expirationTime,
356        final TimeUnit timeUnit)
357    {
358      this.expirationTime = timeUnit.toSeconds(expirationTime);
359      return this;
360    }
361
362    /**
363     * Set the optional issuedAt field of the token validation result.
364     *
365     * @param issuedAt Integer timestamp, measured in the number of time
366     *                 units since January 1 1970 UTC, indicating when this
367     *                 token was originally issued.
368     * @param timeUnit the time units of the specified issuedAt time.
369     * @return this.
370     */
371    public Builder setIssuedAt(
372        final long issuedAt,
373        final TimeUnit timeUnit)
374    {
375      this.issuedAt = timeUnit.toSeconds(issuedAt);
376      return this;
377    }
378
379    /**
380     * Set the optional notUsedBefore field of the token validation result.
381     *
382     * @param notUsedBefore Integer timestamp, measured in the number of
383     *                      time units since January 1 1970 UTC, indicating
384     *                      when this token is not to be used before.
385     * @param timeUnit the time units of the specified notUsedBefore time.
386     * @return this.
387     */
388    public Builder setNotUsedBefore(
389        final long notUsedBefore,
390        final TimeUnit timeUnit)
391    {
392      this.notUsedBefore = timeUnit.toSeconds(notUsedBefore);
393      return this;
394    }
395
396    /**
397     * Set the optional subjectToken field of the token validation result.
398     *
399     * @param tokenSubject Subject of the token, as defined in JWT [RFC7519].
400     *                     This value should contain the subject ID as known to
401     *                     the external authorization server rather than the
402     *                     local server.
403     * @return this.
404     */
405    public Builder setTokenSubject(final String tokenSubject)
406    {
407      this.tokenSubject = tokenSubject;
408      return this;
409    }
410
411    /**
412     * Set the optional tokenOwner field of the token validation result.
413     *
414     * @param tokenOwner Mapped subject of the token.
415     *                   This value should contain the subject ID as known to
416     *                   the local server rather than the external
417     *                   authorization server.
418     *                   <p>
419     *                   It is the responsibility of the Token Validator to
420     *                   translate an external subject identifier into the
421     *                   local server's syntax. This syntax varies by product.
422     *                   For the Directory Server,
423     *                   Directory Proxy Server, Data Sync Server, or
424     *                   Data Metrics Server, the value should be an
425     *                   LDAP DN. The Data Governance Server uses a relative
426     *                   resource path as the subject ID,  e.g. "Users/user_id",
427     *                   where user_id is the value of the subject's SCIM id
428     *                   property.
429     * @return this.
430     */
431    public Builder setTokenOwner(final String tokenOwner)
432    {
433      this.tokenOwner = tokenOwner;
434      return this;
435    }
436
437    /**
438     * Set the optional audience field of the token validation result.
439     *
440     * @param audience Service-specific identifiers representing the
441     *                 intended audience(s) for this token, as defined in
442     *                 JWT [RFC7519].
443     * @return this.
444     */
445    public Builder setAudience(final Set<String> audience)
446    {
447      this.audience = audience;
448      return this;
449    }
450
451    /**
452     * Set the optional tokenIdentifier field of the token validation result.
453     *
454     * @param tokenIdentifier Unique string identifier for the token, as
455     *                        defined in section 4.1.7 of JWT [RFC7519].
456     * @return this.
457     */
458    public Builder setTokenIdentifier(final String tokenIdentifier)
459    {
460      this.tokenIdentifier = tokenIdentifier;
461      return this;
462    }
463
464    /**
465     * Set the optional additionalProperties field of the token validation
466     * result.
467     * @param properties Map of property names to values, containing any
468     *                   extension values implemented by the
469     *                   AccessTokenValidator.
470     * @return this.
471     */
472    public Builder setAdditionalProperties(
473        final Map<String,Object> properties) {
474
475      this.additionalProperties = properties;
476      return this;
477    }
478
479    /**
480     * Builds a new TokenValidationResult from the parameters
481     * previously supplied to the builder.
482     *
483     * @return a new TokenValidationResult.
484     */
485    public TokenValidationResult build()
486    {
487      return new TokenValidationResult(this);
488    }
489  }
490
491}