diff options
Diffstat (limited to 'connector')
23 files changed, 1028 insertions, 140 deletions
diff --git a/connector/checks/spotbugs-exclude.xml b/connector/checks/spotbugs-exclude.xml index 5d4fd515..281e3796 100644 --- a/connector/checks/spotbugs-exclude.xml +++ b/connector/checks/spotbugs-exclude.xml @@ -19,4 +19,9 @@ </OR> <Bug pattern="SPRING_CSRF_UNRESTRICTED_REQUEST_MAPPING" /> </Match> + <Match> + <!-- Path to application configuration is trusted --> + <Class name="at.asitplus.eidas.specific.connector.MsSpecificSpringBootApplicationContextInitializer" /> + <Bug pattern="PATH_TRAVERSAL_IN" /> + </Match> </FindBugsFilter> diff --git a/connector/pom.xml b/connector/pom.xml index dad27b38..7fbc2a36 100644 --- a/connector/pom.xml +++ b/connector/pom.xml @@ -49,7 +49,15 @@ <artifactId>authmodule-eIDAS-v2</artifactId> </dependency> - <!-- Third party libs --> + <!-- Third party libs --> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-actuator</artifactId> + </dependency> + <dependency> + <groupId>de.codecentric</groupId> + <artifactId>spring-boot-admin-starter-client</artifactId> + </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> @@ -74,11 +82,10 @@ <groupId>org.apache.commons</groupId> <artifactId>commons-collections4</artifactId> </dependency> - <dependency> - <groupId>javax.servlet</groupId> - <artifactId>javax.servlet-api</artifactId> - <scope>provided</scope> - </dependency> + <dependency> + <groupId>org.hibernate.validator</groupId> + <artifactId>hibernate-validator</artifactId> + </dependency> <!-- Testing --> @@ -104,8 +111,63 @@ <scope>test</scope> <type>test-jar</type> </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-tomcat</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>at.gv.egiz.eaaf</groupId> + <artifactId>eaaf-springboot-utils</artifactId> + <scope>test</scope> + </dependency> </dependencies> + + <profiles> + <profile> + <id>default</id> + <activation> + <activeByDefault>true</activeByDefault> + <property> + <name>default</name> + </property> + </activation> + <dependencies> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-web</artifactId> + <exclusions> + <exclusion> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-tomcat</artifactId> + </exclusion> + </exclusions> + </dependency> + + <dependency> + <groupId>javax.servlet</groupId> + <artifactId>javax.servlet-api</artifactId> + <scope>provided</scope> + </dependency> + </dependencies> + </profile> + <profile> + <id>embbededTomcat</id> + <dependencies> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-web</artifactId> + </dependency> + <dependency> + <groupId>at.gv.egiz.eaaf</groupId> + <artifactId>eaaf-springboot-utils</artifactId> + </dependency> + </dependencies> + </profile> + + </profiles> + <build> <finalName>ms_connector</finalName> @@ -126,6 +188,24 @@ </plugin> <plugin> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-maven-plugin</artifactId> + <version>2.2.6.RELEASE</version> + <configuration> + <executable>true</executable> + <!-- layout>ZIP</layout --> + </configuration> + <executions> + <execution> + <goals> + <goal>build-info</goal> + <goal>repackage</goal> + </goals> + </execution> + </executions> + </plugin> + + <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <configuration> diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/MsSpecificEidasNodeSpringResourceProvider.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/MsSpecificEidasNodeSpringResourceProvider.java index 6e8e06ef..40ed283b 100644 --- a/connector/src/main/java/at/asitplus/eidas/specific/connector/MsSpecificEidasNodeSpringResourceProvider.java +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/MsSpecificEidasNodeSpringResourceProvider.java @@ -32,11 +32,15 @@ public class MsSpecificEidasNodeSpringResourceProvider implements SpringResource @Override public Resource[] getResourcesToLoad() { - final ClassPathResource msEidasNode = new ClassPathResource("/specific_eIDAS_connector.beans.xml", - MsSpecificEidasNodeSpringResourceProvider.class); + final ClassPathResource generic = + new ClassPathResource("/applicationContext.xml", MsSpecificEidasNodeSpringResourceProvider.class); + + final ClassPathResource msEidasNode = new ClassPathResource( + "/specific_eIDAS_connector.beans.xml", MsSpecificEidasNodeSpringResourceProvider.class); + final ClassPathResource msEidasNodeStorage = new ClassPathResource( "/specific_eIDAS_connector.storage.beans.xml", MsSpecificEidasNodeSpringResourceProvider.class); - return new Resource[] { msEidasNode, msEidasNodeStorage }; + return new Resource[] { generic, msEidasNode, msEidasNodeStorage }; } @Override diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/MsSpecificSpringBootApplicationContextInitializer.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/MsSpecificSpringBootApplicationContextInitializer.java new file mode 100644 index 00000000..5160bdf5 --- /dev/null +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/MsSpecificSpringBootApplicationContextInitializer.java @@ -0,0 +1,82 @@ +package at.asitplus.eidas.specific.connector; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Properties; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.core.env.MutablePropertySources; +import org.springframework.core.env.PropertiesPropertySource; + +import at.gv.egiz.components.spring.api.SpringBootApplicationContextInitializer; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class MsSpecificSpringBootApplicationContextInitializer extends + SpringBootApplicationContextInitializer { + + private static final String SYSTEMD_PROP_NAME = "eidas.ms.configuration"; + private static final String PATH_FILE_PREFIX = "file:"; + + @Override + public void initialize(ConfigurableApplicationContext applicationContext) { + String configPath = System.getProperty(SYSTEMD_PROP_NAME); + if (StringUtils.isNotEmpty(configPath)) { + log.debug("Find configuration-source from SystemD Property: '{}' ...", SYSTEMD_PROP_NAME); + if (configPath.startsWith(PATH_FILE_PREFIX)) { + configPath = configPath.substring(PATH_FILE_PREFIX.length()); + + } + injectConfiguration(configPath, applicationContext); + + } else { + log.info("Find NO SystemD Property: '{}' Maybe no configuration available", SYSTEMD_PROP_NAME); + + } + + super.initialize(applicationContext); + + } + + private void injectConfiguration(String configPath, ConfigurableApplicationContext applicationContext) { + InputStream is = null; + try { + Path path = Paths.get(configPath); + if (Files.exists(path)) { + File file = new File(configPath); + Properties props = new Properties(); + is = new FileInputStream(file); + props.load(is); + MutablePropertySources sources = applicationContext.getEnvironment().getPropertySources(); + sources.addFirst(new PropertiesPropertySource(SYSTEMD_PROP_NAME, props)); + log.info("Set configuration-source from SystemD-Property: {}", SYSTEMD_PROP_NAME); + + } else { + log.error("Configuration from SystemD Property: '{}' at Location: {} DOES NOT exist", + SYSTEMD_PROP_NAME, configPath); + + } + + } catch (IOException e) { + log.error("Configuration from SystemD Property: '{}' at Location: {} CAN NOT be loaded", + SYSTEMD_PROP_NAME, configPath, e); + + } finally { + try { + if (is != null) { + is.close(); + + } + } catch (IOException e) { + log.error("Can not close InputStream of configLoader: {}", configPath, e); + + } + } + } +} diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/SpringBootApplicationInitializer.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/SpringBootApplicationInitializer.java new file mode 100644 index 00000000..0d3226bf --- /dev/null +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/SpringBootApplicationInitializer.java @@ -0,0 +1,60 @@ +package at.asitplus.eidas.specific.connector; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.ConfigurableApplicationContext; + +import at.gv.egiz.eaaf.core.impl.logging.LogMessageProviderFactory; +import at.gv.egiz.eaaf.core.impl.logging.SimpleStatusMessager; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@SpringBootApplication(scanBasePackages = {"at.gv.egiz.eaaf.utils.springboot.ajp"}) +public class SpringBootApplicationInitializer { + + private static ConfigurableApplicationContext ctx; + + /** + * Starts MS-specific eIDAS-Implementation SpringBoot application. + * + * @param args Starting parameters + */ + public static void main(final String[] args) { + try { + log.info("=============== Initializing Spring-Boot context! ==============="); + LogMessageProviderFactory.setStatusMessager(new SimpleStatusMessager()); + final SpringApplication springApp = + new SpringApplication(SpringBootApplicationInitializer.class); + springApp.addInitializers(new MsSpecificSpringBootApplicationContextInitializer()); + + log.debug("Run SpringBoot initialization process ... "); + ctx = springApp.run(args); + + log.info("Initialization of MS-specific eIDAS-Implementation finished."); + + } catch (final Throwable e) { + log.error("MS-specific eIDAS-Implementation initialization FAILED!", e); + throw e; + + } + + } + + /** + * Stops SpringBoot application of MS-specific eIDAS-Implementation. + * + */ + public static void exit() { + if (ctx != null) { + log.info("Stopping SpringBoot application ... "); + SpringApplication.exit(ctx, () -> 0); + ctx = null; + + } else { + log.info("No SpringBoot context. Nothing todo"); + + } + + } + +} diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/SpringContextCloseHandler.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/SpringContextCloseHandler.java new file mode 100644 index 00000000..2a3b659a --- /dev/null +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/SpringContextCloseHandler.java @@ -0,0 +1,224 @@ +package at.asitplus.eidas.specific.connector; + +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; + +import org.slf4j.Logger; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.context.ApplicationListener; +import org.springframework.context.event.ContextClosedEvent; +import org.springframework.context.event.EventListener; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; + +import at.gv.egiz.components.spring.api.IDestroyableObject; +import eu.eidas.auth.cache.IgniteInstanceInitializerSpecificCommunication; + +/** + * SpringContext CloseHandler. + * + * @author tlenz + * + */ + +public class SpringContextCloseHandler + implements ApplicationListener<ContextClosedEvent>, ApplicationContextAware, BeanPostProcessor { + + private static final Logger log = + org.slf4j.LoggerFactory.getLogger(SpringContextCloseHandler.class); + + private ApplicationContext context; + + /* + * (non-Javadoc) + * + * @see org.springframework.context.ApplicationListener#onApplicationEvent(org. + * springframework.context. ApplicationEvent) + */ + @Override + @EventListener + public void onApplicationEvent(final ContextClosedEvent arg0) { + log.info("MS-specific eIDAS-Node shutdown process started ..."); + + try { + log.debug("CleanUp objects with implements the IDestroyable interface ... "); + final Map<String, IDestroyableObject> objectsToDestroy = + context.getBeansOfType(IDestroyableObject.class); + internalIDestroyableObject(objectsToDestroy); + log.info("Object cleanUp complete"); + + log.debug("Stopping Spring Thread-Pools ... "); + // shut-down task schedulers + final Map<String, ThreadPoolTaskScheduler> schedulers = + context.getBeansOfType(ThreadPoolTaskScheduler.class); + internalThreadPoolTaskScheduler(schedulers); + + // shut-down task executors + final Map<String, ThreadPoolTaskExecutor> executers = + context.getBeansOfType(ThreadPoolTaskExecutor.class); + internalThreadPoolTaskExecutor(executers); + log.debug("Spring Thread-Pools stopped"); + + + //clean-up eIDAS node + Map<String, IgniteInstanceInitializerSpecificCommunication> nodeIgnite = + context.getBeansOfType(IgniteInstanceInitializerSpecificCommunication.class); + log.info("Find #{} Apache Ignite instances from eIDAS Ref. impl.", nodeIgnite.size()); + for (Entry<String, IgniteInstanceInitializerSpecificCommunication> el : nodeIgnite.entrySet()) { + if (el.getValue().getInstance() != null) { + el.getValue().getInstance().close(); + el.getValue().destroyInstance(); + log.debug("Shutdown Apache-Ignite: {}", el.getKey()); + + } + } + + log.info("MS-specific eIDAS-Node shutdown process finished"); + + } catch (final Exception e) { + log.warn("MS-specific eIDAS-Node shutdown process has an error.", e); + + } + + } + + /* + * (non-Javadoc) + * + * @see org.springframework.beans.factory.config.BeanPostProcessor# + * postProcessAfterInitialization(java. lang.Object, java.lang.String) + */ + @Override + public Object postProcessAfterInitialization(final Object arg0, final String arg1) + throws BeansException { + if (arg0 instanceof ThreadPoolTaskScheduler) { + ((ThreadPoolTaskScheduler) arg0).setWaitForTasksToCompleteOnShutdown(true); + } + if (arg0 instanceof ThreadPoolTaskExecutor) { + ((ThreadPoolTaskExecutor) arg0).setWaitForTasksToCompleteOnShutdown(true); + } + return arg0; + + } + + /* + * (non-Javadoc) + * + * @see org.springframework.beans.factory.config.BeanPostProcessor# + * postProcessBeforeInitialization(java .lang.Object, java.lang.String) + */ + @Override + public Object postProcessBeforeInitialization(final Object arg0, final String arg1) + throws BeansException { + return arg0; + + } + + /* + * (non-Javadoc) + * + * @see + * org.springframework.context.ApplicationContextAware#setApplicationContext(org + * .springframework. context.ApplicationContext) + */ + @Override + public void setApplicationContext(final ApplicationContext arg0) throws BeansException { + this.context = arg0; + + } + + private void internalThreadPoolTaskExecutor(final Map<String, ThreadPoolTaskExecutor> executers) { + for (final ThreadPoolTaskExecutor executor : executers.values()) { + // Not needed yet + // int retryCount = 0; + // while(executor.getActiveCount()>0 && ++retryCount<51){ + // try { + // log.debug("Executer {} is still working with active {} work. Retry count is + // {}", + // executor.getThreadNamePrefix(), + // executor.getActiveCount(), + // retryCount); + // Thread.sleep(1000); + // + // } catch (final InterruptedException e) { + // e.printStackTrace(); + // } + // } + // + // if(!(retryCount<51)) + // log.debug("Executer {} is still working. Since Retry count exceeded max value + // {}, will be + // killed immediately", + // executor.getThreadNamePrefix(), + // retryCount); + + executor.shutdown(); + log.debug("Executer {} with active {} work has killed", executor.getThreadNamePrefix(), + executor.getActiveCount()); + + } + + } + + // Not required at the moment + private void internalThreadPoolTaskScheduler( + final Map<String, ThreadPoolTaskScheduler> schedulers) { + log.trace("Stopping #{} task-schedulers", schedulers.size()); + + // for (final ThreadPoolTaskScheduler scheduler : schedulers.values()) { + // scheduler.getScheduledExecutor().shutdown(); + // try { + // scheduler.getScheduledExecutor().awaitTermination(20000, + // TimeUnit.MILLISECONDS); + // if(scheduler.getScheduledExecutor().isTerminated() || + // scheduler.getScheduledExecutor().isShutdown()) + // log.debug("Scheduler {} has stoped", scheduler.getThreadNamePrefix()); + // + // else{ + // log.debug("Scheduler {} has not stoped normally and will be shut down + // immediately", + // scheduler.getThreadNamePrefix()); + // scheduler.getScheduledExecutor().shutdownNow(); + // log.info("Scheduler {} has shut down immediately", + // scheduler.getThreadNamePrefix()); + // + // } + // + // } catch (final IllegalStateException e) { + // e.printStackTrace(); + // + // } catch (final InterruptedException e) { + // e.printStackTrace(); + // + // } finally { + // scheduler.shutdown(); + // + // } + // } + + } + + private void internalIDestroyableObject(final Map<String, IDestroyableObject> objectsToDestroy) { + if (objectsToDestroy != null) { + final Iterator<Entry<String, IDestroyableObject>> interator = + objectsToDestroy.entrySet().iterator(); + while (interator.hasNext()) { + final Entry<String, IDestroyableObject> object = interator.next(); + try { + object.getValue().fullyDestroy(); + log.debug("Object with ID: {} is destroyed", object.getKey()); + + } catch (final Exception e) { + log.warn("Destroing object with ID: {} FAILED!", object.getKey(), null, e); + + } + } + } + + } + +} diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/config/StaticResourceConfiguration.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/config/StaticResourceConfiguration.java index 2a10031b..a1e953f1 100644 --- a/connector/src/main/java/at/asitplus/eidas/specific/connector/config/StaticResourceConfiguration.java +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/config/StaticResourceConfiguration.java @@ -24,6 +24,7 @@ package at.asitplus.eidas.specific.connector.config; import java.net.MalformedURLException; +import java.util.List; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; @@ -35,11 +36,11 @@ import org.springframework.context.support.ReloadableResourceBundleMessageSource import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; -import org.springframework.web.servlet.i18n.CookieLocaleResolver; import org.thymeleaf.templateresolver.FileTemplateResolver; import at.asitplus.eidas.specific.connector.MsEidasNodeConstants; import at.gv.egiz.eaaf.core.api.idp.IConfiguration; +import at.gv.egiz.eaaf.core.api.logging.IMessageSourceLocation; import at.gv.egiz.eaaf.core.impl.utils.FileUtils; /** @@ -90,43 +91,63 @@ public class StaticResourceConfiguration implements WebMvcConfigurer { } /** - * Internal i18n message source. - * + * Get a message source with only internal message properties. + * + * @param ressourceLocations List of source-locations * @return */ @Bean - public ReloadableResourceBundleMessageSource internalMessageSource() { - final ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource(); + public ReloadableResourceBundleMessageSource internalMessageSource( + @Autowired(required = false) final List<IMessageSourceLocation> ressourceLocations) { + final ReloadableResourceBundleMessageSource messageSource = + new ReloadableResourceBundleMessageSource(); // add default message source messageSource.setBasename(DEFAULT_MESSAGE_SOURCE); + + if (ressourceLocations != null) { + // load more message sources + for (final IMessageSourceLocation el : ressourceLocations) { + if (el.getMessageSourceLocation() != null) { + for (final String source : el.getMessageSourceLocation()) { + messageSource.addBasenames(source); + log.debug("Add additional messageSources: {}", el.getMessageSourceLocation().toArray()); + + } + } + } + } + messageSource.setDefaultEncoding("UTF-8"); return messageSource; } /** - * External i18n message source. - * + * Get full message source with internal and external message-properties files. + * + * @param ressourceLocations List of source-locations * @return */ @Bean - public ReloadableResourceBundleMessageSource messageSource() { - final ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource(); + public ReloadableResourceBundleMessageSource messageSource( + @Autowired(required = false) final List<IMessageSourceLocation> ressourceLocations) { + final ReloadableResourceBundleMessageSource messageSource = + new ReloadableResourceBundleMessageSource(); messageSource.setDefaultEncoding("UTF-8"); - messageSource.setParentMessageSource(internalMessageSource()); + messageSource.setParentMessageSource(internalMessageSource(ressourceLocations)); - final String staticResources = basicConfig.getBasicConfiguration( - MsEidasNodeConstants.PROP_CONFIG_WEBCONTENT_PROPERTIES_PATH); + final String staticResources = basicConfig + .getBasicConfiguration(MsEidasNodeConstants.PROP_CONFIG_WEBCONTENT_PROPERTIES_PATH); try { if (StringUtils.isNotEmpty(staticResources)) { - final String absPath = FileUtils.makeAbsoluteUrl(staticResources, basicConfig - .getConfigurationRootDirectory()); + final String absPath = + FileUtils.makeAbsoluteUrl(staticResources, basicConfig.getConfigurationRootDirectory()); messageSource.setBasename(absPath); - messageSource.setFallbackToSystemLocale(false); } else { log.debug("No Ressourcefolder for dynamic Web content templates"); + } } catch (final MalformedURLException e) { @@ -137,40 +158,28 @@ public class StaticResourceConfiguration implements WebMvcConfigurer { return messageSource; } - + /** - * Cookie based i18n language selector. - * - * @return - */ - @Bean - public CookieLocaleResolver localeResolver() { - final CookieLocaleResolver localeResolver = new CookieLocaleResolver(); - localeResolver.setCookieName("currentLanguage"); - localeResolver.setCookieMaxAge(3600); - return localeResolver; - } - - - /** - * Thymeleaf based template resolver. - * + * Get a Tyhmeleaf Template-Resolver with external configuration path. + * * @return */ @Bean(name = "templateResolver") public FileTemplateResolver templateResolver() { - final String staticResources = basicConfig.getBasicConfiguration( - MsEidasNodeConstants.PROP_CONFIG_WEBCONTENT_TEMPLATES_PATH); + final String staticResources = basicConfig + .getBasicConfiguration(MsEidasNodeConstants.PROP_CONFIG_WEBCONTENT_TEMPLATES_PATH); try { if (StringUtils.isNotEmpty(staticResources)) { - String absPath = FileUtils.makeAbsoluteUrl(staticResources, basicConfig - .getConfigurationRootDirectory()); + String absPath = + FileUtils.makeAbsoluteUrl(staticResources, basicConfig.getConfigurationRootDirectory()); if (!absPath.endsWith("/")) { absPath += "/"; + } if (absPath.startsWith("file:")) { absPath = absPath.substring("file:".length()); + } final FileTemplateResolver viewResolver = new FileTemplateResolver(); @@ -179,11 +188,12 @@ public class StaticResourceConfiguration implements WebMvcConfigurer { viewResolver.setTemplateMode("HTML"); viewResolver.setCacheable(false); - log.info("Add Ressourcefolder: " + absPath + " for dynamic Web content templates"); + log.info("Add Ressourcefolder: {} for dynamic Web content templates", absPath); return viewResolver; } else { log.debug("No Ressourcefolder for dynamic Web content templates"); + } } catch (final MalformedURLException e) { @@ -191,8 +201,7 @@ public class StaticResourceConfiguration implements WebMvcConfigurer { } - // TODO: implement some backup solution - return null; + throw new RuntimeException("Can NOT initialize HTML template resolver"); } } diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/storage/SimpleInMemoryTransactionStorage.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/storage/SimpleInMemoryTransactionStorage.java index 26d442cb..3bda2932 100644 --- a/connector/src/main/java/at/asitplus/eidas/specific/connector/storage/SimpleInMemoryTransactionStorage.java +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/storage/SimpleInMemoryTransactionStorage.java @@ -33,13 +33,11 @@ import java.util.concurrent.ConcurrentHashMap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Service; import at.gv.egiz.eaaf.core.api.storage.ITransactionStorage; import at.gv.egiz.eaaf.core.exceptions.EaafException; import at.gv.egiz.eaaf.core.exceptions.EaafStorageException; -@Service("SimpleInMemoryTransactionStorage") public class SimpleInMemoryTransactionStorage implements ITransactionStorage { private static final Logger log = LoggerFactory.getLogger(SimpleInMemoryTransactionStorage.class); diff --git a/connector/src/main/resources/application.properties b/connector/src/main/resources/application.properties new file mode 100644 index 00000000..2cb0c83a --- /dev/null +++ b/connector/src/main/resources/application.properties @@ -0,0 +1,144 @@ +## Set Spring-Boot profile-configuration to 2.3 style +spring.config.use-legacy-processing=true + +## ApplicationServer configuration +server.servlet.contextPath=/ms_connector +#server.port=7080 + +app.build.artifactId=ms_connector + + +############################################################################# +## SpringBoot Admin client +spring.boot.admin.client.enabled=false + + +############################################################################# +## MS-speccific eIDAS-Connector configuration +#proxy.context.url.prefix= +eidas.ms.context.url.request.validation=false +#proxy.configRootDir=file:/.../config/ +eidas.ms.context.use.clustermode=true + + +##Monitoring +eidas.ms.monitoring.eIDASNode.metadata.url= + + +##Specific logger configuration +eidas.ms.technicallog.write.MDS.into.techlog=true +eidas.ms.revisionlog.write.MDS.into.revisionlog=true +eidas.ms.revisionlog.logIPAddressOfUser=true + + +##Directory for static Web content +eidas.ms.webcontent.static.directory=webcontent/ +eidas.ms.webcontent.templates=templates/ +eidas.ms.webcontent.properties=properties/messages +eidas.ms.webcontent.templates.countryselection=countrySelection.html + + +## extended validation of pending-request Id's +eidas.ms.core.pendingrequestid.maxlifetime=300 +eidas.ms.core.pendingrequestid.digist.algorithm=HmacSHA256 +#eidas.ms.core.pendingrequestid.digist.secret=pendingReqIdSecret + + +## eIDAS Ref. Implementation connector ### +eidas.ms.auth.eIDAS.node_v2.entityId=ownSpecificConnector +#eidas.ms.auth.eIDAS.node_v2.forward.endpoint= +eidas.ms.auth.eIDAS.node_v2.forward.method=POST +eidas.ms.auth.eIDAS.node_v2.countrycode=AT +eidas.ms.auth.eIDAS.node_v2.publicSectorTargets=.* +eidas.ms.auth.eIDAS.node_v2.workarounds.addAlwaysProviderName=true +eidas.ms.auth.eIDAS.node_v2.workarounds.useRequestIdAsTransactionIdentifier=true +eidas.ms.auth.eIDAS.node_v2.workarounds.useStaticProviderNameForPublicSPs=true + +eidas.ms.auth.eIDAS.node_v2.loa.requested.minimum=http://eidas.europa.eu/LoA/substantial + +#eidas.ms.auth.eIDAS.szrclient.useTestService=true +#eidas.ms.auth.eIDAS.szrclient.endpoint.prod= +#eidas.ms.auth.eIDAS.szrclient.endpoint.test=http://localhost:1234/demoszr +#eidas.ms.auth.eIDAS.szrclient.ssl.keyStore.path=keys/junit.jks +#eidas.ms.auth.eIDAS.szrclient.ssl.keyStore.password=password +#eidas.ms.auth.eIDAS.szrclient.ssl.trustStore.path= +#eidas.ms.auth.eIDAS.szrclient.ssl.trustStore.password= +eidas.ms.auth.eIDAS.szrclient.timeout.connection=15 +eidas.ms.auth.eIDAS.szrclient.timeout.response=30 +eidas.ms.auth.eIDAS.szrclient.params.vkz= + +eidas.ms.auth.eIDAS.szrclient.params.useSZRForbPKCalculation=false + + +# tech. AuthBlock signing for E-ID process +#eidas.ms.auth.eIDAS.authblock.keystore.password=f/+saJBc3a}*/T^s +#eidas.ms.auth.eIDAS.authblock.keystore.friendlyName=connectorkeypair +#eidas.ms.auth.eIDAS.authblock.keystore.path=keys/teststore.jks +#eidas.ms.auth.eIDAS.authblock.keystore.type=jks +#eidas.ms.auth.eIDAS.authblock.key.alias=connectorkeypair +#eidas.ms.auth.eIDAS.authblock.key.password=f/+saJBc3a}*/T^s + + +#Raw eIDAS Id data storage +eidas.ms.auth.eIDAS.szrclient.workarounds.eidmapping.revisionlog.active=true + +eidas.ms.auth.eIDAS.szrclient.params.setPlaceOfBirthIfAvailable=true +eidas.ms.auth.eIDAS.szrclient.params.setBirthNameIfAvailable=true + +eidas.ms.auth.eIDAS.szrclient.debug.logfullmessages=false +eidas.ms.auth.eIDAS.szrclient.debug.useDummySolution=false + +##without mandates +eidas.ms.auth.eIDAS.node_v2.attributes.requested.onlynatural.0=PersonIdentifier,true +eidas.ms.auth.eIDAS.node_v2.attributes.requested.onlynatural.1=FamilyName,true +eidas.ms.auth.eIDAS.node_v2.attributes.requested.onlynatural.2=FirstName,true +eidas.ms.auth.eIDAS.node_v2.attributes.requested.onlynatural.3=DateOfBirth,true + +eidas.ms.auth.eIDAS.node_v2.attributes.requested.de.onlynatural.4=PlaceOfBirth,false +eidas.ms.auth.eIDAS.node_v2.attributes.requested.de.onlynatural.5=BirthName,false +eidas.ms.auth.eIDAS.node_v2.attributes.requested.de.onlynatural.6=Gender,false +eidas.ms.auth.eIDAS.node_v2.attributes.requested.de.onlynatural.7=CurrentAddress,false + +##with mandates ---- NOT FULLY SUPPORTED AT THE MOMENT ----- +eidas.ms.auth.eIDAS.node_v2.attributes.requested.representation.0=PersonIdentifier,true +eidas.ms.auth.eIDAS.node_v2.attributes.requested.representation.1=FamilyName,true +eidas.ms.auth.eIDAS.node_v2.attributes.requested.representation.2=FirstName,true +eidas.ms.auth.eIDAS.node_v2.attributes.requested.representation.3=DateOfBirth,true +eidas.ms.auth.eIDAS.node_v2.attributes.requested.representation.4=LegalPerson,true +eidas.ms.auth.eIDAS.node_v2.attributes.requested.representation.5=LegalName,true + + +## PVP2 S-Profile end-point configuration +#eidas.ms.pvp2.keystore.type=jks +#eidas.ms.pvp2.keystore.path=keys/junit.jks +#eidas.ms.pvp2.keystore.password=password +#eidas.ms.pvp2.key.metadata.alias=meta +#eidas.ms.pvp2.key.metadata.password=password +#eidas.ms.pvp2.key.signing.alias=sig +#eidas.ms.pvp2.key.signing.password=password +#eidas.ms.pvp2.metadata.validity=24 + +#eidas.ms.pvp2.metadata.organisation.name=JUnit +#eidas.ms.pvp2.metadata.organisation.friendyname=For testing with jUnit +#eidas.ms.pvp2.metadata.organisation.url=http://junit.test +#eidas.ms.pvp2.metadata.contact.givenname=Max +#eidas.ms.pvp2.metadata.contact.surname=Mustermann +#eidas.ms.pvp2.metadata.contact.email=max@junit.test + + +## Service Provider configuration +#eidas.ms.sp.0.uniqueID=https://demo.egiz.gv.at/demoportal_moaid-2.0/sp/eidas/metadata +#eidas.ms.sp.0.pvp2.metadata.truststore=keys/junit.jks +#eidas.ms.sp.0.pvp2.metadata.truststore.password=password +#eidas.ms.sp.0.friendlyName=jUnit test +#eidas.ms.sp.0.pvp2.metadata.url= +#eidas.ms.sp.0.policy.allowed.requested.targets=.* +#eidas.ms.sp.0.policy.hasBaseIdTransferRestriction=false + + +##only for advanced config +eidas.ms.configuration.sp.disableRegistrationRequirement= +#eidas.ms.configuration.restrictions.baseID.spTransmission= +eidas.ms.configuration.auth.default.countrycode= +eidas.ms.configuration.pvp.scheme.validation= +eidas.ms.configuration.pvp.enable.entitycategories=
\ No newline at end of file diff --git a/connector/src/main/resources/applicationContext.xml b/connector/src/main/resources/applicationContext.xml index 76682a2e..8a21e68f 100644 --- a/connector/src/main/resources/applicationContext.xml +++ b/connector/src/main/resources/applicationContext.xml @@ -14,10 +14,14 @@ http://www.springframework.org/schema/tx/spring-tx.xsd"> <context:annotation-config /> - <mvc:annotation-driven /> + <context:component-scan base-package="at.gv.egiz.eaaf.utils.springboot.ajp"/> +<!-- + <context:annotation-config /> + <mvc:annotation-driven /> <mvc:default-servlet-handler /> - +--> + <mvc:interceptors> <bean class="at.asitplus.eidas.specific.connector.interceptor.WebFrontEndSecurityInterceptor" /> @@ -27,13 +31,24 @@ </bean> </mvc:interceptors> + <bean id="springContextClosingHandler" + class="at.asitplus.eidas.specific.connector.SpringContextCloseHandler" /> + +<!-- <context:property-placeholder location="${eidas.ms.configuration}" /> + --> + <beans profile="!springBoot"> <bean id="BasicMSSpecificNodeConfig" class="at.asitplus.eidas.specific.connector.config.BasicConfigurationProvider"> - <constructor-arg - value="#{systemProperties['eidas.ms.configuration']}" /> + <constructor-arg value="#{systemProperties['eidas.ms.configuration']}" /> </bean> + </beans> + <beans profile="springBoot"> + <bean id="springBootMsSpecificNodeConfig" + class="at.asitplus.eidas.specific.connector.config.SpringBootBasicConfigurationProvider" /> + + </beans> </beans> diff --git a/connector/src/main/resources/log4j.properties b/connector/src/main/resources/log4j.properties deleted file mode 100644 index 81e54aae..00000000 --- a/connector/src/main/resources/log4j.properties +++ /dev/null @@ -1,55 +0,0 @@ -# commons-logging setup -org.apache.commons.logging.LogFactory=org.apache.commons.logging.impl.Log4jFactory - -# define log4j root loggers -log4j.rootLogger=info,stdout, console - -log4j.logger.at.gv.egiz.eaaf=info, msnode -log4j.logger.at.gv.egiz.eidas.specific=info, msnode -log4j.logger.at.gv.egiz.eidas.specific.connector.logger.RevisionLogger=info, reversion -log4j.logger.at.gv.egiz.eidas.specific.connector.logger.StatisticLogger=info, statistic -log4j.logger.eu.eidas=info, EIDASNODE - -log4j.additivity.at.gv.egiz.eidas.specific=false -log4j.additivity.at.gv.egiz.eidas.specific.connector.logger.RevisionLogger=false -log4j.additivity.at.gv.egiz.eidas.specific.connector.logger.StatisticLogger=false -log4j.additivity.eu.eidas=false - -log4j.appender.console=org.apache.log4j.ConsoleAppender -log4j.appender.console.layout=org.apache.log4j.PatternLayout -log4j.appender.console.layout.ConversionPattern=%5p | %d{dd HH:mm:ss,SSS} | %20c | %10t | %m%n - -log4j.appender.stdout=org.apache.log4j.RollingFileAppender -log4j.appender.stdout.File=${catalina.base}/logs/console.log -log4j.appender.stdout.MaxFileSize=10000KB -log4j.appender.stdout.MaxBackupIndex=9999 -log4j.appender.stdout.layout=org.apache.log4j.PatternLayout -log4j.appender.stdout.layout.ConversionPattern=%5p | %d{dd HH:mm:ss,SSS} | %t | %m%n - -log4j.appender.msnode=org.apache.log4j.RollingFileAppender -log4j.appender.msnode.File=${catalina.base}/logs/eidas-ms-reversion.log -log4j.appender.msnode.MaxFileSize=10000KB -log4j.appender.msnode.MaxBackupIndex=9999 -log4j.appender.msnode.layout=org.apache.log4j.PatternLayout -log4j.appender.msnode.layout.ConversionPattern=%5p | %d{dd HH:mm:ss,SSS} | %t | %m%n - -log4j.appender.reversion=org.apache.log4j.RollingFileAppender -log4j.appender.reversion.File=${catalina.base}/logs/eidas-ms-reversion.log -log4j.appender.reversion.MaxFileSize=10000KB -log4j.appender.reversion.MaxBackupIndex=9999 -log4j.appender.reversion.layout=org.apache.log4j.PatternLayout -log4j.appender.reversion.layout.ConversionPattern=%5p | %d{dd HH:mm:ss,SSS} | %t | %m%n - -log4j.appender.statistic=org.apache.log4j.RollingFileAppender -log4j.appender.statistic.File=${catalina.base}/logs/eidas-ms-statistic.log -log4j.appender.statistic.MaxFileSize=10000KB -log4j.appender.statistic.MaxBackupIndex=9999 -log4j.appender.statistic.layout=org.apache.log4j.PatternLayout -log4j.appender.statistic.layout.ConversionPattern=%m%n - -log4j.appender.EIDASNODE=org.apache.log4j.RollingFileAppender -log4j.appender.EIDASNODE.File=${catalina.base}/logs/eIDAS_node.log -log4j.appender.EIDASNODE.MaxFileSize=10000KB -log4j.appender.EIDASNODE.MaxBackupIndex=9999 -log4j.appender.EIDASNODE.layout=org.apache.log4j.PatternLayout -log4j.appender.EIDASNODE.layout.ConversionPattern=%5p | %d{dd HH:mm:ss,SSS} | %t | %m%n
\ No newline at end of file diff --git a/connector/src/main/resources/logback.xml b/connector/src/main/resources/logback.xml index a0a9995e..7aa2d0cc 100644 --- a/connector/src/main/resources/logback.xml +++ b/connector/src/main/resources/logback.xml @@ -11,14 +11,14 @@ <appender name="msnode" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!--See also http://logback.qos.ch/manual/appenders.html#RollingFileAppender --> - <File>${catalina.base}/logs/eidas-ms-reversion.log</File> + <File>logs/eidas-ms-specific.log</File> <encoder> <pattern>%5p | %d{dd HH:mm:ss,SSS} | %t | %m%n</pattern> </encoder> <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> <maxIndex>9999</maxIndex> - <FileNamePattern>${catalina.base}/logs/eidas-ms-reversion.log.%i + <FileNamePattern>logs/eidas-ms-specific.log.%i </FileNamePattern> </rollingPolicy> <triggeringPolicy @@ -29,14 +29,14 @@ <appender name="EIDASNODE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!--See also http://logback.qos.ch/manual/appenders.html#RollingFileAppender --> - <File>${catalina.base}/logs/eIDAS_node.log</File> + <File>logs/eIDAS_node.log</File> <encoder> <pattern>%5p | %d{dd HH:mm:ss,SSS} | %t | %m%n</pattern> </encoder> <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> <maxIndex>9999</maxIndex> - <FileNamePattern>${catalina.base}/logs/eIDAS_node.log.%i + <FileNamePattern>logs/eIDAS_node.log.%i </FileNamePattern> </rollingPolicy> <triggeringPolicy @@ -47,14 +47,14 @@ <appender name="reversion" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!--See also http://logback.qos.ch/manual/appenders.html#RollingFileAppender --> - <File>${catalina.base}/logs/eidas-ms-reversion.log</File> + <File>logs/eidas-ms-reversion.log</File> <encoder> <pattern>%5p | %d{dd HH:mm:ss,SSS} | %t | %m%n</pattern> </encoder> <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> <maxIndex>9999</maxIndex> - <FileNamePattern>${catalina.base}/logs/eidas-ms-reversion.log.%i + <FileNamePattern>logs/eidas-ms-reversion.log.%i </FileNamePattern> </rollingPolicy> <triggeringPolicy @@ -65,14 +65,14 @@ <appender name="statistic" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!--See also http://logback.qos.ch/manual/appenders.html#RollingFileAppender --> - <File>${catalina.base}/logs/eidas-ms-statistic.log</File> + <File>logs/eidas-ms-statistic.log</File> <encoder> <pattern>%m%n</pattern> </encoder> <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> <maxIndex>9999</maxIndex> - <FileNamePattern>${catalina.base}/logs/eidas-ms-statistic.log.%i + <FileNamePattern>logs/eidas-ms-statistic.log.%i </FileNamePattern> </rollingPolicy> <triggeringPolicy @@ -83,14 +83,14 @@ <appender name="stdout" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!--See also http://logback.qos.ch/manual/appenders.html#RollingFileAppender --> - <File>${catalina.base}/logs/console.log</File> + <File>logs/console.log</File> <encoder> <pattern>%5p | %d{dd HH:mm:ss,SSS} | %t | %m%n</pattern> </encoder> <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> <maxIndex>9999</maxIndex> - <FileNamePattern>${catalina.base}/logs/console.log.%i + <FileNamePattern>logs/console.log.%i </FileNamePattern> </rollingPolicy> <triggeringPolicy diff --git a/connector/src/main/resources/specific_eIDAS_connector.beans.xml b/connector/src/main/resources/specific_eIDAS_connector.beans.xml index 5cf0d5b8..aa5040fa 100644 --- a/connector/src/main/resources/specific_eIDAS_connector.beans.xml +++ b/connector/src/main/resources/specific_eIDAS_connector.beans.xml @@ -11,17 +11,15 @@ http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> - <context:annotation-config /> - <mvc:annotation-driven /> - <mvc:default-servlet-handler /> + <import resource="common_gui.beans.xml"/> <bean id="WebResourceConfiguration" class="at.asitplus.eidas.specific.connector.config.StaticResourceConfiguration" /> - <bean id="ProcessEngineSignalController" + <bean id="processEngineSignalController" class="at.asitplus.eidas.specific.connector.controller.ProcessEngineSignalController" /> - <bean id="MonitoringController" + <bean id="monitoringController" class="at.asitplus.eidas.specific.connector.controller.MonitoringController"> <property name="pvpIdpCredentials"> <ref bean="PVPEndPointCredentialProvider" /> @@ -43,7 +41,7 @@ <bean id="PVPMetadataConfigurationFactory" class="at.asitplus.eidas.specific.connector.provider.PvpMetadataConfigurationFactory" /> - <bean id="PVP2XProtocol" + <bean id="pvp2SProfileEndpoint" class="at.asitplus.eidas.specific.connector.controller.Pvp2SProfileEndpoint"> <property name="pvpIdpCredentials"> <ref bean="PVPEndPointCredentialProvider" /> @@ -96,17 +94,6 @@ <bean id="mvcGUIBuilderImpl" class="at.asitplus.eidas.specific.connector.gui.SpringMvcGuiFormBuilderImpl" /> - <bean id="templateEngine" - class="org.thymeleaf.spring5.SpringTemplateEngine"> - <property name="templateResolver" ref="templateResolver" /> - </bean> - - <bean class="org.thymeleaf.spring5.view.ThymeleafViewResolver"> - <property name="order" value="2" /> - <property name="templateEngine" ref="templateEngine" /> - <property name="characterEncoding" value="UTF-8" /> - </bean> - <bean id="StatusMessageProvider" class="at.asitplus.eidas.specific.connector.provider.StatusMessageProvider" /> diff --git a/connector/src/main/resources/tomcat.properties b/connector/src/main/resources/tomcat.properties new file mode 100644 index 00000000..38ab5a64 --- /dev/null +++ b/connector/src/main/resources/tomcat.properties @@ -0,0 +1,15 @@ +tomcat.ajp.enabled=true +#tomcat.ajp.port=41009 +#tomcat.ajp.additionalAttributes.secretrequired=true +#tomcat.ajp.additionalAttributes.secret= + +server.tomcat.accesslog.buffered=false +server.tomcat.accesslog.prefix=tomcat-access_log +server.tomcat.accesslog.directory=logs/ +server.tomcat.accesslog.enabled=true +server.tomcat.accesslog.file-date-format=.yyyy-MM-dd +server.tomcat.accesslog.pattern=common +server.tomcat.accesslog.rename-on-rotate=false +server.tomcat.accesslog.request-attributes-enabled=true +server.tomcat.accesslog.rotate=true +server.tomcat.accesslog.suffix=.log
\ No newline at end of file diff --git a/connector/src/test/java/at/asitplus/eidas/specific/connector/test/MainClassExecutableModeTest.java b/connector/src/test/java/at/asitplus/eidas/specific/connector/test/MainClassExecutableModeTest.java new file mode 100644 index 00000000..66147971 --- /dev/null +++ b/connector/src/test/java/at/asitplus/eidas/specific/connector/test/MainClassExecutableModeTest.java @@ -0,0 +1,109 @@ +package at.asitplus.eidas.specific.connector.test; + +import java.io.IOException; +import java.lang.reflect.Field; + +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.client.HttpClients; +import org.apache.ignite.Ignition; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.BlockJUnit4ClassRunner; + +import at.asitplus.eidas.specific.connector.SpringBootApplicationInitializer; +import at.gv.egiz.eaaf.core.impl.logging.DummyStatusMessager; +import at.gv.egiz.eaaf.core.impl.logging.LogMessageProviderFactory; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@RunWith(BlockJUnit4ClassRunner.class) +public class MainClassExecutableModeTest { + + /** + * jUnit class initializer. + * @throws InterruptedException In case of an error + * + */ + @BeforeClass + public static void classInitializer() throws InterruptedException { + final String current = new java.io.File(".").toURI().toString(); + System.clearProperty("eidas.ms.configuration"); + + //eIDAS Ref. Impl. properties + System.setProperty("EIDAS_CONFIG_REPOSITORY", current.substring("file:".length()) + + "../basicConfig/eIDAS/"); + System.setProperty("SPECIFIC_CONNECTOR_CONFIG_REPOSITORY", current.substring("file:".length()) + + "../basicConfig/eIDAS/"); + System.setProperty("SPECIFIC_PROXY_SERVICE_CONFIG_REPOSITORY", current.substring("file:".length()) + + "../basicConfig/eIDAS/"); + + } + + /** + * Initializer. + * @throws InterruptedException In case of an error + * + */ + @AfterClass + public static void closeIgniteNode() throws InterruptedException { + System.out.println("Closing Ignite Node ... "); + + log.info("Stopping already running Apache Ignite nodes ... "); + Ignition.stopAll(true); + Thread.sleep(1000); + + } + + /** + * Test reseter. + * + */ + @After + public void cleanJvmState() throws NoSuchFieldException, SecurityException, + IllegalArgumentException, IllegalAccessException { + final Field field = LogMessageProviderFactory.class.getDeclaredField("internalMessager"); + field.setAccessible(true); + field.set(null, new DummyStatusMessager()); + + System.clearProperty("eidas.ms.configuration"); + SpringBootApplicationInitializer.exit(); + + } + + + @Test + public void validConfigLocation() throws ClientProtocolException, IOException { + SpringBootApplicationInitializer + .main(new String[] { + "--spring.config.location=src/test/resources/config/junit_config_1_springboot.properties,classpath:/application.properties", + "--spring.profiles.active=jUnitTestMode,springBoot" }); + + System.out.println("Is started!"); + + // test Spring-Actuator http Basic-Auth + testSpringActuatorSecurity(); + + } + + private void testSpringActuatorSecurity() throws ClientProtocolException, IOException { + // check if authentication works on actuator end-point + final HttpClientBuilder builder = HttpClients.custom(); + final CloseableHttpClient client = builder.build(); + Assert.assertNotNull("httpClient", client); + + final HttpUriRequest httpGet1 = new HttpGet("http://localhost:8080/ms_connector/actuator/info"); + final CloseableHttpResponse httpResp1 = client.execute(httpGet1); + Assert.assertEquals("http statusCode", 200, httpResp1.getStatusLine().getStatusCode()); + + } + +} diff --git a/connector/src/test/java/at/asitplus/eidas/specific/connector/test/MainClassWebAppModeTest.java b/connector/src/test/java/at/asitplus/eidas/specific/connector/test/MainClassWebAppModeTest.java new file mode 100644 index 00000000..265edfb6 --- /dev/null +++ b/connector/src/test/java/at/asitplus/eidas/specific/connector/test/MainClassWebAppModeTest.java @@ -0,0 +1,129 @@ +package at.asitplus.eidas.specific.connector.test; + +import java.io.IOException; +import java.lang.reflect.Field; + +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.client.HttpClients; +import org.apache.ignite.Ignition; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.BlockJUnit4ClassRunner; + +import at.asitplus.eidas.specific.connector.SpringBootApplicationInitializer; +import at.gv.egiz.eaaf.core.impl.logging.DummyStatusMessager; +import at.gv.egiz.eaaf.core.impl.logging.LogMessageProviderFactory; + +@RunWith(BlockJUnit4ClassRunner.class) +public class MainClassWebAppModeTest { + + /** + * jUnit class initializer. + * + */ + @BeforeClass + public static void classInitializer() { + final String current = new java.io.File(".").toURI().toString(); + + //eIDAS Ref. Impl. properties + System.setProperty("EIDAS_CONFIG_REPOSITORY", current.substring("file:".length()) + + "../basicConfig/eIDAS/"); + System.setProperty("SPECIFIC_CONNECTOR_CONFIG_REPOSITORY", current.substring("file:".length()) + + "../basicConfig/eIDAS/"); + System.setProperty("SPECIFIC_PROXY_SERVICE_CONFIG_REPOSITORY", current.substring("file:".length()) + + "../basicConfig/eIDAS/"); + + } + + /** + * Initializer. + * + */ + @AfterClass + public static void closeIgniteNode() { + System.out.println("Closing Ignite Node ... "); + Ignition.stopAll(true); + + } + + /** + * Test reseter. + * + */ + @After + public void cleanJvmState() throws NoSuchFieldException, SecurityException, + IllegalArgumentException, IllegalAccessException { + final Field field = LogMessageProviderFactory.class.getDeclaredField("internalMessager"); + field.setAccessible(true); + field.set(null, new DummyStatusMessager()); + + System.clearProperty("eidas.ms.configuration"); + SpringBootApplicationInitializer.exit(); + + } + + @Test + public void wrongConfigLocation() { + //MS-specific connector property + final String current = new java.io.File(".").toURI().toString(); + System.setProperty("eidas.ms.configuration", current + + "src/test/resources/config/notextist.properties"); + + try { + //starting application + SpringBootApplicationInitializer + .main(new String[] { + "--spring.profiles.active=jUnitTestMode,springBoot" }); + Assert.fail("Missing configuration not detected"); + + } catch (final Exception e) { + Assert.assertNotNull("Exception is null", e); + + } + } + + + @Test + public void systemdConfigLocation() throws ClientProtocolException, IOException { + //MS-specific connector property + final String current = new java.io.File(".").toURI().toString(); + System.setProperty("eidas.ms.configuration", current + + "src/test/resources/config/junit_config_1_springboot.properties"); + + //starting application + SpringBootApplicationInitializer + .main(new String[] { + "--spring.profiles.active=jUnitTestMode,springBoot" }); + + System.out.println("Is started!"); + + // test Spring-Actuator http Basic-Auth + testSpringActuatorSecurity(); + + + + + } + + private void testSpringActuatorSecurity() throws ClientProtocolException, IOException { + // check if authentication works on actuator end-point + final HttpClientBuilder builder = HttpClients.custom(); + final CloseableHttpClient client = builder.build(); + Assert.assertNotNull("httpClient", client); + + final HttpUriRequest httpGet1 = new HttpGet("http://localhost:8080/ms_connector/actuator/info"); + final CloseableHttpResponse httpResp1 = client.execute(httpGet1); + Assert.assertEquals("http statusCode", 200, httpResp1.getStatusLine().getStatusCode()); + + } + +} diff --git a/connector/src/test/java/at/asitplus/eidas/specific/connector/test/BasicConfigurationTest.java b/connector/src/test/java/at/asitplus/eidas/specific/connector/test/config/BasicConfigurationTest.java index 6e52f113..86342f99 100644 --- a/connector/src/test/java/at/asitplus/eidas/specific/connector/test/BasicConfigurationTest.java +++ b/connector/src/test/java/at/asitplus/eidas/specific/connector/test/config/BasicConfigurationTest.java @@ -1,4 +1,4 @@ -package at.asitplus.eidas.specific.connector.test; +package at.asitplus.eidas.specific.connector.test.config; import java.net.MalformedURLException; import java.net.URL; diff --git a/connector/src/test/java/at/asitplus/eidas/specific/connector/test/AuthenticationDataBuilderTest.java b/connector/src/test/java/at/asitplus/eidas/specific/connector/test/utils/AuthenticationDataBuilderTest.java index 316dcb5f..87abb06f 100644 --- a/connector/src/test/java/at/asitplus/eidas/specific/connector/test/AuthenticationDataBuilderTest.java +++ b/connector/src/test/java/at/asitplus/eidas/specific/connector/test/utils/AuthenticationDataBuilderTest.java @@ -1,4 +1,4 @@ -package at.asitplus.eidas.specific.connector.test; +package at.asitplus.eidas.specific.connector.test.utils; import static at.asitplus.eidas.specific.connector.MsEidasNodeConstants.PROP_CONFIG_SP_NEW_EID_MODE; diff --git a/connector/src/test/java/at/asitplus/eidas/specific/connector/test/AuthnRequestValidatorTest.java b/connector/src/test/java/at/asitplus/eidas/specific/connector/test/utils/AuthnRequestValidatorTest.java index 389f561e..a9929a01 100644 --- a/connector/src/test/java/at/asitplus/eidas/specific/connector/test/AuthnRequestValidatorTest.java +++ b/connector/src/test/java/at/asitplus/eidas/specific/connector/test/utils/AuthnRequestValidatorTest.java @@ -1,4 +1,4 @@ -package at.asitplus.eidas.specific.connector.test; +package at.asitplus.eidas.specific.connector.test.utils; import java.io.IOException; import java.util.HashMap; diff --git a/connector/src/test/java/at/asitplus/eidas/specific/connector/test/CountrySelectionProcessImplTest.java b/connector/src/test/java/at/asitplus/eidas/specific/connector/test/utils/CountrySelectionProcessImplTest.java index 455288f5..d0343eba 100644 --- a/connector/src/test/java/at/asitplus/eidas/specific/connector/test/CountrySelectionProcessImplTest.java +++ b/connector/src/test/java/at/asitplus/eidas/specific/connector/test/utils/CountrySelectionProcessImplTest.java @@ -1,4 +1,4 @@ -package at.asitplus.eidas.specific.connector.test; +package at.asitplus.eidas.specific.connector.test.utils; import java.util.HashMap; import java.util.Map; diff --git a/connector/src/test/resources/config/junit_config_1.properties b/connector/src/test/resources/config/junit_config_1.properties index 78981b6a..429d3538 100644 --- a/connector/src/test/resources/config/junit_config_1.properties +++ b/connector/src/test/resources/config/junit_config_1.properties @@ -1,6 +1,7 @@ ## Basic service configuration eidas.ms.context.url.prefix=http://localhost eidas.ms.context.url.request.validation=false +eidas.ms.core.configRootDir=file:./ eidas.ms.context.use.clustermode=true diff --git a/connector/src/test/resources/config/junit_config_1_springboot.properties b/connector/src/test/resources/config/junit_config_1_springboot.properties new file mode 100644 index 00000000..7257df9b --- /dev/null +++ b/connector/src/test/resources/config/junit_config_1_springboot.properties @@ -0,0 +1,81 @@ +## embbeded Tomcat +tomcat.workingdir=./target/work +tomcat.ajp.enabled=true +tomcat.ajp.port=8009 +tomcat.ajp.networkAddress=127.0.0.1 +tomcat.ajp.additionalAttributes.secretrequired=true +tomcat.ajp.additionalAttributes.secret=junit + +## Basic service configuration +eidas.ms.context.url.prefix=http://localhost +eidas.ms.core.configRootDir=file:./src/test/resources/config/ + +eidas.ms.context.use.clustermode=true + +##Monitoring +eidas.ms.monitoring.eIDASNode.metadata.url= + +## extended validation of pending-request Id's +eidas.ms.core.pendingrequestid.digist.secret=pendingReqIdSecret + +## eIDAS Ref. Implementation connector ### +eidas.ms.auth.eIDAS.node_v2.forward.endpoint= + +eidas.ms.auth.eIDAS.szrclient.useTestService=true +eidas.ms.auth.eIDAS.szrclient.endpoint.prod= +eidas.ms.auth.eIDAS.szrclient.endpoint.test=http://localhost:1234/demoszr +eidas.ms.auth.eIDAS.szrclient.ssl.keyStore.path=keys/junit.jks +eidas.ms.auth.eIDAS.szrclient.ssl.keyStore.password=password +eidas.ms.auth.eIDAS.szrclient.ssl.trustStore.path= +eidas.ms.auth.eIDAS.szrclient.ssl.trustStore.password= + +#tech. AuthBlock signing for E-ID process +eidas.ms.auth.eIDAS.authblock.keystore.password=f/+saJBc3a}*/T^s +eidas.ms.auth.eIDAS.authblock.keystore.friendlyName=connectorkeypair +eidas.ms.auth.eIDAS.authblock.keystore.path=keys/teststore.jks +eidas.ms.auth.eIDAS.authblock.keystore.type=jks +eidas.ms.auth.eIDAS.authblock.key.alias=connectorkeypair +eidas.ms.auth.eIDAS.authblock.key.password=f/+saJBc3a}*/T^s + + +#Raw eIDAS Id data storage +eidas.ms.auth.eIDAS.szrclient.debug.logfullmessages=true +eidas.ms.auth.eIDAS.szrclient.debug.useDummySolution=true + + + +## PVP2 S-Profile end-point configuration +eidas.ms.pvp2.keystore.type=jks +eidas.ms.pvp2.keystore.path=keys/junit.jks +eidas.ms.pvp2.keystore.password=password +eidas.ms.pvp2.key.metadata.alias=meta +eidas.ms.pvp2.key.metadata.password=password +eidas.ms.pvp2.key.signing.alias=sig +eidas.ms.pvp2.key.signing.password=password +eidas.ms.pvp2.metadata.validity=24 + +eidas.ms.pvp2.metadata.organisation.name=JUnit +eidas.ms.pvp2.metadata.organisation.friendyname=For testing with jUnit +eidas.ms.pvp2.metadata.organisation.url=http://junit.test +eidas.ms.pvp2.metadata.contact.givenname=Max +eidas.ms.pvp2.metadata.contact.surname=Mustermann +eidas.ms.pvp2.metadata.contact.email=max@junit.test + +## Service Provider configuration +eidas.ms.sp.0.uniqueID=https://demo.egiz.gv.at/demoportal_moaid-2.0/sp/eidas/metadata +eidas.ms.sp.0.pvp2.metadata.truststore=keys/junit.jks +eidas.ms.sp.0.pvp2.metadata.truststore.password=password +eidas.ms.sp.0.friendlyName=jUnit test +#eidas.ms.sp.0.pvp2.metadata.url= +#eidas.ms.sp.0.policy.allowed.requested.targets=.* +#eidas.ms.sp.0.policy.hasBaseIdTransferRestriction=false + +## Service Provider configuration +eidas.ms.sp.1.uniqueID=https://demo.egiz.gv.at/junit_test +eidas.ms.sp.1.pvp2.metadata.truststore=keys/junit.jks +eidas.ms.sp.1.pvp2.metadata.truststore.password=password +eidas.ms.sp.1.friendlyName=jUnit test +eidas.ms.sp.1.pvp2.metadata.url=http://junit.test/metadata +eidas.ms.sp.1.policy.allowed.requested.targets=test +eidas.ms.sp.1.policy.hasBaseIdTransferRestriction=true + diff --git a/connector/src/test/resources/config/keys/teststore.jks b/connector/src/test/resources/config/keys/teststore.jks Binary files differnew file mode 100644 index 00000000..fcc6400c --- /dev/null +++ b/connector/src/test/resources/config/keys/teststore.jks |