package org.simbasecurity.dwclient.dropwizard.credentials; import static com.yammer.dropwizard.assets.ResourceURL.*; import java.net.MalformedURLException; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.inject.Inject; import javax.inject.Named; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import org.eclipse.jetty.http.HttpHeaders; import org.eclipse.jetty.http.HttpMethods; import org.simbasecurity.common.constants.AuthenticationConstants; import org.simbasecurity.common.request.RequestUtil; import org.simbasecurity.dwclient.exception.IllegalArgumentDWSimbaException; import com.google.common.collect.Maps; import com.sun.jersey.core.util.Base64; import com.sun.jersey.spi.container.ContainerRequest; public class SimbaCredentialsFactory { private String simbaWebURL; @Inject public SimbaCredentialsFactory(@Named("simbaWebURL") String simbaWebURL) { this.simbaWebURL = simbaWebURL; } public SimbaCredentials create(ContainerRequest containerRequest) { return create(containerRequest, false); } public SimbaCredentials createForLogin(String username, String password) { Map<String, String> requestParameters = Maps.newHashMap(); addUsernameAndPasswordToRequestParams(username, password, requestParameters); Map<String, String> requestHeaders = Maps.newHashMap(); String emptyBecauseWeDontCareButSimbaDoes = ""; requestHeaders.put("user-agent", emptyBecauseWeDontCareButSimbaDoes); return new SimbaCredentials(requestParameters, requestHeaders, emptyBecauseWeDontCareButSimbaDoes, simbaWebURL, HttpMethods.POST, null, RequestUtil.HOST_SERVER_NAME, false, true, false, null); } private void addUsernameAndPasswordToRequestParams(String username, String password, Map<String, String> requestParameters) { requestParameters.put(AuthenticationConstants.USERNAME, username); requestParameters.put(AuthenticationConstants.PASSWORD, password); } public SimbaCredentials create(ContainerRequest containerRequest, boolean isLogoutRequest) { Map<String, String> requestParameters = toMap(containerRequest.getQueryParameters()); String auth = containerRequest.getHeaderValue(HttpHeaders.AUTHORIZATION); String ssotoken = containerRequest.getHeaderValue(org.simbasecurity.dwclient.dropwizard.http.HttpHeaders.X_SSO_TOKEN); boolean isLoginRequest = false; if (ssotoken == null && auth == null) { throw new WebApplicationException(Response.status(Response.Status.UNAUTHORIZED) .entity("Neither SSOToken, nor authorization header found on request") .type(MediaType.APPLICATION_JSON) .build()); } if (auth != null) { String[] lap = decode(auth); addUsernameAndPasswordToRequestParams(lap[0], lap[1], requestParameters); isLoginRequest = true; } Map<String, String> requestHeaders = toMap(containerRequest.getRequestHeaders()); try { return new SimbaCredentials(requestParameters, requestHeaders, appendTrailingSlash(containerRequest.getAbsolutePath().toURL()).toString(), simbaWebURL, containerRequest.getMethod(), ssotoken, RequestUtil.HOST_SERVER_NAME, false, isLoginRequest, isLogoutRequest, null); } catch (MalformedURLException e) { throw new IllegalArgumentDWSimbaException(e.getMessage()); } } private String[] decode(String auth) { if (auth.toLowerCase().startsWith("basic ")) { String[] usernamePassword = decodeBasic(auth); if (usernamePassword.length != 2) { throw new WebApplicationException(401); } return usernamePassword; } throw new UnsupportedOperationException("Only Basic Authentication supported so far"); } private String[] decodeBasic(String auth) { String digest = auth.substring(6); String decodedString = Base64.base64Decode(digest); return decodedString != null ? decodedString.split(":", 2) : null; } private <K, V> Map<K, V> toMap(Map<K, List<V>> map) { Map<K, V> result = new HashMap<K, V>(); for (Map.Entry<K, List<V>> entry : map.entrySet()) { List<V> list = entry.getValue(); if (list.size() > 0) { result.put(entry.getKey(), list.get(0)); } } return result; } }