common-smartgears/src/main/java/org/gcube/smartgears/handlers/application/request/RequestValidator.java

117 lines
3.5 KiB
Java

package org.gcube.smartgears.handlers.application.request;
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 javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import org.gcube.common.authorization.utils.manager.SecretManager;
import org.gcube.common.authorization.utils.manager.SecretManagerProvider;
import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.common.scope.impl.ScopeBean;
import org.gcube.common.scope.impl.ScopeBean.Type;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
@XmlRootElement(name = Constants.request_validation)
public class RequestValidator extends RequestHandler {
@XmlAttribute(required=false, name="oauth")
@Deprecated
boolean oauthCompatibility = false;
private static Logger log = LoggerFactory.getLogger(RequestValidator.class);
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();
validateAgainstLifecycle(call);
rejectUnauthorizedCalls(call);
if (appContext.container().configuration().mode()!=Mode.offline) {
validateScopeCall();
validatePolicy(ScopeProvider.instance.get(), call);
}
}
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");
}
ScopeBean bean = new ScopeBean(context);
ContainerConfiguration conf = appContext.container().configuration();
if (!conf.allowedContexts().contains(context) &&
!(conf.authorizeChildrenContext() && bean.is(Type.VRE)
&& conf.allowedContexts().contains(bean.enclosingScope().toString()) ) ) {
log.warn("rejecting call to {} in invalid context {}, allowed context are {}",appContext.name(),context,appContext.container().configuration().allowedContexts());
invalid_request_error.fire(appContext.name()+" cannot be called in scope "+context);
}
}
private void rejectUnauthorizedCalls(RequestEvent call){
SecretManager secretManager = SecretManagerProvider.instance.get();
if (secretManager.getCurrentSecretHolder().getSecrets().size()>0){
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(String scope, RequestEvent call){
//TODO: must be re-think
}
}