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-2015 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    /**
042     * This class provides a data structure for working with OAuth2 temporary
043     * authorization codes.
044     */
045    @NotExtensible()
046    @Mutable()
047    @ThreadSafety(level= ThreadSafetyLevel.COMPLETELY_THREADSAFE)
048    public final class AuthorizationCode
049    {
050      // The ID of the user that performed the authorization.
051      private final String userId;
052    
053      // The application ID that has been authorized.
054      private final String applicationId;
055    
056      // The redirect URI the client specified.
057      private final String redirectUri;
058    
059      // The time that this authorization code was generated.
060      private final Date generateTimestamp;
061    
062      // The maximum length of time in seconds that this authorization code will be
063      // considered valid.
064      private final long maxValiditySeconds;
065    
066      // The set of scope IDs for which the application has been authorized.
067      private final Set<String> scopeIds;
068    
069      // The optional state parameter from the client.
070      private final String state;
071    
072      // The time that the user authenticated with the server, in milliseconds
073      // since midnight January 1, 1970 GMT
074      private final long authTime;
075    
076      // A value of this authorization code that will be exposed to clients.
077      private volatile String value;
078    
079      /**
080       * Construct a new authorization code instance.
081       *
082       * @param userId The user ID of the resource owner this authorization code
083       *                 is associated with. Must not be null.
084       * @param applicationId The application ID with which this token is
085       *                      associated. Must not be null.
086       * @param redirectUri the endpoint to redirect the resource owner's user-agent
087       *                    back to the application. Must not be null.
088       * @param generateTimestamp The time that this token was generated.
089       *                          Must not be null.
090       * @param maxValiditySeconds The maximum length of time in seconds that this
091       *                           token will be considered valid. Must not be null.
092       * @param scopeIds The set of scopes for which the client has been authorized.
093       *                  Must not be null.
094       * @param state The opaque value used by the client to maintain state between
095       *              the request and callback.
096       * @param authTime The time at which the resource owner was authenticated with
097       *                 the Identity Broker, in milliseconds since 1/1/70 12:00 AM.
098       */
099      public AuthorizationCode(final String userId, final String applicationId,
100                               final String redirectUri,
101                               final Date generateTimestamp,
102                               final long maxValiditySeconds,
103                               final Set<String> scopeIds,
104                               final String state,
105                               final long authTime)
106      {
107        Validator.ensureNotNull(userId, applicationId, redirectUri);
108        Validator.ensureNotNull(generateTimestamp, maxValiditySeconds, scopeIds);
109        this.applicationId = applicationId;
110        this.userId = userId;
111        this.redirectUri = redirectUri;
112        this.generateTimestamp = generateTimestamp;
113        this.maxValiditySeconds = maxValiditySeconds;
114        this.scopeIds = Collections.unmodifiableSet(scopeIds);
115        this.state = state;
116        this.authTime = authTime;
117      }
118    
119      /**
120       * Retrieves the user ID of the resource owner this authorization code is
121       * associated with.
122       *
123       * @return The user ID of the resource owner this authorization code is
124       *         associated with.
125       */
126      public String getUserId()
127      {
128        return userId;
129      }
130    
131      /**
132       * Retrieves the application ID with which this authorization code is
133       * associated.
134       *
135       * @return  The application ID with which this authorization code is
136       *          associated.
137       */
138      public String getApplicationId()
139      {
140        return applicationId;
141      }
142    
143      /**
144       * Retrieves the set of scope IDs for which the client has been authorized.
145       *
146       * @return  The set of scope IDs for which the client has been authorized.
147       */
148      public Set<String> getScopeIds()
149      {
150        return scopeIds;
151      }
152    
153      /**
154       * Retrieves the time that this authorization code was generated.
155       *
156       * @return  The time that this authorization code was generated.
157       */
158      public Date getGenerateTimestamp()
159      {
160        return generateTimestamp;
161      }
162    
163      /**
164       * Retrieves the maximum length of time in seconds that this code will be
165       * considered valid.
166       *
167       * @return  The maximum length of time in seconds that this code will be
168       *          considered valid.
169       */
170      public long getMaxValiditySeconds()
171      {
172        return maxValiditySeconds;
173      }
174    
175      /**
176       * Retrieves the opaque value used by the client to maintain state between
177       * the request and callback.
178       *
179       * @return  The opaque value used by the client to maintain state between
180       *          the request and callback or {@code null} if it was not used.
181       */
182      public String getState()
183      {
184        return state;
185      }
186    
187      /**
188       * Returns the endpoint to redirect the resource owner's user-agent back to
189       * the application.
190       *
191       * @return  The endpoint to redirect the resource owner's user-agent back to
192       *          the application.
193       */
194      public String getRedirectUri()
195      {
196        return redirectUri;
197      }
198    
199    
200      /**
201       * Retrieves the time that the user authenticated with the server.
202       *
203       * @return Authentication time in milliseconds since midnight 1/1/1970 GMT.
204       */
205      public long getAuthTime() {
206        return authTime;
207      }
208    
209      /**
210       * Retrieves the string value of this authorization code that should be
211       * returned to the client.
212       *
213       * @return  The string value of this authorization code that should be
214       *          returned to the client.
215       */
216      public String getValue()
217      {
218        return value;
219      }
220    
221      /**
222       * Sets the string value of this authorization code that should be returned
223       * to the client.
224       *
225       * @param value The string value of this authorization code that should be
226       *              returned to the client.
227       */
228      public void setValue(final String value)
229      {
230        this.value = value;
231      }
232    
233      /**
234       * Indicates whether this authorization code is expired.
235       *
236       * @return  {@code true} if this authorization code is expired, or
237       *          {@code false} if not.
238       */
239      public boolean isExpired()
240      {
241        final long generateTS = generateTimestamp.getTime();
242        final long expirationTime = (generateTS + (1000L * maxValiditySeconds));
243        final long currentTime = System.currentTimeMillis();
244        return currentTime > expirationTime;
245      }
246    
247    
248    
249      /**
250       * Retrieves a hash code for this authorization code.
251       *
252       * @return  A hash code for this authorization code.
253       */
254      @Override
255      public int hashCode()
256      {
257        final int prime = 31;
258        int result = 1;
259        result = prime * result + (userId != null ? userId.hashCode() : 0);
260        result = prime * result + (applicationId != null ?
261            applicationId.hashCode() : 0);
262        result = prime * result + (state != null ? state.hashCode() : 0);
263        result = prime * result + (redirectUri != null ?
264            redirectUri.hashCode() : 0);
265        result = prime * result + (generateTimestamp != null ?
266            generateTimestamp.hashCode() : 0);
267        result = prime * result + (int) (maxValiditySeconds ^
268            (maxValiditySeconds >>> 32));
269        result = prime * result + (scopeIds != null ? scopeIds.hashCode() : 0);
270        return result;
271      }
272    
273      /**
274       * Indicates whether the provided object is equal to this authorization code.
275       *
276       * @param  o  The object for which to make the determination.
277       *
278       * @return  {@code true} if the provided object is equal to this authorization
279       *          code, or {@code false} if not.
280       */
281      @Override
282      public boolean equals(final Object o)
283      {
284        if (this == o)
285        {
286          return true;
287        }
288        if (o == null || getClass() != o.getClass())
289        {
290          return false;
291        }
292    
293        AuthorizationCode that = (AuthorizationCode) o;
294    
295        if (maxValiditySeconds != that.maxValiditySeconds)
296        {
297          return false;
298        }
299        if (applicationId != null ? !applicationId.equals(that.applicationId) :
300            that.applicationId != null)
301        {
302          return false;
303        }
304        if (scopeIds != null ? !scopeIds.equals(that.scopeIds) :
305            that.scopeIds != null)
306        {
307          return false;
308        }
309        if (generateTimestamp != null ?
310            !generateTimestamp.equals(that.generateTimestamp) :
311            that.generateTimestamp != null)
312        {
313          return false;
314        }
315        if (userId != null ? !userId.equals(that.userId) :
316            that.userId != null)
317        {
318          return false;
319        }
320        if (redirectUri != null ? !redirectUri.equals(that.redirectUri) :
321            that.redirectUri != null)
322        {
323          return false;
324        }
325        if (state != null ? !state.equals(that.state) : that.state != null)
326        {
327          return false;
328        }
329        if (value != null ? !value.equals(that.value) : that.value != null)
330        {
331          return false;
332        }
333    
334        return true;
335      }
336    
337    
338    
339    
340      /**
341       * Retrieves a string representation of this authorization code.
342       *
343       * @return  A string representation of this authorization code.
344       */
345      @Override()
346      public String toString()
347      {
348        final StringBuilder buffer = new StringBuilder();
349        toString(buffer);
350        return buffer.toString();
351      }
352    
353    
354    
355      /**
356       * Appends a string representation of this authorization code to the provided
357       * buffer.
358       *
359       * @param  buffer  The buffer to which the string representation should be
360       *                 appended.
361       */
362      void toString(final StringBuilder buffer)
363      {
364        buffer.append("AuthorizationCode(userId='");
365        buffer.append(userId);
366        buffer.append("', appID=");
367        buffer.append(applicationId);
368        buffer.append(", generateTimestamp=");
369        buffer.append(generateTimestamp);
370        buffer.append("', maxValiditySeconds=");
371        buffer.append(maxValiditySeconds);
372        buffer.append(", value=");
373        buffer.append(value);
374    
375        if (state != null)
376        {
377          buffer.append("', state='");
378          buffer.append(state);
379        }
380        if (! scopeIds.isEmpty())
381        {
382          buffer.append(", authorizedScopes={");
383    
384          final Iterator<String> iterator = scopeIds.iterator();
385          while (iterator.hasNext())
386          {
387            buffer.append(iterator.next());
388            if (iterator.hasNext())
389            {
390              buffer.append(", ");
391            }
392          }
393    
394          buffer.append('}');
395        }
396        buffer.append("', redirectUri='");
397        buffer.append(redirectUri);
398    
399        buffer.append("')");
400      }
401    }