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 }