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