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