package restx.security;
import com.google.common.base.Joiner;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import restx.*;
import restx.factory.Component;
import restx.http.HttpStatus;
import java.io.IOException;
/**
* User: xavierhanin
* Date: 2/7/13
* Time: 9:33 AM
*/
@Component
public class CORSRoute extends CORSHandler implements RestxRoute, RestxHandler {
private static final Logger logger = LoggerFactory.getLogger(CORSRoute.class);
private final Iterable<CORSAuthorizer> authorizers;
public CORSRoute(Iterable<CORSAuthorizer> authorizers) {
this.authorizers = authorizers;
}
@Override
public Optional<RestxHandlerMatch> match(RestxRequest req) {
Optional<String> acrMethod = req.getHeader("Access-Control-Request-Method");
if ("OPTIONS".equals(req.getHttpMethod())
&& acrMethod.isPresent()) {
Optional<String> origin = req.getHeader("Origin");
CORS cors = CORS.check(authorizers, req, origin.get(), acrMethod.get(), req.getRestxPath());
if (cors.isAccepted()) {
return Optional.of(new RestxHandlerMatch(new StdRestxRequestMatch("*", req.getRestxPath(),
ImmutableMap.<String, String>of(), ImmutableMap.of("cors", cors)), this));
} else {
logger.info("Unauthorized pre-flight CORS request; Origin={}; Method={}", origin.get(), acrMethod.get());
return unauthorized(req);
}
}
return Optional.absent();
}
@Override
public void handle(RestxRequestMatch match, RestxRequest req, RestxResponse resp, RestxContext ctx) throws IOException {
AcceptedCORS cors = (AcceptedCORS) match.getOtherParams().get("cors");
resp.setHeader("Access-Control-Allow-Origin", cors.getOrigin());
if (!cors.getHeaders().isEmpty()) {
resp.setHeader("Access-Control-Allow-Headers", Joiner.on(", ").join(cors.getHeaders()));
}
if (!cors.getMethods().isEmpty()) {
resp.setHeader("Access-Control-Allow-Methods", Joiner.on(", ").join(cors.getMethods()));
}
if (cors.getAllowCredentials().or(false)) {
resp.setHeader("Access-Control-Allow-Credentials", "true");
}
resp.setHeader("Access-Control-Max-Age", String.valueOf(cors.getMaxAge()));
}
public String toString() {
return "CORSRoute";
}
}