/**
* Copyright 2014 Daum Kakao Corp.
*
* Redistribution and modification in source or binary forms are not permitted without specific prior written permission.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.kakao.authorization.accesstoken;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import com.kakao.helper.ServerProtocol;
import com.kakao.helper.SharedPreferencesCache;
import com.kakao.helper.Utility;
/**
* refresh token에 대한 expires_at은 아직 내려오지 않는다.
* @author MJ
*/
public class AccessToken implements Parcelable{
private static final String CACHE_ACCESS_TOKEN = "com.kakao.token.AccessToken";
private static final String CACHE_ACCESS_TOKEN_EXPIRES_AT = "com.kakao.token.AccessToken.ExpiresAt";
private static final String CACHE_REFRESH_TOKEN = "com.kakao.token.RefreshToken";
private static final String CACHE_REFRESH_TOKEN_EXPIRES_AT = "com.kakao.token.RefreshToken.ExpiresAt";
private static final Date MIN_DATE = new Date(Long.MIN_VALUE);
private static final Date MAX_DATE = new Date(Long.MAX_VALUE);
private static final Date DEFAULT_EXPIRATION_TIME = MAX_DATE;
private static final Date ALREADY_EXPIRED_EXPIRATION_TIME = MIN_DATE;
private String accessTokenString;
private String refreshTokenString;
private Date accessTokenExpiresAt;
private Date refreshTokenExpiresAt;
public static AccessToken createEmptyToken() {
return new AccessToken("", "", ALREADY_EXPIRED_EXPIRATION_TIME, ALREADY_EXPIRED_EXPIRATION_TIME);
}
public static AccessToken createFromCache(final SharedPreferencesCache cache) {
final String accessToken = cache.getString(CACHE_ACCESS_TOKEN);
final String refreshToken = cache.getString(CACHE_REFRESH_TOKEN);
final Date accessTokenExpiresAt = cache.getDate(CACHE_ACCESS_TOKEN_EXPIRES_AT);
final Date refreshTokenExpiresAt = cache.getDate(CACHE_REFRESH_TOKEN_EXPIRES_AT);
return new AccessToken(accessToken, refreshToken, accessTokenExpiresAt, refreshTokenExpiresAt);
}
public static AccessToken createFromResponse(final Map resultObj) {
String accessToken;
long accessTokenExpiresAt;
String refreshToken;
//long refreshTokenExpiresAt =0L;
accessToken = (String) resultObj.get(ServerProtocol.ACCESS_TOKEN_KEY);
if(accessToken == null)
return null;
refreshToken = (String) resultObj.get(ServerProtocol.REFRESH_TOKEN_KEY);
accessTokenExpiresAt = new Date().getTime() + (Integer)resultObj.get(ServerProtocol.EXPIRES_AT_KEY) * 1000;
// 일단 refresh token의 expires_in은 나중에
return new AccessToken(accessToken, refreshToken, new Date(accessTokenExpiresAt), MAX_DATE);
}
private AccessToken(final String accessTokenString, final String refreshTokenString, final Date accessTokenExpiresAt, final Date refreshTokenExpiresAt) {
this.accessTokenString = accessTokenString;
this.refreshTokenString = refreshTokenString;
this.accessTokenExpiresAt = accessTokenExpiresAt;
this.refreshTokenExpiresAt = refreshTokenExpiresAt;
}
public static void clearAccessTokenFromCache(final SharedPreferencesCache cache) {
final List<String> keysToRemove = new ArrayList<String>();
keysToRemove.add(CACHE_ACCESS_TOKEN);
keysToRemove.add(CACHE_ACCESS_TOKEN_EXPIRES_AT);
cache.clear(keysToRemove);
}
public void saveAccessTokenToCache(final SharedPreferencesCache cache) {
Bundle bundle = new Bundle();
bundle.putString(CACHE_ACCESS_TOKEN, accessTokenString);
bundle.putString(CACHE_REFRESH_TOKEN, refreshTokenString);
bundle.putLong(CACHE_ACCESS_TOKEN_EXPIRES_AT, accessTokenExpiresAt.getTime());
bundle.putLong(CACHE_REFRESH_TOKEN_EXPIRES_AT, refreshTokenExpiresAt.getTime());
cache.save(bundle);
}
// access token 갱신시에는 refresh token이 내려오지 않을 수도 있다.
public void updateAccessToken(final AccessToken newAccessToken){
String newRefreshToken = newAccessToken.refreshTokenString;
if(TextUtils.isEmpty(newRefreshToken)){
this.accessTokenString = newAccessToken.accessTokenString;
this.accessTokenExpiresAt = newAccessToken.accessTokenExpiresAt;
} else {
this.accessTokenString = newAccessToken.accessTokenString;
this.refreshTokenString = newAccessToken.refreshTokenString;
this.accessTokenExpiresAt = newAccessToken.accessTokenExpiresAt;
this.refreshTokenExpiresAt = newAccessToken.refreshTokenExpiresAt;
}
}
public String getAccessTokenString() {
return accessTokenString;
}
public String getRefreshTokenString() {
return refreshTokenString;
}
public boolean hasRefreshToken(){
return !Utility.isNullOrEmpty(this.refreshTokenString);
}
public boolean hasValidAccessToken() {
return !Utility.isNullOrEmpty(this.accessTokenString) && !new Date().after(this.accessTokenExpiresAt);
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(accessTokenString);
dest.writeString(refreshTokenString);
dest.writeLong(accessTokenExpiresAt.getTime());
dest.writeLong(refreshTokenExpiresAt.getTime());
}
public AccessToken(Parcel in) {
accessTokenString = in.readString();
refreshTokenString = in.readString();
accessTokenExpiresAt = new Date(in.readLong());
refreshTokenExpiresAt = new Date(in.readLong());
}
public static final Creator<AccessToken> CREATOR = new Creator<AccessToken>() {
public AccessToken createFromParcel(Parcel in) {
return new AccessToken(in);
}
public AccessToken[] newArray(int size) {
return new AccessToken[size];
}
};
}