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     * trunk/ds/resource/legal-notices/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     * trunk/ds/resource/legal-notices/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 2010-2013 UnboundID Corp.
026     */
027    package com.unboundid.directory.sdk.broker.types;
028    
029    import com.unboundid.util.Mutable;
030    import com.unboundid.util.NotExtensible;
031    import com.unboundid.util.ThreadSafety;
032    import com.unboundid.util.ThreadSafetyLevel;
033    import com.unboundid.util.Validator;
034    
035    import java.util.Collections;
036    import java.util.Date;
037    import java.util.Iterator;
038    import java.util.Set;
039    
040    /**
041     * This class provides a data structure for working with OAuth2 access tokens.
042     */
043    @NotExtensible()
044    @Mutable()
045    @ThreadSafety(level= ThreadSafetyLevel.COMPLETELY_THREADSAFE)
046    public final class AccessToken extends Token
047    {
048      // The owner associated with this token.
049      private final String username;
050    
051      // The granted authorities of the user that performed the authorization.
052      private final Set<String> authorities;
053    
054      // The set of scope IDs for which the application has requested or authorized.
055      private final Set<String> scopeIds;
056    
057      // The refresh token associated with this access token.
058      private volatile RefreshToken refreshToken;
059    
060      /**
061       * Construct a new access token instance.
062       *
063       * @param username The username of the resource owner this access token is
064       *                 associated with or {@code null} if resource owner
065       *                 authentication was not performed.
066       * @param authorities The authorities of the resource owner or empty if
067       *                    resource owner authentication was not performed.
068       *                    Must not be null.
069       * @param applicationId The application ID with which this token is
070       *                      associated. Must not be null.
071       * @param generateTimestamp The time that this token was generated. Must not
072       *                          be null.
073       * @param maxValiditySeconds The maximum length of time in seconds that this
074       *                           token will be considered valid. Must not be null
075       *                           and must not be negative.
076       * @param scopeIds The set of scopes for which the client has been authorized.
077       *                 Must not be null.
078       */
079      public AccessToken(final String username, final Set<String> authorities,
080                         final String applicationId, final Date generateTimestamp,
081                         final long maxValiditySeconds, final Set<String> scopeIds)
082      {
083        super(applicationId, generateTimestamp, maxValiditySeconds);
084        Validator.ensureNotNull(authorities, scopeIds);
085        this.username = username;
086        this.authorities = Collections.unmodifiableSet(authorities);
087        this.scopeIds = Collections.unmodifiableSet(scopeIds);
088      }
089    
090      /**
091       * Retrieves the username of the resource owner this access token is
092       * associated with. Some grant types don't require resource owner involvement
093       * (ie. client_credentials), the username may be {@code null}.
094       *
095       * @return The username of the resource owner this access token is associated
096       *         with or {@code null} if resource owner authentication was not
097       *         performed.
098       */
099      public String getUsername()
100      {
101        return username;
102      }
103    
104    
105      /**
106       * Retrieves the authorities of the resource owner. Some grant types don't
107       * require resource owner involvement (ie. client_credentials), the
108       * authorities may be empty.
109       *
110       * @return The authorities of the resource owner or empty if
111       *         resource owner authentication was not performed.
112       */
113      public Set<String> getAuthorities()
114      {
115        return authorities;
116      }
117    
118      /**
119       * Retrieves the set of scope IDs for which the client has been authorized.
120       *
121       * @return The set of scope IDs for which the client has been authorized.
122       */
123      public Set<String> getScopeIds()
124      {
125        return scopeIds;
126      }
127    
128      /**
129       * Retrieves the refresh token associated with this access token.
130       *
131       * @return The refresh token associated with this access token or {@code null}
132       *         if there is no associated refresh token.
133       */
134      public RefreshToken getRefreshToken()
135      {
136        return refreshToken;
137      }
138    
139      /**
140       * Sets the refresh token associated with this access token.
141       *
142       * @param refreshToken The refresh token associated with this access token.
143       */
144      public void setRefreshToken(final RefreshToken refreshToken)
145      {
146        Validator.ensureNotNull(refreshToken);
147        this.refreshToken = refreshToken;
148      }
149    
150      /**
151       * Retrieves a hash code for this access token.
152       *
153       * @return  A hash code for this access token.
154       */
155      @Override
156      public int hashCode()
157      {
158        final int prime = 31;
159        int result = super.hashCode();
160        result = prime * result + (username != null ? username.hashCode() : 0);
161        result = prime * result + (authorities != null ?
162            authorities.hashCode() : 0);
163        result = prime * result + (scopeIds != null ? scopeIds.hashCode() : 0);
164        return result;
165      }
166    
167      /**
168       * Indicates whether the provided object is equal to this access token.
169       *
170       * @param  o  The object for which to make the determination.
171       *
172       * @return  {@code true} if the provided object is equal to this authorization
173       *          code, or {@code false} if not.
174       */
175      @Override
176      public boolean equals(final Object o)
177      {
178        if (this == o)
179        {
180          return true;
181        }
182        if (o == null || getClass() != o.getClass())
183        {
184          return false;
185        }
186    
187        AccessToken that = (AccessToken) o;
188    
189        if (scopeIds != null ?
190            !scopeIds.equals(that.scopeIds) :
191            that.scopeIds != null)
192        {
193          return false;
194        }
195        if (username != null ?
196            !username.equals(that.username) :
197            that.username != null)
198        {
199          return false;
200        }
201        if (authorities != null ?
202            !authorities.equals(that.authorities) :
203            that.authorities != null)
204        {
205          return false;
206        }
207        if (refreshToken != null ?
208            !refreshToken.equals(that.refreshToken) :
209            that.refreshToken != null)
210        {
211          return false;
212        }
213    
214        return super.equals(o);
215      }
216    
217      /**
218       * Appends a string representation of this access token to the provided
219       * buffer.
220       *
221       * @param  buffer  The buffer to which the string representation should be
222       *                 appended.
223       */
224      protected void toString(final StringBuilder buffer)
225      {
226        buffer.append("AccessToken(username='");
227        buffer.append(username);
228        if (! authorities.isEmpty())
229        {
230          buffer.append(", authorities={");
231    
232          final Iterator<String> iterator = authorities.iterator();
233          while (iterator.hasNext())
234          {
235            buffer.append(iterator.next());
236            if (iterator.hasNext())
237            {
238              buffer.append(", ");
239            }
240          }
241    
242          buffer.append('}');
243        }
244        buffer.append("', appID=");
245        buffer.append(getApplicationId());
246        buffer.append(", generateTimestamp=");
247        buffer.append(getGenerateTimestamp());
248        buffer.append("', maxValiditySeconds=");
249        buffer.append(getMaxValiditySeconds());
250        buffer.append(", value=");
251        buffer.append(getValue());
252    
253        if (! scopeIds.isEmpty())
254        {
255          buffer.append(", scopes={");
256    
257          final Iterator<String> iterator = scopeIds.iterator();
258          while (iterator.hasNext())
259          {
260            buffer.append(iterator.next());
261            if (iterator.hasNext())
262            {
263              buffer.append(", ");
264            }
265          }
266    
267          buffer.append('}');
268        }
269    
270        buffer.append("')");
271      }
272    }