1 /* 2 * Copyright 2015, Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * 15 * * Neither the name of Google Inc. nor the names of its 16 * contributors may be used to endorse or promote products derived from 17 * this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 package com.google.auth.oauth2; 33 34 import com.google.common.base.MoreObjects; 35 import com.google.errorprone.annotations.CanIgnoreReturnValue; 36 import java.io.Serializable; 37 import java.util.ArrayList; 38 import java.util.Arrays; 39 import java.util.Date; 40 import java.util.List; 41 import java.util.Objects; 42 43 /** Represents a temporary OAuth2 access token and its expiration information. */ 44 public class AccessToken implements Serializable { 45 46 private static final long serialVersionUID = -8514239465808977353L; 47 48 private final String tokenValue; 49 private final Long expirationTimeMillis; 50 private final List<String> scopes; 51 52 /** 53 * @param tokenValue String representation of the access token. 54 * @param expirationTime Time when access token will expire. 55 */ AccessToken(String tokenValue, Date expirationTime)56 public AccessToken(String tokenValue, Date expirationTime) { 57 this.tokenValue = tokenValue; 58 this.expirationTimeMillis = (expirationTime == null) ? null : expirationTime.getTime(); 59 this.scopes = new ArrayList<>(); 60 } 61 AccessToken(Builder builder)62 private AccessToken(Builder builder) { 63 this.tokenValue = builder.getTokenValue(); 64 Date expirationTime = builder.getExpirationTime(); 65 this.expirationTimeMillis = (expirationTime == null) ? null : expirationTime.getTime(); 66 this.scopes = builder.getScopes(); 67 } 68 newBuilder()69 public static Builder newBuilder() { 70 return new Builder(); 71 } 72 toBuilder()73 public Builder toBuilder() { 74 return new Builder(this); 75 } 76 77 /** 78 * Scopes from the access token response. Not all credentials provide scopes in response and as 79 * per https://datatracker.ietf.org/doc/html/rfc6749#section-5.1 it is optional in the response. 80 * 81 * @return List of scopes 82 */ getScopes()83 public List<String> getScopes() { 84 return scopes; 85 } 86 87 /** 88 * String representation of the access token. 89 * 90 * @return The raw access token string value. 91 */ getTokenValue()92 public String getTokenValue() { 93 return tokenValue; 94 } 95 96 /** 97 * Time when access token will expire. 98 * 99 * @return The expiration time as a {@link Date}. 100 */ getExpirationTime()101 public Date getExpirationTime() { 102 if (expirationTimeMillis == null) { 103 return null; 104 } 105 return new Date(expirationTimeMillis); 106 } 107 getExpirationTimeMillis()108 Long getExpirationTimeMillis() { 109 return expirationTimeMillis; 110 } 111 112 @Override hashCode()113 public int hashCode() { 114 return Objects.hash(tokenValue, expirationTimeMillis, scopes); 115 } 116 117 @Override toString()118 public String toString() { 119 return MoreObjects.toStringHelper(this) 120 .add("tokenValue", tokenValue) 121 .add("expirationTimeMillis", expirationTimeMillis) 122 .add("scopes", scopes) 123 .toString(); 124 } 125 126 @Override equals(Object obj)127 public boolean equals(Object obj) { 128 if (!(obj instanceof AccessToken)) { 129 return false; 130 } 131 AccessToken other = (AccessToken) obj; 132 return Objects.equals(this.tokenValue, other.tokenValue) 133 && Objects.equals(this.expirationTimeMillis, other.expirationTimeMillis) 134 && Objects.equals(this.scopes, other.scopes); 135 } 136 137 public static class Builder { 138 private String tokenValue; 139 private Date expirationTime; 140 private List<String> scopes = new ArrayList<>(); 141 Builder()142 protected Builder() {} 143 Builder(AccessToken accessToken)144 protected Builder(AccessToken accessToken) { 145 this.tokenValue = accessToken.getTokenValue(); 146 this.expirationTime = accessToken.getExpirationTime(); 147 this.scopes = accessToken.getScopes(); 148 } 149 getTokenValue()150 public String getTokenValue() { 151 return this.tokenValue; 152 } 153 getScopes()154 public List<String> getScopes() { 155 return this.scopes; 156 } 157 getExpirationTime()158 public Date getExpirationTime() { 159 return this.expirationTime; 160 } 161 162 @CanIgnoreReturnValue setTokenValue(String tokenValue)163 public Builder setTokenValue(String tokenValue) { 164 this.tokenValue = tokenValue; 165 return this; 166 } 167 168 @CanIgnoreReturnValue setScopes(String scopes)169 public Builder setScopes(String scopes) { 170 if (scopes != null && scopes.trim().length() > 0) { 171 this.scopes = Arrays.asList(scopes.split(" ")); 172 } 173 return this; 174 } 175 176 @CanIgnoreReturnValue setScopes(List<String> scopes)177 public Builder setScopes(List<String> scopes) { 178 if (scopes == null) { 179 this.scopes = new ArrayList<>(); 180 } else { 181 this.scopes = scopes; 182 } 183 184 return this; 185 } 186 187 @CanIgnoreReturnValue setExpirationTime(Date expirationTime)188 public Builder setExpirationTime(Date expirationTime) { 189 this.expirationTime = expirationTime; 190 return this; 191 } 192 build()193 public AccessToken build() { 194 return new AccessToken(this); 195 } 196 } 197 } 198