001/** 002 * Copyright 2014 Tampere University of Technology, Pori Department 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package service.tut.pori.users.google; 017 018import java.lang.reflect.Type; 019import java.util.Date; 020 021import org.apache.commons.lang3.StringUtils; 022import org.apache.log4j.Logger; 023 024import com.google.gson.Gson; 025import com.google.gson.GsonBuilder; 026import com.google.gson.JsonDeserializationContext; 027import com.google.gson.JsonDeserializer; 028import com.google.gson.JsonElement; 029import com.google.gson.JsonParseException; 030import com.google.gson.JsonPrimitive; 031import com.google.gson.JsonSerializationContext; 032import com.google.gson.JsonSerializer; 033import com.google.gson.annotations.SerializedName; 034 035 036/** 037 * OAuth2 Token 038 */ 039public class OAuth2Token { 040 private static final Logger LOGGER = Logger.getLogger(OAuth2Token.class); 041 @SerializedName(value=Definitions.JSON_NAME_OAUTH2_ACCESS_TOKEN) 042 private String _accessToken = null; 043 @SerializedName(value=Definitions.JSON_NAME_OAUTH2_EXPIRES_IN) 044 private Date _expires = null; 045 @SerializedName(value=Definitions.JSON_NAME_OAUTH2_REFRESH_TOKEN) 046 private String _refreshToken = null; 047 @SerializedName(value=Definitions.JSON_NAME_OAUTH2_TOKEN_TYPE) 048 private String _type = null; 049 050 /** 051 * 052 * @return serializer capable of properly serializing an OAuth2Token 053 */ 054 public static Gson getTokenGSONSerializer(){ 055 GsonBuilder builder = new GsonBuilder(); 056 builder.setPrettyPrinting(); 057 058 JsonSerializer<Date> dateSerializer = new JsonSerializer<Date>() { 059 060 @Override 061 public JsonElement serialize(Date src, Type typeOfSrc, JsonSerializationContext context) { 062 return (src == null ? null : new JsonPrimitive(toExpiresIn(src))); 063 } 064 }; 065 builder.registerTypeAdapter(Date.class, dateSerializer); 066 067 builder.registerTypeAdapter(Date.class, new JsonDeserializer<Date>() { // register custom adapter for Dates 068 069 @Override 070 public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { 071 return (json == null ? null : fromExpiresIn(json.getAsLong())); 072 } 073 }); 074 return builder.create(); 075 } 076 077 /** 078 * 079 * @param expiresIn in seconds 080 * @return the expiration date based on the given expiresIn or null if null value was passed 081 */ 082 public static Date fromExpiresIn(Long expiresIn){ 083 if(expiresIn == null){ 084 return null; 085 } 086 return new Date(System.currentTimeMillis()+expiresIn*1000); 087 } 088 089 /** 090 * 091 * @param expirationDate 092 * @return seconds to the expiration date (always at least 0) as designated b the expirationDate or null if null passed 093 */ 094 public static Long toExpiresIn(Date expirationDate){ 095 if(expirationDate == null){ 096 return null; 097 } 098 long milliSecondsTo = expirationDate.getTime()-System.currentTimeMillis(); // expiration time somewhere in the future, so unix time is greater 099 if(milliSecondsTo <= 0){ // the expiration time has passed 100 return 0L; 101 }else{ 102 return milliSecondsTo/1000; // convert to seconds truncating if necessary 103 } 104 } 105 106 /** 107 * Note: if you want to know if this token has expired, use isExpired() instead 108 * 109 * Note: this does not validate the token stricly as defined by the OAuth2 spec 110 * (e.g. http://tools.ietf.org/html/draft-ietf-oauth-v2-31#section-4.2.2), 111 * This is generally because the draft seems to change ~7 times a year, and because 112 * there is an ambiguity on what to do on missing expires_in field. This class 113 * should be subclassed to provide a more accurate (provider specific) implementation 114 * if one is needed. 115 * 116 * @return true if: 117 * - the token contains an accessToken, which is NOT expired OR 118 * - ...the token contains an refreshToken 119 */ 120 public boolean isValid(){ 121 if(!StringUtils.isEmpty(_refreshToken)){ 122 return true; 123 }else if(StringUtils.isEmpty(_accessToken)){ 124 return false; 125 }else{ 126 return !(isExpired()); 127 } 128 } 129 130 /** 131 * Same as calling expiresIn(0) 132 * @see #expiresIn(long) 133 * 134 * @return true if this token has expired 135 */ 136 public boolean isExpired(){ 137 return expiresIn(0); 138 } 139 140 /** 141 * This returns true if the token has already expired, expires in the the given timeframe or does not have a valid 142 * expiration time 143 * 144 * @param time the timeframe in ms 145 * @return true if the token expires in the given timeframe 146 */ 147 public boolean expiresIn(long time){ 148 if(_expires == null){ 149 LOGGER.debug("No expiration date given."); 150 return true; 151 }else if(_expires.getTime() <= (System.currentTimeMillis()+time)){ 152 return true; 153 }else{ 154 return false; 155 } 156 } 157 158 /** 159 * @return the accessToken 160 */ 161 public String getAccessToken() { 162 return _accessToken; 163 } 164 165 /** 166 * @param accessToken the accessToken to set 167 */ 168 public void setAccessToken(String accessToken) { 169 _accessToken = accessToken; 170 } 171 172 /** 173 * @return the refreshToken 174 */ 175 public String getRefreshToken() { 176 return _refreshToken; 177 } 178 179 /** 180 * @param refreshToken the refreshToken to set 181 */ 182 public void setRefreshToken(String refreshToken) { 183 _refreshToken = refreshToken; 184 } 185 186 /** 187 * @return the expires 188 */ 189 public Date getExpires() { 190 return _expires; 191 } 192 193 /** 194 * @param expires the expires to set 195 */ 196 public void setExpires(Date expires) { 197 _expires = expires; 198 } 199 200 /** 201 * 202 * @param expiresIn (in seconds) 203 */ 204 public void setExpiresIn(Long expiresIn){ 205 _expires = fromExpiresIn(expiresIn); 206 } 207 208 /** 209 * @return the type 210 */ 211 public String getType() { 212 return _type; 213 } 214 215 /** 216 * @param type the type to set 217 */ 218 public void setType(String type) { 219 _type = type; 220 } 221}