config validation on Credential was not working
This commit is contained in:
parent
e193c80d11
commit
4d060fbb54
38
pom.xml
38
pom.xml
|
@ -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…
Reference in New Issue