master
Lucio Lelii 2 years ago
parent 08b3cd590a
commit 454533abcd

@ -13,6 +13,10 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- Added SecretManagerProvider thread local from authorization-utils [#22871]
- Added Linux distribution version [#22933]
## [v3.1.3] - 2022-03-21
- fixed bug on policies
## [v3.1.2] - 2022-01-19

@ -12,6 +12,7 @@
<groupId>org.gcube.core</groupId>
<artifactId>common-smartgears</artifactId>
<version>4.0.0-SNAPSHOT</version>
<name>SmartGears</name>
<dependencyManagement>

@ -176,8 +176,6 @@ public class HttpController extends HttpExtension {
case OPTIONS:
resource.doOptions(request, response);
break;
case TRACE:
resource.doTrace(request, response);
}
}

@ -11,7 +11,7 @@ import javax.xml.bind.annotation.XmlAttribute;
import org.gcube.common.validator.annotations.NotEmpty;
import org.gcube.smartgears.configuration.application.Exclude;
import org.gcube.smartgears.context.application.ApplicationContext;
import javax.ws.rs.HttpMethod;
/**
* An {@link ApplicationExtension} that implements the {@link HttpServlet} interface
*
@ -27,7 +27,25 @@ public abstract class HttpExtension extends HttpServlet implements ApplicationEx
*
*/
public static enum Method {
GET, PUT, POST, HEAD, DELETE, OPTIONS, TRACE
GET(HttpMethod.GET),
PUT(HttpMethod.PUT),
POST(HttpMethod.POST),
HEAD(HttpMethod.HEAD),
DELETE(HttpMethod.DELETE),
OPTIONS(HttpMethod.OPTIONS);
private String value;
private Method(String value) {
this.value = value;
}
public String getValue() {
return this.value;
}
}
@XmlAttribute @NotEmpty

@ -99,4 +99,4 @@ public class RequestContextRetriever extends RequestHandler {
SecretManagerProvider.instance.reset();
}
}
}

