package org.josso.atlassian.seraph;
import com.atlassian.crowd.embedded.api.CrowdDirectoryService;
import com.atlassian.crowd.embedded.api.CrowdService;
import com.atlassian.crowd.embedded.impl.ImmutableUser;
import com.atlassian.jira.ComponentManager;
import com.atlassian.jira.user.util.OSUserConverter;
import com.atlassian.seraph.auth.AuthenticatorException;
import com.atlassian.seraph.auth.DefaultAuthenticator;
import com.atlassian.seraph.config.SecurityConfig;
import com.atlassian.crowd.embedded.api.Directory;
import org.apache.log4j.Logger;
import org.josso.gateway.SSONameValuePair;
import org.josso.gateway.identity.SSOUser;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.StringWriter;
import java.security.Principal;
import java.util.List;
import java.util.Map;
/**
* @author <a href=mailto:sgonzalez@atricore.org>Sebastian Gonzalez Oyuela</a>
*/
public class JOSSOJiraAuthenticator extends DefaultAuthenticator {
private static final Logger logger = Logger.getLogger(JOSSOJiraAuthenticator.class);
private CrowdDirectorySelectorStrategy dirSelector;
private String lookupCrowdDirStrategyType;
private Map<String, String> params;
@Override
public void init(Map<String, String> params, SecurityConfig config) {
super.init(params, config);
this.params = params;
lookupCrowdDirStrategyType = params.get("directory.lookup.strategy");
if (lookupCrowdDirStrategyType == null) {
lookupCrowdDirStrategyType = FixedCrowdDirectorySelectorFactory.class.getName();
logger.info("Using default Directory Selector:" + lookupCrowdDirStrategyType);
}
}
@Override
protected Principal getUser(String username) {
return OSUserConverter.convertToOSUser(getCrowdService().getUser(username));
}
@Override
protected boolean authenticate(Principal principal, String s) throws AuthenticatorException {
throw new UnsupportedOperationException("User is always authenticated by JOSSO");
}
@Override
public Principal getUser(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
Principal user = httpServletRequest.getUserPrincipal();
// Addapt SSOUser to Crowd user ...
if (user instanceof SSOUser ) {
SSOUser ssoUser = (SSOUser) httpServletRequest.getUserPrincipal();
// Addapt SSO User to Crowd user
String email = null;
String displayName = ssoUser.getName();
for (SSONameValuePair ssoProp : ssoUser.getProperties()) {
if (ssoProp.getName().contains("email"))
email = ssoProp.getValue();
if (ssoProp.getName().equals("displayName"))
displayName = ssoProp.getValue();
}
// Lookup proper user directory
Directory dir = getDirSelector().lookupDirectory(ssoUser);
ImmutableUser crowdUser = new ImmutableUser(dir.getId(), ssoUser.getName(), displayName, email, true);
user = OSUserConverter.convertToOSUser(crowdUser);
authoriseUserAndEstablishSession(httpServletRequest, httpServletResponse, user);
} else {
// If we don't have a valid SSO Session, return NULL!!!
String ssoSessionId = (String) httpServletRequest.getAttribute("org.josso.agent.ssoSessionid");
if (ssoSessionId == null || "".equals(ssoSessionId) || "-".equals(ssoSessionId)) {
super.removePrincipalFromSessionContext(httpServletRequest);
return null;
} else {
user = super.getUser(httpServletRequest, httpServletResponse);
}
}
return user;
}
@Override
public boolean login(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, String s, String s1, boolean b) throws AuthenticatorException {
throw new UnsupportedOperationException("JOSSO Agent must perform 'login' operation");
}
@Override
public boolean logout(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws AuthenticatorException {
throw new UnsupportedOperationException("JOSSO Agent must perform 'logout' operation");
}
private CrowdService getCrowdService() {
CrowdService svc = (CrowdService) ComponentManager.getComponent(CrowdService.class);
return svc;
}
private CrowdDirectoryService getCrowdDirectoryService() {
CrowdDirectoryService svc = (CrowdDirectoryService) ComponentManager.getComponent(CrowdDirectoryService.class);
return svc;
}
public CrowdDirectorySelectorStrategy getDirSelector() {
if (dirSelector == null) {
synchronized (this) {
if (dirSelector == null) {
dirSelector = CrowdDirectorySelectorFactory.getInstance(lookupCrowdDirStrategyType).getStrategy(params, getCrowdDirectoryService());
}
}
}
return dirSelector;
}
}