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