package org.marketcetera.util.ws.stateful;
import java.util.Arrays;
import org.marketcetera.util.except.I18NException;
import org.marketcetera.util.misc.ClassVersion;
import org.marketcetera.util.ws.stateless.StatelessClientContext;
import org.marketcetera.util.ws.stateless.StatelessRemoteCaller;
import org.marketcetera.util.ws.tags.SessionId;
import org.marketcetera.util.ws.wrappers.RemoteException;
/**
* An authentication service implementation.
*
* @author tlerios@marketcetera.com
* @since 1.0.0
* @version $Id: AuthServiceImpl.java 16154 2012-07-14 16:34:05Z colin $
*/
/* $License$ */
@ClassVersion("$Id: AuthServiceImpl.java 16154 2012-07-14 16:34:05Z colin $")
public class AuthServiceImpl<T>
extends ServiceBaseImpl<T>
implements AuthService
{
// INSTANCE DATA.
private final Authenticator mAuthenticator;
// CONSTRUCTORS.
/**
* Creates a new authentication service implementation with the
* given authenticator and session manager.
*
* @param authenticator The authenticator.
* @param sessionManager The session manager.
*/
public AuthServiceImpl
(Authenticator authenticator,
SessionManager<T> sessionManager)
{
super(sessionManager);
mAuthenticator=authenticator;
}
// INSTANCE METHODS.
/**
* Returns the receiver's authenticator.
*
* @return The authenticator.
*/
public Authenticator getAuthenticator()
{
return mAuthenticator;
}
/**
* Logs in the client with the given context, provided the given
* credentials are acceptable.
*
* @param context The context.
* @param user The user name.
* @param password The password.
*
* @return The ID of the new session.
*
* @throws I18NException Thrown if the authenticator rejects the
* credentials.
*/
private SessionId loginImpl
(StatelessClientContext context,
String user,
char[] password)
throws I18NException
{
if (!getAuthenticator().shouldAllow(context,user,password)) {
throw new I18NException(Messages.BAD_CREDENTIALS);
}
SessionId sessionId=SessionId.generate();
getSessionManager().put(sessionId,new SessionHolder<T>(user,context));
return sessionId;
}
/**
* Logs out the client with the given context and associated
* session holder. This method is a no-op if there is no active
* session for that client.
*
* @param sessionHolder The holder, which may be null.
*/
private void logout
(ClientContext context,
SessionHolder<T> sessionHolder)
{
if (sessionHolder!=null) {
getSessionManager().remove(context.getSessionId());
}
}
// AuthServiceInterface.
@Override
public SessionId login
(StatelessClientContext context,
final String user,
final char[] password)
throws RemoteException
{
try {
return (new StatelessRemoteCaller<SessionId>() {
@Override
protected SessionId call
(StatelessClientContext context)
throws I18NException
{
return loginImpl(context,user,password);
}}).execute(context);
} finally {
Arrays.fill(password,'\0');
}
}
@Override
public void logout
(ClientContext context)
throws RemoteException
{
(new RemoteRunner<T>(RemoteRunner.DEFAULT_VERSION_FILTER,
null,null,getSessionManager(),null) {
@Override
protected void run
(ClientContext context,
SessionHolder<T> sessionHolder)
{
logout(context,sessionHolder);
}}).execute(context);
}
}