package net.unicon.cas.addons.authentication.principal;
import com.stormpath.sdk.account.Account;
import com.stormpath.sdk.resource.ResourceException;
import net.unicon.cas.addons.authentication.handler.StormpathAuthenticationHandler;
import net.unicon.cas.addons.support.ThreadSafe;
import org.jasig.cas.authentication.principal.Credentials;
import org.jasig.cas.authentication.principal.CredentialsToPrincipalResolver;
import org.jasig.cas.authentication.principal.Principal;
import org.jasig.cas.authentication.principal.UsernamePasswordCredentials;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* An implementation of {@link org.jasig.cas.authentication.principal.CredentialsToPrincipalResolver}
* that resolves instances of {@link StormpathPrincipal} from provided {@link org.jasig.cas.authentication.principal.UsernamePasswordCredentials}
* <p/>
* Note that this implementation makes a remote HTTP call to Stormapth cloud to authenticate the credential and therefore
* retrieve an instance of an {@link com.stormpath.sdk.account.Account}. Thus, 2 Stormpath remote authentication calls are made -
* one is during authentication by {@link net.unicon.cas.addons.authentication.handler.StormpathAuthenticationHandler} and
* one is during <code>Account</code> retrieval by this class.
*
* @author Dmitriy Kopylenko
* @author Unicon, inc.
* @since 1.4
*/
@ThreadSafe
public class StormpathPrincipalResolver implements CredentialsToPrincipalResolver {
private final StormpathAuthenticationHandler stormpathAuthenticationHandler;
private static final Logger logger = LoggerFactory.getLogger(StormpathPrincipalResolver.class);
public StormpathPrincipalResolver(StormpathAuthenticationHandler stormpathAuthenticationHandler) {
this.stormpathAuthenticationHandler = stormpathAuthenticationHandler;
}
@Override
public Principal resolvePrincipal(final Credentials credentials) {
final UsernamePasswordCredentials usernamePasswordCredentials = UsernamePasswordCredentials.class.cast(credentials);
try {
final Account account = this.stormpathAuthenticationHandler.authenticateAccount(usernamePasswordCredentials);
final Principal principal = new StormpathPrincipal(account);
logger.debug("Successfully resolved {}", principal);
return principal;
}
catch (Throwable e) {
logger.error("An exception is caught trying to access Stormpath cloud while resolving StormpathPrincipal: {} ", e.getMessage());
return null;
}
}
@Override
public boolean supports(final Credentials credentials) {
return credentials != null && UsernamePasswordCredentials.class.isAssignableFrom(credentials.getClass());
}
}