package org.jboss.seam.security;
import static org.jboss.seam.ScopeType.SESSION;
import static org.jboss.seam.annotations.Install.BUILT_IN;
import java.io.IOException;
import java.io.Serializable;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import org.jboss.seam.annotations.Install;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.intercept.BypassInterceptors;
import org.jboss.seam.core.Events;
import org.jboss.seam.log.LogProvider;
import org.jboss.seam.log.Logging;
@Name("org.jboss.seam.security.credentials")
@Scope(SESSION)
@Install(precedence = BUILT_IN)
@BypassInterceptors
public class Credentials implements Serializable
{
public static final String EVENT_INIT_CREDENTIALS = "org.jboss.seam.security.initCredentials";
public static final String EVENT_CREDENTIALS_UPDATED = "org.jboss.seam.security.credentialsUpdated";
private static final LogProvider log = Logging.getLogProvider(Credentials.class);
private String username;
private String password;
private boolean invalid = false;
private boolean initialized;
public boolean isInitialized()
{
return initialized;
}
public void setInitialized(boolean initialized)
{
this.initialized = initialized;
}
public String getUsername()
{
if (!isInitialized() && Events.exists())
{
setInitialized(true);
Events.instance().raiseEvent(EVENT_INIT_CREDENTIALS, this);
}
return username;
}
public void setUsername(String username)
{
if (this.username != username && (this.username == null || !this.username.equals(username)))
{
this.username = username;
invalid = false;
if (Events.exists()) Events.instance().raiseEvent(EVENT_CREDENTIALS_UPDATED);
}
}
public String getPassword()
{
return password;
}
public void setPassword(String password)
{
if (this.password != password && (this.password == null || !this.password.equals(password)))
{
this.password = password;
invalid = false;
if (Events.exists()) Events.instance().raiseEvent(EVENT_CREDENTIALS_UPDATED);
}
}
public boolean isSet()
{
return getUsername() != null && password != null;
}
public boolean isInvalid()
{
return invalid;
}
public void invalidate()
{
invalid = true;
}
public void clear()
{
username = null;
password = null;
}
/**
* Creates a callback handler that can handle a standard username/password
* callback, using the username and password properties.
*/
public CallbackHandler createCallbackHandler()
{
return new CallbackHandler()
{
public void handle(Callback[] callbacks)
throws IOException, UnsupportedCallbackException
{
for (int i=0; i < callbacks.length; i++)
{
if (callbacks[i] instanceof NameCallback)
{
( (NameCallback) callbacks[i] ).setName(getUsername());
}
else if (callbacks[i] instanceof PasswordCallback)
{
( (PasswordCallback) callbacks[i] ).setPassword( getPassword() != null ?
getPassword().toCharArray() : null );
}
else
{
log.warn("Unsupported callback " + callbacks[i]);
}
}
}
};
}
}