update
This commit is contained in:
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
|
||||
|
||||
|
|
1
pom.xml
1
pom.xml
|
@ -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…
Reference in New Issue