blob: 6b52d63d4e389750d2be66abb920cda650b4ed86 [file] [log] [blame]
/*
* Copyright (c) 2016 Manumitting Technologies Inc and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Manumitting Technologies Inc - initial API and implementation
*/
package org.eclipse.userstorage.internal.oauth;
import org.eclipse.userstorage.internal.util.IOUtil;
import org.eclipse.userstorage.internal.util.JSONUtil;
import org.eclipse.userstorage.internal.util.StringUtil;
import org.apache.http.client.utils.DateUtils;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* Represents the <em>authorization token</em> returned from an OAuth server.
* This object knows how to serialize and deserialize itself.
* It also knows about its staleness.
*/
public class AuthToken
{
// {
// "access_token":"06f965eefeac977ea132fff0afcc396639ada8d6",
// "expires_in":"3600",
// "token_type":"Bearer",
// "scope":"uss_all_retrieve",
// "refresh_token":"83f14719ffcf3f5b82825f4bda93c2e5f3e896cc"
// }
/** The actual access token itself */
private static String ACCESS_TOKEN = "access_token";
/** The type of access token, expected to be "Bearer" */
private static String TOKEN_TYPE = "token_type";
/** The scopes that had been authorized */
private static String SCOPE = "scope";
/** A token to provide to obtain a new access token */
private static String REFRESH_TOKEN = "refresh_token";
/** Expiry time of the token in seconds */
private static String EXPIRES_IN = "expires_in";
/** A private field to encode the absolute expiry date */
private static String EXPIRES = "_expires_";
private Map<String, String> details;
private Date expiryDate;
private AuthToken(Map<String, String> details, Date expiryDate)
{
this.details = details;
this.expiryDate = expiryDate;
}
public AuthToken(String jsonRepresentation, Date responseDate)
{
try
{
Object o = JSONUtil.parse(IOUtil.streamUTF(jsonRepresentation), null);
if (!(o instanceof Map<?, ?>))
{
throw new IllegalArgumentException("not a valid auth token object");
}
details = (Map<String, String>)o;
}
catch (IOException e)
{
throw new IllegalArgumentException("not a valid auth token object");
}
if (!details.containsKey(ACCESS_TOKEN))
{
throw new IllegalArgumentException("does not appear to be a valid auth token object");
}
if (details.containsKey(EXPIRES_IN))
{
long expiry = Long.parseLong(details.remove(EXPIRES_IN)); // seconds
expiryDate = new Date(responseDate.getTime() + expiry * 1000);
details.put(EXPIRES, DateUtils.formatDate(expiryDate));
}
}
/**
* Reconstitute an AuthToken object from the given serialized string
* @throws IllegalArgumentException if not a serialized token
*/
public static AuthToken deserialize(String serializedForm) throws IllegalArgumentException
{
if (serializedForm == null)
{
throw new IllegalArgumentException("no token");
}
try
{
Object o = JSONUtil.parse(IOUtil.streamUTF(serializedForm), null);
if (!(o instanceof Map<?, ?>))
{
throw new IllegalArgumentException("not a JSON object");
}
Map<String, String> details = (Map<String, String>)o;
if (details.containsKey(EXPIRES_IN) || !details.containsKey(ACCESS_TOKEN))
{
throw new IllegalArgumentException("does not appear to be a valid auth token object");
}
Date expiryDate = null;
if (details.containsKey(EXPIRES))
{
expiryDate = DateUtils.parseDate(details.get(EXPIRES));
}
return new AuthToken(details, expiryDate);
}
catch (IOException e)
{
throw new IllegalArgumentException(e);
}
}
public String getAccessToken()
{
return details.get(ACCESS_TOKEN);
}
public String getRefreshToken()
{
return details.get(REFRESH_TOKEN);
}
public String getTokenType()
{
return details.get(TOKEN_TYPE);
}
public Set<String> getScopes()
{
Set<String> result = new HashSet<String>();
String scopes = details.get(SCOPE);
if (scopes != null)
{
for (String s : scopes.split(" "))
{
result.add(s);
}
}
return result;
}
public boolean isExpired()
{
return expiryDate != null && expiryDate.compareTo(new Date()) <= 0;
}
/**
* Return a serialized form of the auth token.
* @throws IOException if an error occurred while serializing the form
*/
public String serialize() throws IOException
{
InputStream inputStream = JSONUtil.build(details);
ByteArrayOutputStream result = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer, 0, buffer.length)) != -1)
{
result.write(buffer, 0, length);
}
return result.toString(StringUtil.UTF8);
}
}