package net.sourceforge.javautil.developer.web.unit.mockserver;
import java.io.IOException;
import java.security.Principal;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import net.sourceforge.javautil.common.exception.ThrowableManagerRegistry;
import net.sourceforge.javautil.developer.web.unit.mockserver.http.MockHttpServletContext;
import net.sourceforge.javautil.developer.web.unit.mockserver.http.MockHttpServletRequest;
import net.sourceforge.javautil.web.server.WebServer;
import net.sourceforge.javautil.web.server.WebServerHostValve;
import net.sourceforge.javautil.web.server.WebServerHostValveContext;
import net.sourceforge.javautil.web.server.application.WebApplication;
import net.sourceforge.javautil.web.server.application.WebApplicationAuthenticator;
import net.sourceforge.javautil.web.server.application.WebApplicationDeploymentContext;
import net.sourceforge.javautil.web.server.application.WebApplicationRequest;
import net.sourceforge.javautil.web.server.application.WebApplicationResponse;
import net.sourceforge.javautil.web.server.application.impl.WebApplicationAuthenticationContextBase;
import net.sourceforge.javautil.web.server.application.impl.WebApplicationRequestBase;
import net.sourceforge.javautil.web.server.application.impl.WebApplicationRequestContextAbstract;
import net.sourceforge.javautil.web.server.application.impl.WebApplicationResponseBase;
import net.sourceforge.javautil.web.server.descriptor.IWebXml;
import net.sourceforge.javautil.web.server.descriptor.IWebXmlResourceCollection;
import net.sourceforge.javautil.web.server.descriptor.IWebXmlSecurityConstraint;
/**
* The root for valve processing with {@link MockServer}'s.
*
* @author elponderador
* @author $Author$
* @version $Id$
*/
public class MockServerValve implements WebServerHostValve {
protected final WebServer server;
protected final WebApplicationDeploymentContext context;
protected final String authenticationType;
protected final WebApplicationAuthenticator authenticator;
protected final WebApplicationRequest request;
protected final WebApplicationResponse response;
public MockServerValve(WebServer server, WebApplicationDeploymentContext context, ServletRequest request, ServletResponse response) {
this.server = server;
this.context = context;
this.request = new WebApplicationRequestBase(request);
this.response = new WebApplicationResponseBase(response);
if (context.getApplication().getWebXml().getLoginConfig() != null) {
this.authenticationType = context.getApplication().getWebXml().getLoginConfig().getAuthMethod();
} else
this.authenticationType = null;
if (this.authenticationType != null) {
Map<String, WebApplicationAuthenticator> authenticators = server.getDefaultAuthenticatorSet(context.getApplication());
for (WebApplicationAuthenticator authenticator : context.getApplication().getAuthenticators())
authenticators.put(authenticator.getName(), authenticator);
this.authenticator = authenticators.get(this.authenticationType);
if (this.authenticator == null)
throw new IllegalArgumentException("Authentication type not supported: " + this.authenticationType);
} else
this.authenticator = null;
}
public void invoke(WebServerHostValveContext ctx) {
try {
if (this.authenticate(ctx)) {
if (this.authenticator != null)
this.authenticator.invoke(new MockServerRequestContext(this, ctx));
else
ctx.next();
}
} catch (IOException e) {
throw ThrowableManagerRegistry.caught(e);
}
}
/**
* @param ctx The valve context
* @return True if this request is authenticated or allowed, otherwise false
* @throws IOException
*/
private boolean authenticate (WebServerHostValveContext ctx) throws IOException {
if (this.authenticator != null) {
boolean na = false;
MockServletContext sc = (MockServletContext) ctx.getServletContext();
String path = ((HttpServletRequest)ctx.getRequest().getServletRequest()).getServletPath();
String method = ((HttpServletRequest)ctx.getRequest().getServletRequest()).getMethod();
String role = null;
List<? extends IWebXmlSecurityConstraint> constraints = this.context.getApplication().getWebXml().getSecurityConstraints();
for (IWebXmlSecurityConstraint constraint : constraints) {
role = constraint.getAuthConstraint() == null ? null : constraint.getAuthConstraint().getRoleName();
for (IWebXmlResourceCollection resource : constraint.getResourceCollections()) {
for (String pattern : resource.getPatterns()) {
if (sc.matches(path, pattern)) {
na = true;
break;
}
}
}
}
if (na) {
boolean authed = this.authenticator.authenticate(new WebApplicationAuthenticationContextBase(new MockServerRequestContext(this, ctx),
this.context.getApplication().getWebXml().getLoginConfig()));
Principal principal = ((MockHttpServletRequest)ctx.getRequest().getServletRequest()).getUserPrincipal();
if (authed && principal != null && role != null) {
return context.getApplication().hasRole(context.getServletContext(), principal, role);
}
return authed;
}
}
return true;
}
}