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-2016 UnboundID Corp. 026 */ 027package com.unboundid.directory.sdk.broker.types; 028 029import com.unboundid.util.Mutable; 030import com.unboundid.util.NotExtensible; 031import com.unboundid.util.ThreadSafety; 032import com.unboundid.util.ThreadSafetyLevel; 033import com.unboundid.util.Validator; 034 035import java.util.Collections; 036import java.util.Date; 037import java.util.Iterator; 038import 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) 048public 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}