@ -1,21 +1,12 @@
package org.gcube.smartgears.handlers.application.request;
import static org.gcube.common.authorization.client.Constants.authorizationService;
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.List;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import org.gcube.common.authorization.library.PolicyUtils;
import org.gcube.common.authorization.library.policies.Policy;
import org.gcube.common.authorization.library.policies.User2ServicePolicy;
import org.gcube.common.authorization.library.policies.UserEntity;
import org.gcube.common.authorization.library.provider.SecurityTokenProvider;
import org.gcube.common.authorization.library.provider.ServiceIdentifier;
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;
@ -26,7 +17,6 @@ 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.utils.Utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -83,30 +73,30 @@ public class RequestValidator extends RequestHandler {
private void validateScopeCall() {
String scope = ScopeProvider.instance.get();
String context = SecretManagerProvider.instance.get().getContext();
if (scope == null) {
if (context == null) {
log.warn("rejecting unscoped call to {}",appContext.name());
invalid_request_error.fire("call is unscoped");
}
ScopeBean bean = new ScopeBean(scope);
ScopeBean bean = new ScopeBean(context);
ContainerConfiguration conf = appContext.container().configuration();
if (!conf.allowedContexts().contains(scope) &&
!(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(),scope,appContext.container().configuration().allowedContexts());
invalid_request_error.fire(appContext.name()+" cannot be called in scope "+scope);
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){
String token = SecurityTokenProvider.instance.get();
String context = SecretManagerProvider.instance.get().getContext();
if (token == null && context==null){
log.warn("rejecting call to {}, authorization required",appContext.name(),token);
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");
}
}
@ -117,40 +107,10 @@ public class RequestValidator extends RequestHandler {
}
private void validatePolicy(String scope, RequestEvent call){
log.info("accessing policy validator in scope {} ", scope);
ServiceIdentifier serviceIdentifier = Utils.getServiceInfo(call.context()).getServiceIdentifier();
String callerId = SecretManagerProvider.instance.get().getUser().getUsername();
List<Policy> policies = null;
try {
policies = authorizationService().getPolicies(scope);
}catch (Exception e) {
invalid_request_error.fire("error contating authorization for polices");
}
for (Policy policy: policies) {
log.debug("policy: {}", policy.getPolicyAsString() );
if (PolicyUtils.isPolicyValidForClient(policy.getServiceAccess(), serviceIdentifier )) {
boolean toReject = false;
UserEntity entity = (((User2ServicePolicy) policy).getEntity());
if (entity.getIdentifier()!=null)
toReject = entity.getIdentifier().equals(callerId);
else if (entity.getExcludes().isEmpty())
toReject = true;
else toReject = !entity.getExcludes().contains(callerId);
if (toReject) {
log.error("rejecting call to {} : {} is not allowed to contact the service ",appContext.name(), callerId);
RequestError.request_not_authorized_error.fire("rejecting call to "+appContext.name()+" for polices: "+callerId+" is not allowed to contact the service: "+serviceIdentifier.getServiceName() );
}
}
}
//TODO: must be re-think
}
}

@ -1,6 +1,7 @@
package app;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -10,6 +11,7 @@ import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;
import javax.ws.rs.HttpMethod;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Invocation.Builder;
@ -17,6 +19,7 @@ import javax.ws.rs.client.Invocation.Builder;
import org.gcube.common.authorization.library.provider.AuthorizationProvider;
import org.gcube.common.authorization.library.provider.UserInfo;
import org.gcube.common.authorization.library.utils.Caller;
import org.gcube.smartgears.extensions.HttpExtension.Method;
import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.client.ClientResponse;
import org.glassfish.jersey.logging.LoggingFeature;
@ -63,12 +66,12 @@ public class Request {
}
public Request with(String name, String value) {
this.headers.put(name, value);
this.headers.put(name, Collections.singletonList(value));
return this;
}
public Request using(String method) {
this.method=method;
public Request using(Method method) {
this.method=method.getValue();
return this;
}
@ -98,7 +101,7 @@ public class Request {
class Box {
volatile Exception failure;
volatile WebApplicationException failure;
volatile ClientResponse response;
}
@ -143,13 +146,13 @@ public class Request {
//throws an exception if there response has error status
if (response.getStatus()>300)
throw new Exception(response.getStatus());
throw new WebApplicationException(response.getStatus());
box.response=response;
}
} catch (Exception t) {
} catch (WebApplicationException t) {
box.failure=t;
}
@ -178,7 +181,7 @@ public class Request {
path = (path.isEmpty() || path.startsWith("/"))?path:"/"+path;
return "http://localhost:" + port+ "/" + context_root+path;
return "http://localhost:" + port+ "/" + TestUtils.context_root+path;
}
}

@ -27,14 +27,13 @@ import org.gcube.smartgears.configuration.container.ContainerConfiguration;
import org.gcube.smartgears.context.application.ApplicationContext;
import org.gcube.smartgears.managers.ContainerManager;
import org.gcube.smartgears.provider.ProviderFactory;
import org.glassfish.jersey.client.ClientResponse;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.StringAsset;
import org.jboss.shrinkwrap.api.exporter.ZipExporter;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.jboss.shrinkwrap.impl.base.path.BasicPath;
import com.sun.jersey.api.client.ClientResponse;
import utils.TestProvider;
import utils.TestUtils;
@ -308,7 +307,7 @@ public class SomeApp {
*/
public String send(Request call) {
return call.make(port()).getEntity(String.class);
return (String) call.make(port()).getEntity();
}
/**

@ -14,6 +14,8 @@ import static utils.TestUtils.scope;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import javax.ws.rs.WebApplicationException;
import org.gcube.common.authorization.library.provider.SecurityTokenProvider;
import org.gcube.smartgears.Constants;
import org.gcube.smartgears.configuration.application.Exclude;
@ -24,7 +26,6 @@ import org.junit.Test;
import app.SomeApp;
import com.sun.jersey.api.client.UniformInterfaceException;
public class CallValidationTest {
@ -52,7 +53,7 @@ public class CallValidationTest {
try {
app.send(request());
}
catch(UniformInterfaceException e) {
catch(WebApplicationException e) {
assertEquals(application_unavailable_error.code(), e.getResponse().getStatus());
}
@ -62,7 +63,7 @@ public class CallValidationTest {
try {
app.send(request());
}
catch(UniformInterfaceException e) {
catch(WebApplicationException e) {
assertEquals(application_failed_error.code(), e.getResponse().getStatus());
}
@ -82,7 +83,7 @@ public class CallValidationTest {
app.send(request().inScope(null));; //call in no scope
fail();
}
catch(UniformInterfaceException e) {
catch(WebApplicationException e) {
assertEquals(request_not_authorized_error.code(), e.getResponse().getStatus());
}
@ -101,7 +102,7 @@ public class CallValidationTest {
app.send(request().inScope("/bad/scope")); //call in no scope
fail();
}
catch(UniformInterfaceException e) {
catch(WebApplicationException e) {
assertEquals(invalid_request_error.code(), e.getResponse().getStatus());
}

@ -1,31 +1,42 @@
package test.application;
import static app.Request.*;
import static org.gcube.smartgears.Constants.*;
import static org.gcube.smartgears.extensions.ApiResource.*;
import static org.gcube.smartgears.extensions.HttpExtension.Method.*;
import static org.gcube.smartgears.handlers.application.request.RequestError.*;
import static org.junit.Assert.*;
import static app.Request.request;
import static org.gcube.smartgears.Constants.accept;
import static org.gcube.smartgears.Constants.allow;
import static org.gcube.smartgears.Constants.content_type;
import static org.gcube.smartgears.extensions.ApiResource.handles;
import static org.gcube.smartgears.extensions.ApiResource.method;
import static org.gcube.smartgears.extensions.HttpExtension.Method.GET;
import static org.gcube.smartgears.extensions.HttpExtension.Method.POST;
import static org.gcube.smartgears.extensions.HttpExtension.Method.PUT;
import static org.gcube.smartgears.handlers.application.request.RequestError.incoming_contenttype_unsupported_error;
import static org.gcube.smartgears.handlers.application.request.RequestError.method_unsupported_error;
import static org.gcube.smartgears.handlers.application.request.RequestError.outgoing_contenttype_unsupported_error;
import static org.gcube.smartgears.handlers.application.request.RequestError.resource_notfound_error;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.WebApplicationException;
import org.gcube.smartgears.Constants;
import org.gcube.smartgears.extensions.ApiResource;
import org.gcube.smartgears.extensions.ApiSignature;
import org.gcube.smartgears.extensions.HttpController;
import org.gcube.smartgears.extensions.HttpExtension;
import org.glassfish.jersey.client.ClientResponse;
import org.junit.Test;
import app.Request;
import app.SomeApp;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.UniformInterfaceException;
public class ControllerTest {
String name = "name";
@ -74,7 +85,7 @@ public class ControllerTest {
try {
app.send(request);
fail();
} catch (UniformInterfaceException e) {
} catch (WebApplicationException e) {
assertEquals(resource_notfound_error.code(), e.getResponse().getStatus());
}
}
@ -91,7 +102,7 @@ public class ControllerTest {
try {
app.send(request);
fail();
} catch (UniformInterfaceException e) {
} catch (WebApplicationException e) {
assertEquals(method_unsupported_error.code(), e.getResponse().getStatus());
assertNotNull(e.getResponse().getHeaders().toString(),e.getResponse().getHeaders().get(allow));
}
@ -109,7 +120,7 @@ public class ControllerTest {
try {
app.send(request);
fail();
} catch (UniformInterfaceException e) {
} catch (WebApplicationException e) {
assertEquals(outgoing_contenttype_unsupported_error.code(), e.getResponse().getStatus());
}
@ -127,7 +138,7 @@ public class ControllerTest {
try {
app.send(request);
fail();
} catch (UniformInterfaceException e) {
} catch (WebApplicationException e) {
assertEquals(outgoing_contenttype_unsupported_error.code(), e.getResponse().getStatus());
}
}
@ -189,7 +200,7 @@ public class ControllerTest {
try {
app.send(request);
fail();
} catch (UniformInterfaceException e) {
} catch (WebApplicationException e) {
assertEquals(incoming_contenttype_unsupported_error.code(), e.getResponse().getStatus());
}
}

@ -12,6 +12,7 @@ import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.ws.rs.WebApplicationException;
import javax.xml.bind.annotation.XmlRootElement;
import org.gcube.smartgears.Constants;
@ -24,8 +25,6 @@ import org.junit.Test;
import app.SomeApp;
import com.sun.jersey.api.client.UniformInterfaceException;
public class ExtensionsTest {
String name = "name";
@ -144,7 +143,7 @@ public class ExtensionsTest {
app.send(request().at(Constants.root_mapping+extension_path));
fail();
}
catch(UniformInterfaceException e) {
catch(WebApplicationException e) {
assertEquals(error.code(),e.getResponse().getStatus());
}
@ -177,9 +176,9 @@ public class ExtensionsTest {
app.send(request().at(Constants.root_mapping+extension_path).inScope(null));
fail();
}
catch(UniformInterfaceException e) {
catch(WebApplicationException e) {
assertEquals(e.getResponse().getEntity(String.class),invalid_request_error.code(),e.getResponse().getStatus());
assertEquals((String)e.getResponse().getEntity(),invalid_request_error.code(),e.getResponse().getStatus());
}
}
}

@ -8,6 +8,7 @@ import org.gcube.smartgears.lifecycle.application.ApplicationState;
import org.gcube.smartgears.lifecycle.container.ContainerState;
import org.gcube.smartgears.managers.ContainerManager;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
@ -15,7 +16,14 @@ import app.SomeApp;
public class ContainerLifecycleTest {
SomeApp app = new SomeApp();
SomeApp app;
@Before
public void init() {
app = new SomeApp();
}
@After
public void teardown() {

@ -18,7 +18,7 @@ import org.gcube.smartgears.handlers.application.ApplicationHandler;
public class TestUtils {
public static String location = "target/ghn-home";
public static String location = "/tmp/ghn-home";
public static String context_root = "test-app";
public static String context_root_path = "/" + context_root;
public static String servlet_name = "test";

Loading…
Cancel
Save