config validation on Credential was not working

master
lucio 2 months ago
parent e193c80d11
commit 4d060fbb54

@ -17,7 +17,7 @@
<dependency>
<groupId>org.gcube.distribution</groupId>
<artifactId>gcube-bom</artifactId>
<version>3.0.0-SNAPSHOT</version>
<version>3.0.1-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
@ -25,7 +25,6 @@
</dependencyManagement>
<properties>
<tomcat.version>8.0.42</tomcat.version>
<jersey.version>2.25.1</jersey.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
@ -39,7 +38,6 @@
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.9.10</version>
</dependency>
<dependency>
<groupId>org.yaml</groupId>
@ -54,7 +52,7 @@
<dependency>
<groupId>org.gcube.common</groupId>
<artifactId>health-api</artifactId>
<version>1.0.0-SNAPSHOT</version>
<version>[1.0.0-SNAPSHOT, 2.0.0-SNAPSHOT)</version>
</dependency>
<!-- gCube Jackson -->
<dependency>
@ -122,14 +120,6 @@
<artifactId>micrometer-registry-prometheus</artifactId>
<version>1.9.0</version>
</dependency>
<!-- ***************** test ******************* -->
<dependency>
<groupId>org.jboss.shrinkwrap.resolver</groupId>
<artifactId>shrinkwrap-resolver-depchain</artifactId>
<version>2.0.0-beta-2</version>
<type>pom</type>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.tomcat/tomcat-catalina -->
<dependency>
<groupId>org.apache.tomcat</groupId>
@ -137,30 +127,6 @@
<version>${tomcat.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>${tomcat.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>2.25.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-logging-log4j</artifactId>
<version>${tomcat.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<version>${tomcat.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>

@ -44,6 +44,8 @@ public class Bootstrap implements ServletContainerInitializer {
public Bootstrap() {
log.info("bootstrap started the container");
if (smartgearsHasStarted)
return;
@ -61,6 +63,8 @@ public class Bootstrap implements ServletContainerInitializer {
ApplicationManager appManager = new ApplicationManager();
log.info("check if is managed @ {}", application.getContextPath());
//act only on resources
if (isResource(application)) {
@ -82,7 +86,7 @@ public class Bootstrap implements ServletContainerInitializer {
+ " (see cause)", t);
}
}
} else log.info("is not managed @ {}", application.getContextPath());
}
// helpers

@ -1,16 +1,16 @@
package org.gcube.smartgears.configuration;
import org.gcube.common.security.credentials.Credentials;
import org.gcube.common.validator.annotations.NotEmpty;
import org.gcube.common.validator.annotations.IsValid;
import org.gcube.common.validator.annotations.NotNull;
import org.gcube.smartgears.security.AuthorizationProviderFactory;
public class AuthorizationProviderConfiguration {
@NotNull @NotEmpty
@NotNull
AuthorizationProviderFactory<?> authProviderFactory;
@NotNull @NotEmpty
@NotNull @IsValid
Credentials credentials;
public AuthorizationProviderConfiguration(AuthorizationProviderFactory<?> authProviderFactory,

@ -244,7 +244,7 @@ public class ContainerConfiguration {
for (ValidationError error : validator.validate(this))
msgs.add(error.toString());
if (!msgs.isEmpty())
throw new IllegalStateException("invalid configuration: "+msgs);

@ -23,6 +23,7 @@ import org.gcube.smartgears.utils.Utils;
*/
public class RequestExceptionBarrier implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@ -31,10 +32,8 @@ public class RequestExceptionBarrier implements Filter {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException {
try {
chain.doFilter(request, response);
chain.doFilter(request, response);
} catch (Throwable t) {

@ -21,6 +21,7 @@ public abstract class AbstractHandler {
return this.getClass().getCanonicalName().equals(handler.getClass().getCanonicalName());
}
//so far, largely a placeholder for future cross-handler behaviour
}

@ -68,5 +68,7 @@ public abstract class RequestHandler extends AbstractHandler implements Applicat
*/
public void stop() {
}
}

@ -41,7 +41,7 @@ public class RequestMetrics extends RequestHandler {
Metrics.timer(HTTP_REQUEST_METRICS_NAME, "status", statusCode).record(Duration.ofMillis(System.currentTimeMillis() - startCallThreadLocal.get()));
startCallThreadLocal.remove();
}catch(Throwable t) {
log.warn("error getting Metrics",t);
log.warn("error setting Metrics",t);
}
}

@ -191,8 +191,6 @@ public class ApplicationManager {
FilterRegistration.Dynamic filter = app.addFilter(name + "-filter-"+mapping.replaceAll("/", ""), requestFilter);
log.trace("filter {} for requestfilter {} in contextPath {} is null ?? {} ",name ,requestFilter, mapping, (filter==null));
filter.addMappingForUrlPatterns(null, false, mapping);
}
}

@ -54,8 +54,8 @@ public class ContainerManager {
this.context = context;
try {
if (context.configuration().mode()!=Mode.offline)
validateContainer(context);
@ -65,18 +65,17 @@ public class ContainerManager {
log.trace("managing container lifecycle with {}", handlers);
startHandlers(handlers);
context.lifecycle().moveTo(active);
return context;
}
catch(RuntimeException e) {
} catch (RuntimeException e) {
log.error("cannot manage container (see cause)",e);
log.error("cannot manage container (see cause)", e);
if (context!=null)
if (context != null)
context.lifecycle().moveTo(failed);
throw e;
@ -84,12 +83,11 @@ public class ContainerManager {
}
private void saveContainerState() {
File file = context.persistenceWriter().file(container_profile_file_path);
try(ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file))){
File file = context.persistenceWriter().file(container_profile_file_path);
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file))) {
oos.writeObject(context.id());
}catch (Exception e) {
} catch (Exception e) {
log.error("error serializing cointainer state");
throw new RuntimeException(e);
}
@ -97,40 +95,40 @@ public class ContainerManager {
}
private void validateContainer(ContainerContext context) {
//List<String> tokensToRemove = new ArrayList<String>();
// List<String> tokensToRemove = new ArrayList<String>();
context.configuration().validate();
Set<String> foundContexts;
try {
foundContexts = context.authorizationProvider().getContexts();
} catch (Exception e) {
log.error("error authorizing container",e);
throw new RuntimeException("error authorizing container, moving the container to failed",e);
}
log.error("error authorizing container", e);
throw new RuntimeException("error authorizing container, moving the container to failed", e);
}
if (foundContexts.isEmpty()){
if (foundContexts.isEmpty()) {
log.error("no valid contexts found, moving the container to failed");
throw new RuntimeException("no valid contexts found, moving the container to failed");
}
}
public void manage(ApplicationContext app) {
app.events().subscribe(this);
app.events().subscribe(this);
}
@Observes(value={ApplicationLifecycle.failure,ApplicationLifecycle.stop},kind=Kind.critical)
@Observes(value = { ApplicationLifecycle.failure, ApplicationLifecycle.stop }, kind = Kind.critical)
void monitorApplication(ApplicationLifecycle lifecycle) {
context.lifecycle().tryMoveTo(ContainerState.partActive);
}
@Observes(value=ContextEvents.ADD_CONTEXT_TO_CONTAINER,kind=Kind.critical)
@Observes(value = ContextEvents.ADD_CONTEXT_TO_CONTAINER, kind = Kind.critical)
void addContext(String scope) {
log.info("adding context {} event send", context);
context.events().fire(scope, ProfileEvents.addToContext);
}
@Observes(value=ContextEvents.REMOVE_CONTEXT_FROM_CONTAINER,kind=Kind.critical)
@Observes(value = ContextEvents.REMOVE_CONTEXT_FROM_CONTAINER, kind = Kind.critical)
void removeContext(String scope) {
log.info("removing context {} event send", context);
context.events().fire(scope, ProfileEvents.removeFromContext);
@ -145,18 +143,20 @@ public class ContainerManager {
stop(false);
}
/**
* Stops container management on remote request or container shutdown.
*
*/
public void stop(boolean shutdown) {
//two cases: stop-on-shutdown and stop-on-request, some listeners will be selective about this,
// two cases: stop-on-shutdown and stop-on-request, some listeners will be
// selective about this,
//shutdown is triggered by probe app, which is notified among other apps
//if other app have been already notified, the container may already be part-active.
//apps still to notify will listen only on stop, hence won't react to this but will go down when their turn arrives.
// shutdown is triggered by probe app, which is notified among other apps
// if other app have been already notified, the container may already be
// part-active.
// apps still to notify will listen only on stop, hence won't react to this but
// will go down when their turn arrives.
if (context == null)
return;
@ -165,26 +165,23 @@ public class ContainerManager {
try {
context.lifecycle().tryMoveTo(shutdown?down:stopped);
context.lifecycle().tryMoveTo(shutdown ? down : stopped);
stopHandlers();
//no further reactions
// no further reactions
log.info("stopping container events");
context.events().stop();
Utils.scheduledServicePool.shutdownNow();
}
catch (RuntimeException e) {
} catch (RuntimeException e) {
log.warn("cannot stop container management (see cause)", e);
}
}
//helpers
// helpers
private void startHandlers(List<ContainerHandler> handlers) {
@ -201,7 +198,6 @@ public class ContainerManager {
}
}
private void stopHandlers() {
if (pipeline == null)
@ -214,46 +210,32 @@ public class ContainerManager {
returnPipeline.forward(new ContainerLifecycleEvent.Stop(context));
}
/*
private void loadKeyForToken(List<String> tokens) {
String initialToken = SecurityTokenProvider.instance.get();
//TODO: change this
String filePath = "/tmp/keys";
File PathDirs = new File(filePath+"/");
PathDirs.mkdirs();
try{
for (String token : tokens) {
try{
SecurityTokenProvider.instance.set(token);
File key = authProvider.getSymmKey(filePath);
log.trace("loading key {} file name ",key.getAbsolutePath());
log.trace("loaded key {} file name ",key.getAbsolutePath());
}catch(Exception e){
log.warn("error loading key for token {}", token, e);
}
}
loadFileIntoClasspath(PathDirs);
}finally{
SecurityTokenProvider.instance.set(initialToken);
}
}
private void loadFileIntoClasspath(File file){
try {
URL url = file.toURI().toURL();
ClassLoader currentClassloader = Thread.currentThread().getContextClassLoader().getParent()==null?
Thread.currentThread().getContextClassLoader() : Thread.currentThread().getContextClassLoader().getParent();
URLClassLoader classLoader = (URLClassLoader)currentClassloader;
Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
method.setAccessible(true);
method.invoke(classLoader, url);
} catch (Exception ex) {
log.error("error loading file into classpath",ex);
}
}
*/
/*
* private void loadKeyForToken(List<String> tokens) { String initialToken =
* SecurityTokenProvider.instance.get();
*
* //TODO: change this String filePath = "/tmp/keys"; File PathDirs = new
* File(filePath+"/"); PathDirs.mkdirs(); try{ for (String token : tokens) {
* try{ SecurityTokenProvider.instance.set(token); File key =
* authProvider.getSymmKey(filePath);
* log.trace("loading key {} file name ",key.getAbsolutePath());
* log.trace("loaded key {} file name ",key.getAbsolutePath()); }catch(Exception
* e){ log.warn("error loading key for token {}", token, e); } }
* loadFileIntoClasspath(PathDirs); }finally{
* SecurityTokenProvider.instance.set(initialToken); } }
*
*
* private void loadFileIntoClasspath(File file){ try { URL url =
* file.toURI().toURL();
*
* ClassLoader currentClassloader =
* Thread.currentThread().getContextClassLoader().getParent()==null?
* Thread.currentThread().getContextClassLoader() :
* Thread.currentThread().getContextClassLoader().getParent();
*
* URLClassLoader classLoader = (URLClassLoader)currentClassloader; Method
* method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
* method.setAccessible(true); method.invoke(classLoader, url); } catch
* (Exception ex) { log.error("error loading file into classpath",ex); } }
*/
}

@ -79,7 +79,7 @@ public class RequestManager implements Filter {
ApplicationPipeline<RequestHandler> pipeline = new ApplicationPipeline<RequestHandler>(filterHandlers);
log.trace("filtered handler for this call are {}", filterHandlers);
log.debug("filtered handler for this call are {}", filterHandlers);
// create a per-request context with temporary properties
ApplicationContext ctx = new DefaultApplicationContext(context);
@ -133,21 +133,26 @@ public class RequestManager implements Filter {
path += request.getPathInfo() ==null?"":request.getPathInfo();
log.debug("check wich handler should be excluded {}", path);
log.debug("check which handler should be excluded {}", path);
if (!context.configuration().excludes().isEmpty()) {
log.debug("excludes are not empty");
for (GCubeExclude exclude : context.configuration().excludes()){
String excludePath= exclude.getPath();
log.trace("exclude is {}",exclude);
log.debug("exclude is {}",exclude);
if ((WILDCARD).equals(excludePath) ||
(excludePath.endsWith(WILDCARD) && path!=null && path.startsWith(excludePath.substring(0,excludePath.length()-2))) ||
excludePath.equals(path) || (path.endsWith("/") && excludePath.equals(path.substring(0, path.length()-1)))
){
//ALL handler are filtered except for unfiltrable
if (exclude.getHandlers().isEmpty()) return handlersToFilter.stream()
//ALL handler are filtered except for unfilterable
if (exclude.getHandlers().isEmpty()) {
List<RequestHandler> unfilterables = handlersToFilter.stream()
.filter(RequestHandler::isUnfiltrable).collect(Collectors.toList());
log.debug("exclude handler is empty so unfilterable handlers are {}",unfilterables);
return handlersToFilter.stream()
.filter(RequestHandler::isUnfiltrable).collect(Collectors.toList());
}
List<RequestHandler> filteredHandlers = new ArrayList<>();
for (RequestHandler rh : handlersToFilter)
if (rh.isUnfiltrable() || !exclude.getHandlers().contains(rh.getName()))
@ -178,7 +183,7 @@ public class RequestManager implements Filter {
}
return new ArrayList<>();
}
log.debug("returning original handlers");
return handlersToFilter;
}

@ -155,7 +155,7 @@ public class DefaultProvider implements Provider {
}
ApplicationHandlers defaultHandlers = binder.bindHandlers(currentClassLoader);
return defaultHandlers;
} catch (RuntimeException e) {

@ -1,6 +1,10 @@
package org.gcube.smartgears.security.defaults;
import java.util.List;
import org.gcube.common.security.credentials.Credentials;
import org.gcube.common.validator.ValidationError;
import org.gcube.common.validator.ValidatorFactory;
import org.gcube.common.validator.annotations.NotEmpty;
import org.gcube.smartgears.security.AuthorizationProviderFactory;
import org.gcube.smartgears.security.SimpleCredentials;
@ -14,6 +18,9 @@ public class DefaultAuthorizationProviderFactory implements AuthorizationProvide
public DefaultAuthorizationProvider connect(Credentials credentials) {
if (!SimpleCredentials.class.isInstance(credentials))
throw new IllegalArgumentException("invalid credential type passed");
List<ValidationError> errors = ValidatorFactory.validator().validate(credentials);
if (!errors.isEmpty())
throw new IllegalArgumentException(String.format("invalid credential: %s", errors));
if (this.endpoint == null || this.endpoint.isEmpty())
throw new IllegalArgumentException("invalid enpoint passed");
return new DefaultAuthorizationProvider((SimpleCredentials)credentials, this.endpoint);

Loading…
Cancel
Save