144 lines
4.4 KiB
Java
144 lines
4.4 KiB
Java
package org.gcube.smartgears.handlers.application.request;
|
|
|
|
import static org.gcube.smartgears.Constants.token_header;
|
|
import static org.gcube.smartgears.handlers.application.request.RequestError.application_failed_error;
|
|
import static org.gcube.smartgears.handlers.application.request.RequestError.application_unavailable_error;
|
|
import static org.gcube.smartgears.handlers.application.request.RequestError.invalid_request_error;
|
|
|
|
import java.util.Set;
|
|
|
|
import org.gcube.common.security.ContextBean;
|
|
import org.gcube.common.security.ContextBean.Type;
|
|
import org.gcube.common.security.providers.SecretManagerProvider;
|
|
import org.gcube.common.security.secrets.AccessTokenSecret;
|
|
import org.gcube.common.security.secrets.GCubeSecret;
|
|
import org.gcube.common.security.secrets.Secret;
|
|
import org.gcube.smartgears.Constants;
|
|
import org.gcube.smartgears.configuration.Mode;
|
|
import org.gcube.smartgears.configuration.container.ContainerConfiguration;
|
|
import org.gcube.smartgears.context.application.ApplicationContext;
|
|
import org.gcube.smartgears.handlers.application.RequestEvent;
|
|
import org.gcube.smartgears.handlers.application.RequestHandler;
|
|
import org.gcube.smartgears.handlers.application.ResponseEvent;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
public class RequestValidator extends RequestHandler {
|
|
|
|
private static Logger log = LoggerFactory.getLogger(RequestValidator.class);
|
|
|
|
private static final String BEARER_AUTH_PREFIX ="Bearer";
|
|
|
|
private ApplicationContext appContext;
|
|
|
|
@Override
|
|
public String getName() {
|
|
return Constants.request_validation;
|
|
}
|
|
|
|
@Override
|
|
public void handleRequest(RequestEvent call) {
|
|
|
|
log.trace("executing request validator ON REQUEST");
|
|
|
|
appContext = call.context();
|
|
|
|
SecretManagerProvider.instance.set(getSecret(call));
|
|
|
|
validateAgainstLifecycle(call);
|
|
|
|
rejectUnauthorizedCalls(call);
|
|
|
|
if (appContext.container().configuration().mode()!=Mode.offline) {
|
|
validateScopeCall();
|
|
validatePolicy(call);
|
|
}
|
|
|
|
}
|
|
|
|
@Override
|
|
public void handleResponse(ResponseEvent e) {
|
|
log.debug("resetting all the Thread local for this call.");
|
|
SecretManagerProvider.instance.reset();
|
|
}
|
|
|
|
|
|
private void validateAgainstLifecycle(RequestEvent call) {
|
|
|
|
switch(appContext.lifecycle().state()) {
|
|
|
|
case stopped :
|
|
application_unavailable_error.fire(); break;
|
|
|
|
case failed:
|
|
application_failed_error.fire(); break;
|
|
|
|
default:
|
|
//nothing to do, but avoids warnings
|
|
}
|
|
|
|
}
|
|
|
|
private void validateScopeCall() {
|
|
|
|
String context = SecretManagerProvider.instance.get().getContext();
|
|
|
|
if (context == null) {
|
|
log.warn("rejecting unscoped call to {}",appContext.name());
|
|
invalid_request_error.fire("call is unscoped");
|
|
}
|
|
|
|
ContextBean bean = new ContextBean(context);
|
|
|
|
ContainerConfiguration conf = appContext.container().configuration();
|
|
Set<String> allowedContexts =conf.authorizationProvider().getContexts();
|
|
if (!allowedContexts.contains(context) &&
|
|
!(conf.authorizeChildrenContext() && bean.is(Type.VRE)
|
|
&& allowedContexts.contains(bean.enclosingScope().toString()) ) ) {
|
|
log.warn("rejecting call to {} in invalid context {}, allowed context are {}",appContext.name(),context,allowedContexts);
|
|
invalid_request_error.fire(appContext.name()+" cannot be called in scope "+context);
|
|
}
|
|
}
|
|
|
|
private void rejectUnauthorizedCalls(RequestEvent call){
|
|
|
|
Secret secret = SecretManagerProvider.instance.get();
|
|
|
|
if (secret == null){
|
|
log.warn("rejecting call to {}, authorization required",appContext.name());
|
|
RequestError.request_not_authorized_error.fire(appContext.name()+": authorization required");
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return getName();
|
|
}
|
|
|
|
private void validatePolicy(RequestEvent call){
|
|
//TODO: must be rethought
|
|
}
|
|
|
|
private Secret getSecret(RequestEvent call){
|
|
String token = call.request().getParameter(token_header)==null? call.request().getHeader(token_header):call.request().getParameter(token_header);
|
|
String authHeader = call.request().getHeader(Constants.authorization_header);
|
|
|
|
log.trace("authorization header is {}",authHeader);
|
|
log.trace("token header is {}", token);
|
|
|
|
String accessToken = null;
|
|
if (authHeader!=null && !authHeader.isEmpty())
|
|
if (authHeader.startsWith(BEARER_AUTH_PREFIX))
|
|
accessToken = authHeader.substring(BEARER_AUTH_PREFIX.length()).trim();
|
|
|
|
Secret secret = null;
|
|
if (accessToken!=null)
|
|
secret = new AccessTokenSecret(accessToken);
|
|
else if (token!=null)
|
|
secret = new GCubeSecret(token);
|
|
return secret;
|
|
}
|
|
|
|
|
|
}
|