/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.rest;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
import org.apache.log4j.Logger;
import org.dspace.authorize.AuthorizeException;
import org.dspace.eperson.EPerson;
import org.dspace.rest.common.User;
/**
* This class provide token generation, token holding and logging user into rest
* api. For login use method login with class org.dspace.rest.common.User. If
* you want to be deleted from holder, use method for logout.
*
* @author Rostislav Novak (Computing and Information Centre, CTU in Prague)
*/
public class TokenHolder
{
private static final Logger log = Logger.getLogger(TokenHolder.class);
public static String TOKEN_HEADER = "rest-dspace-token";
private static Map<String, String> tokens = new HashMap<String, String>(); // Map with pair Email,token
private static Map<String, EPerson> persons = new HashMap<String, EPerson>(); // Map with pair token,Eperson
/**
* Login user into rest api. It check user credentials if they are okay.
*
* @param user
* User which will be logged into rest api.
* @return Returns generated token, which must be used in request header
* under rest-api-token. If password is bad or user does not exist,
* it returns NULL.
* @throws WebApplicationException
* It is thrown by SQLException if user could not be read from
* database. And by Authorization exception if context has not
* permission to read eperson.
*/
public static String login(User user) throws WebApplicationException
{
org.dspace.core.Context context = null;
String token = null;
try
{
context = new org.dspace.core.Context();
EPerson dspaceUser = EPerson.findByEmail(context, user.getEmail());
if ((dspaceUser == null) || (!dspaceUser.checkPassword(user.getPassword())))
{
token = null;
}
else if (tokens.containsKey(user.getEmail()))
{
token = tokens.get(user.getEmail());
}
else
{
token = generateToken();
persons.put(token, dspaceUser);
tokens.put(user.getEmail(), token);
}
log.trace("User(" + user.getEmail() + ") has been logged.");
context.complete();
}
catch (SQLException e)
{
context.abort();
log.error("Could not read user from database. Message:" + e);
throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
}
catch (AuthorizeException e)
{
context.abort();
log.error("Could not find user, AuthorizeException. Message:" + e);
throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
}
finally
{
if ((context != null) && (context.isValid()))
{
context.abort();
log.error("Something get wrong. Aborting context in finally statement.");
throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
}
}
return token;
}
/**
* Return EPerson for log into context.
*
* @param token
* Token under which is stored eperson.
* @return Return instance of EPerson if is token right, otherwise it
* returns NULL.
*/
public static EPerson getEPerson(String token)
{
return persons.get(token);
}
/**
* Logout user from rest api. It delete token and EPerson from TokenHolder.
*
* @param token
* Token under which is stored eperson.
* @return Return true if was all okay, otherwise return false.
*/
public static boolean logout(String token)
{
if ((token == null) || (persons.get(token) == null))
{
return false;
}
String email = persons.get(token).getEmail();
EPerson person = persons.remove(token);
if (person == null)
{
return false;
}
tokens.remove(email);
return true;
}
/**
* It generates unique token.
*
* @return String filled with unique token.
*/
private static String generateToken()
{
return UUID.randomUUID().toString();
}
}