From d670e4e661aaf55822fe43470c096f339d3d1a95 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Thu, 18 Mar 2021 09:18:51 +0100 Subject: [PATCH 01/54] Updated IDSCP2 to v0.3.3 --- libraryVersions.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraryVersions.yaml b/libraryVersions.yaml index 750220790..4159a3709 100644 --- a/libraryVersions.yaml +++ b/libraryVersions.yaml @@ -1,4 +1,4 @@ -idscp2: "0.3.2" +idscp2: "0.3.3" # Kotlin library/compiler version kotlin: "1.4.31" From fd24f778b7c5d8deff85ae5d65e947072619cb1c Mon Sep 17 00:00:00 2001 From: "Banse, Christian" Date: Mon, 22 Jun 2020 22:01:13 +0200 Subject: [PATCH 02/54] Added simple spring boot application with webconsole. Does not expose API yet Rebasing to upstream Signed-off-by: Christian Banse --- .gitignore | 4 +- build.gradle.kts | 90 ++++---- camel-idscp2-osgi/LICENSE.txt | 201 ------------------ camel-idscp2-osgi/README.md | 1 - camel-idscp2-osgi/bnd.bnd | 6 - camel-idscp2-osgi/build.gradle.kts | 54 ----- .../camel/idscp2/osgi/Idscp2OsgiComponent.kt | 72 ------- .../org/apache/camel/component/idscp2client | 17 -- .../org/apache/camel/component/idscp2server | 17 -- cxf-jaxws-patch/.gitignore | 5 - cxf-jaxws-patch/LICENSE.txt | 201 ------------------ cxf-jaxws-patch/README.md | 3 - cxf-jaxws-patch/bnd.bnd | 9 - cxf-jaxws-patch/build.gradle.kts | 6 - example-idscp2-client-server/build.gradle.kts | 15 ++ .../de/fhg/aisec/ids/ExampleConnector.kt | 34 +++ .../de/fhg/aisec/ids/ExampleIdscpClient.kt | 88 ++++++++ .../de/fhg/aisec/ids/ExampleIdscpServer.kt | 59 +++++ .../etc/consumer-core-protocol-test.p12 | Bin 0 -> 2709 bytes .../main/resources/etc/consumer-keystore.p12 | Bin 0 -> 2693 bytes .../etc/provider-core-protocol-test.p12 | Bin 0 -> 2709 bytes .../main/resources/etc/provider-keystore.p12 | Bin 0 -> 2693 bytes .../src/main/resources/etc/truststore.p12 | Bin 0 -> 2266 bytes ids-connector/build.gradle.kts | 38 ++++ .../fhg/aisec/ids/ConnectorConfiguration.kt | 94 ++++++++ .../de/fhg/aisec/ids/TrustedConnector.kt | 40 ++++ .../src/main/resources/application.yml | 4 + .../resources/deploy/flow-policy-example.pl | 45 ++++ .../src/main/resources/etc/custom.properties | 41 ++++ .../resources/etc/de.fhg.dfcontrol.rules.cfg | 5 + .../etc/idscp2/aisecconnector1-keystore.jks | Bin 0 -> 2527 bytes .../etc/idscp2/client-truststore_new.jks | Bin 0 -> 1974 bytes .../etc/import_ca_chain_into_keystore.sh | 10 + .../src/main/resources/etc/jetty.xml | 91 ++++++++ .../resources/etc/karaf_maven_settings.xml | 6 + .../org.apache.felix.fileinstall-deploy.cfg | 25 +++ .../etc/org.apache.karaf.management.cfg | 112 ++++++++++ .../resources/etc/org.ops4j.pax.logging.cfg | 102 +++++++++ .../resources/etc/org.ops4j.pax.url.mvn.cfg | 42 ++++ .../main/resources/etc/org.ops4j.pax.web.cfg | 64 ++++++ .../src/main/resources/etc/settings.mapdb | Bin 0 -> 2097152 bytes .../src/main/resources/etc/system.properties | 155 ++++++++++++++ .../etc/tls-webconsole/keystore_latest.jks | Bin 0 -> 5239 bytes .../src/main/resources/etc/users.properties | 37 ++++ ids-container-manager/build.gradle.kts | 6 +- .../aisec/ids/cm/ContainerManagerService.java | 5 + .../fhg/aisec/ids/cm/impl/docker/DockerCM.kt | 4 +- ids-dataflow-control/build.gradle.kts | 2 + .../dataflowcontrol/PolicyDecisionPoint.kt | 19 +- ids-infomodel-manager/build.gradle.kts | 2 + .../InfoModelService.kt | 11 +- ids-route-manager/build.gradle.kts | 4 + .../fhg/aisec/ids/rm/RouteManagerService.kt | 63 +++--- ids-settings/build.gradle.kts | 2 + .../aisec/ids/settings/SettingsComponent.kt | 17 +- ids-webconsole/build.gradle.kts | 8 +- .../fhg/aisec/ids/webconsole/WebConsole.java | 38 ++++ .../ids/webconsole/WebConsoleComponent.java | 31 +-- .../fhg/aisec/ids/webconsole/api/AppApi.java | 175 ++++++--------- .../fhg/aisec/ids/webconsole/api/CertApi.java | 100 +++++---- .../aisec/ids/webconsole/api/ConfigApi.java | 35 ++- .../ids/webconsole/api/ConnectionAPI.java | 3 + .../aisec/ids/webconsole/api/MetricAPI.java | 3 + .../aisec/ids/webconsole/api/PolicyApi.java | 11 +- .../aisec/ids/webconsole/api/RouteApi.java | 59 +---- .../aisec/ids/webconsole/api/SettingsApi.java | 49 ++--- .../fhg/aisec/ids/webconsole/api/UserApi.java | 89 ++++---- .../src/main/resources/www/proxy.conf.json | 4 +- .../ids/webconsole/api/RestApiTests.java | 6 +- jnr-unixsocket-wrapper/LICENSE.txt | 201 ------------------ jnr-unixsocket-wrapper/README.md | 1 - jnr-unixsocket-wrapper/bnd.bnd | 15 -- libraryVersions.yaml | 2 + settings.gradle.kts | 16 +- 74 files changed, 1524 insertions(+), 1250 deletions(-) delete mode 100644 camel-idscp2-osgi/LICENSE.txt delete mode 100644 camel-idscp2-osgi/README.md delete mode 100644 camel-idscp2-osgi/bnd.bnd delete mode 100644 camel-idscp2-osgi/build.gradle.kts delete mode 100644 camel-idscp2-osgi/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/osgi/Idscp2OsgiComponent.kt delete mode 100644 camel-idscp2-osgi/src/main/resources/META-INF/services/org/apache/camel/component/idscp2client delete mode 100644 camel-idscp2-osgi/src/main/resources/META-INF/services/org/apache/camel/component/idscp2server delete mode 100644 cxf-jaxws-patch/.gitignore delete mode 100644 cxf-jaxws-patch/LICENSE.txt delete mode 100644 cxf-jaxws-patch/README.md delete mode 100644 cxf-jaxws-patch/bnd.bnd delete mode 100644 cxf-jaxws-patch/build.gradle.kts create mode 100644 example-idscp2-client-server/build.gradle.kts create mode 100644 example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleConnector.kt create mode 100644 example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpClient.kt create mode 100644 example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpServer.kt create mode 100644 example-idscp2-client-server/src/main/resources/etc/consumer-core-protocol-test.p12 create mode 100644 example-idscp2-client-server/src/main/resources/etc/consumer-keystore.p12 create mode 100644 example-idscp2-client-server/src/main/resources/etc/provider-core-protocol-test.p12 create mode 100644 example-idscp2-client-server/src/main/resources/etc/provider-keystore.p12 create mode 100644 example-idscp2-client-server/src/main/resources/etc/truststore.p12 create mode 100644 ids-connector/build.gradle.kts create mode 100644 ids-connector/src/main/kotlin/de/fhg/aisec/ids/ConnectorConfiguration.kt create mode 100644 ids-connector/src/main/kotlin/de/fhg/aisec/ids/TrustedConnector.kt create mode 100644 ids-connector/src/main/resources/application.yml create mode 100644 ids-connector/src/main/resources/deploy/flow-policy-example.pl create mode 100644 ids-connector/src/main/resources/etc/custom.properties create mode 100644 ids-connector/src/main/resources/etc/de.fhg.dfcontrol.rules.cfg create mode 100644 ids-connector/src/main/resources/etc/idscp2/aisecconnector1-keystore.jks create mode 100644 ids-connector/src/main/resources/etc/idscp2/client-truststore_new.jks create mode 100644 ids-connector/src/main/resources/etc/import_ca_chain_into_keystore.sh create mode 100644 ids-connector/src/main/resources/etc/jetty.xml create mode 100644 ids-connector/src/main/resources/etc/karaf_maven_settings.xml create mode 100644 ids-connector/src/main/resources/etc/org.apache.felix.fileinstall-deploy.cfg create mode 100644 ids-connector/src/main/resources/etc/org.apache.karaf.management.cfg create mode 100644 ids-connector/src/main/resources/etc/org.ops4j.pax.logging.cfg create mode 100644 ids-connector/src/main/resources/etc/org.ops4j.pax.url.mvn.cfg create mode 100644 ids-connector/src/main/resources/etc/org.ops4j.pax.web.cfg create mode 100644 ids-connector/src/main/resources/etc/settings.mapdb create mode 100644 ids-connector/src/main/resources/etc/system.properties create mode 100644 ids-connector/src/main/resources/etc/tls-webconsole/keystore_latest.jks create mode 100644 ids-connector/src/main/resources/etc/users.properties create mode 100644 ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/WebConsole.java delete mode 100644 jnr-unixsocket-wrapper/LICENSE.txt delete mode 100644 jnr-unixsocket-wrapper/README.md delete mode 100644 jnr-unixsocket-wrapper/bnd.bnd diff --git a/.gitignore b/.gitignore index b9f68e59f..c4136c7ff 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ # IDEA *.iml +*.idea /.idea # VSCode @@ -45,4 +46,5 @@ out .lock # Version file -/version.txt \ No newline at end of file +/version.txt +etc/settings.mapdb diff --git a/build.gradle.kts b/build.gradle.kts index 901c34f3c..ee21fdafb 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -15,12 +15,23 @@ repositories { plugins { java maven - id("com.google.protobuf") version "0.8.15" - // WARNING: Versions 5.2.x onwards export java.* packages, which is not allowed in Felix OSGi Resolver! - // See http://karaf.922171.n3.nabble.com/Manifest-import-problems-td4059042.html - id("biz.aQute.bnd") version "5.1.2" apply false - id("org.jetbrains.kotlin.jvm") version "1.4.31" - id("com.github.jlouns.cpe") version "0.5.0" + + // Spring Boot + id("org.springframework.boot") version "2.3.4.RELEASE" apply false + id("io.spring.dependency-management") version "1.0.8.RELEASE" + + // Other needed plugins + id("com.moowork.node") version "1.3.1" apply false + // Latest version compiled with Java 11 + id("com.benjaminsproule.swagger") version "1.0.8" apply false + + // Protobuf + id("com.google.protobuf") version "0.8.12" apply false + + // Kotlin specific + kotlin("jvm") version "1.4.31" apply false + kotlin("plugin.spring") version "1.4.31" apply false + id("com.diffplug.spotless") version "5.11.0" id("com.github.jk1.dependency-license-report") version "1.16" } @@ -39,12 +50,6 @@ allprojects { version = "4.0.0" } -tasks.build { - subprojects.filter { it.name == "karaf-assembly" }.forEach { - dependsOn(it.tasks.build) - } -} - subprojects { repositories { mavenCentral() @@ -54,36 +59,25 @@ subprojects { maven("https://maven.iais.fraunhofer.de/artifactory/eis-ids-public/") } - apply(plugin = "biz.aQute.bnd.builder") apply(plugin = "java") - apply(plugin = "maven") - apply(plugin = "kotlin") - - java { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 - } - - tasks.test { - exclude("**/*IT.*") - } - - val integrationTest = tasks.register("integrationTest") { - include("**/*IT.*") - systemProperty("project.version", "$project.version") - } - - tasks.check { - dependsOn(integrationTest) - } + apply(plugin = "java-library") + apply(plugin = "org.jetbrains.kotlin.jvm") + apply(plugin = "io.spring.dependency-management") + + configure { + imports { + mavenBom("org.springframework.boot:spring-boot-dependencies:${libraryVersions["springBoot"]}") + } - tasks.withType { - testLogging { - events("failed") - exceptionFormat = TestExceptionFormat.FULL + imports { + // need to stick to 3.0 because of org.apache.camel.support.dump.RouteStatDump and ModelHelper + mavenBom("org.apache.camel.springboot:camel-spring-boot-dependencies:3.0.0") } } + // just to make bills of materials (bom) easier to see in the dependency tree + val bom by configurations.creating + // Configuration for dependencies that will be provided through features in the OSGi environment val providedByFeature by configurations.creating @@ -94,9 +88,8 @@ subprojects { val infomodelBundle by configurations.creating // Configurations for bundles grouped to dedicated features apart from the main ids feature - @Suppress("UNUSED_VARIABLE") val influxFeature by configurations.creating - @Suppress("UNUSED_VARIABLE") + val zmqFeature by configurations.creating // OSGi core dependencies which will just be there during runtime @@ -110,10 +103,25 @@ subprojects { dependencies { // Logging API - providedByBundle("org.slf4j", "slf4j-simple", libraryVersions["slf4j"]) + providedByBundle("org.slf4j", "slf4j-api", libraryVersions["slf4j"]) + + val implementation by configurations + val compileOnly by configurations + val testImplementation by configurations // Needed for kotlin modules, provided at runtime via kotlin-osgi-bundle in karaf-features-ids compileOnly("org.jetbrains.kotlin", "kotlin-stdlib-jdk8", libraryVersions["kotlin"]) + + // We need to explicitly specify the 1.4 version for all kotlin dependencies, + // because otherwise something (maybe a plugin) downgrades the kotlin version to 1.3, + // which produces errors in the kotlin compiler. This is really nasty. + configurations.all { + resolutionStrategy.eachDependency { + if (requested.group == "org.jetbrains.kotlin") { + useVersion(libraryVersions["kotlin"] ?: throw RuntimeException("kotlin version not set")) + } + } + } } tasks.withType { @@ -176,4 +184,4 @@ tasks.build { it.write(project.version.toString()) } } -} \ No newline at end of file +} diff --git a/camel-idscp2-osgi/LICENSE.txt b/camel-idscp2-osgi/LICENSE.txt deleted file mode 100644 index 261eeb9e9..000000000 --- a/camel-idscp2-osgi/LICENSE.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/camel-idscp2-osgi/README.md b/camel-idscp2-osgi/README.md deleted file mode 100644 index 2c92b5fc9..000000000 --- a/camel-idscp2-osgi/README.md +++ /dev/null @@ -1 +0,0 @@ -The _camel-idscp2_ module adds IDSCP2 support to the integrated Camel deployment. It creates a Camel Component to make IDSCP2 available for building Camel routes. IDSCP2 itself is contained in module _idscp2_. diff --git a/camel-idscp2-osgi/bnd.bnd b/camel-idscp2-osgi/bnd.bnd deleted file mode 100644 index f5c097400..000000000 --- a/camel-idscp2-osgi/bnd.bnd +++ /dev/null @@ -1,6 +0,0 @@ -Bundle-Name: IDS :: Camel IDSCP2 Support for OSGi -Bundle-SymbolicName: de.fhg.aisec.ids.camel.idscp2.osgi -Bundle-Description: Camel IDSCP2 protocol support for OSGi -Export-Package: \ - de.fhg.aisec.ids.camel.idscp2.osgi -Import-Package: * \ No newline at end of file diff --git a/camel-idscp2-osgi/build.gradle.kts b/camel-idscp2-osgi/build.gradle.kts deleted file mode 100644 index daa9bd266..000000000 --- a/camel-idscp2-osgi/build.gradle.kts +++ /dev/null @@ -1,54 +0,0 @@ -import org.gradle.plugins.ide.idea.model.IdeaModel - -@Suppress("UNCHECKED_CAST") -val libraryVersions = rootProject.extra.get("libraryVersions") as Map - -description = "Camel IDSCP2 Component" -version = libraryVersions["idscp2"] ?: error("IDSCP2 version not specified") - -plugins { - id("com.github.gmazzo.buildconfig") version "2.0.2" -} - -apply(plugin = "idea") - -buildConfig { - sourceSets.getByName("main") { - packageName("de.fhg.aisec.ids.informationmodelmanager") - buildConfigField("String", "INFOMODEL_VERSION", - "\"${libraryVersions["infomodel"] ?: error("Infomodel version not available")}\"") - } -} - -configure { - module { - // mark as generated sources for IDEA - generatedSourceDirs.add(File("${buildDir}/generated/source/buildConfig/main/main")) - } -} - -dependencies { - providedByBundle(project(":ids-api")) { isTransitive = false } - - providedByBundle("de.fhg.aisec.ids", "camel-idscp2", libraryVersions["idscp2"]) { - exclude("de.fraunhofer.iais.eis.ids.infomodel", "java") - exclude("de.fraunhofer.iais.eis.ids", "infomodel-serializer") - exclude("org.jetbrains.kotlin", "*") - exclude("org.jetbrains.kotlinx", "kotlinx-coroutines-core") - } - - implementation("de.fraunhofer.iais.eis.ids.infomodel", "java", libraryVersions["infomodel"]) - implementation("de.fraunhofer.iais.eis.ids", "infomodel-serializer", libraryVersions["infomodel"]) - - osgiCore("org.osgi", "osgi.cmpn", libraryVersions["osgiCompendium"]) - - providedByFeature("org.apache.camel", "camel-core", libraryVersions["camel"]) - - providedByFeature("com.google.protobuf", "protobuf-java", libraryVersions["protobuf"]) - - providedByBundle("com.google.guava", "guava", libraryVersions["guava"]) - - testImplementation("junit", "junit", libraryVersions["junit4"]) - testImplementation("org.apache.camel", "camel-test", libraryVersions["camel"]) - testImplementation("org.mockito", "mockito-core", libraryVersions["mockito"]) -} diff --git a/camel-idscp2-osgi/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/osgi/Idscp2OsgiComponent.kt b/camel-idscp2-osgi/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/osgi/Idscp2OsgiComponent.kt deleted file mode 100644 index bf40cb9c0..000000000 --- a/camel-idscp2-osgi/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/osgi/Idscp2OsgiComponent.kt +++ /dev/null @@ -1,72 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * camel-idscp2-osgi - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.camel.idscp2.osgi - -import de.fhg.aisec.ids.api.idscp2.Idscp2UsageControlInterface -import de.fhg.aisec.ids.api.settings.Settings -import de.fhg.aisec.ids.camel.idscp2.UsageControlMaps -import de.fhg.aisec.ids.camel.idscp2.Utils -import de.fhg.aisec.ids.informationmodelmanager.BuildConfig -import java.net.URI -import org.apache.camel.Exchange -import org.osgi.service.component.annotations.Activate -import org.osgi.service.component.annotations.Component -import org.osgi.service.component.annotations.Reference -import org.osgi.service.component.annotations.ReferenceCardinality - -@Suppress("unused") -@Component -class Idscp2OsgiComponent : Idscp2UsageControlInterface { - @Reference(cardinality = ReferenceCardinality.MANDATORY) private lateinit var settings: Settings - - init { - Utils.connectorUrlProducer = { settings.connectorProfile.connectorUrl } - Utils.maintainerUrlProducer = { settings.connectorProfile.maintainerUrl } - Utils.dapsUrlProducer = { settings.connectorConfig.dapsUrl } - Utils.infomodelVersion = BuildConfig.INFOMODEL_VERSION - } - - @Activate - fun activate() { - instance = this - } - - fun setSettings(settings: Settings) { - this.settings = settings - } - - override fun getExchangeContract(exchange: Exchange) = - UsageControlMaps.getExchangeContract(exchange) - - override fun isProtected(exchange: Exchange) = UsageControlMaps.isProtected(exchange) - - override fun protectBody(exchange: Exchange, contractUri: URI) = - UsageControlMaps.protectBody(exchange, contractUri) - - override fun unprotectBody(exchange: Exchange) = UsageControlMaps.unprotectBody(exchange) - - companion object { - private lateinit var instance: Idscp2OsgiComponent - - fun setInstance(instance: Idscp2OsgiComponent) { - Companion.instance = instance - } - } -} diff --git a/camel-idscp2-osgi/src/main/resources/META-INF/services/org/apache/camel/component/idscp2client b/camel-idscp2-osgi/src/main/resources/META-INF/services/org/apache/camel/component/idscp2client deleted file mode 100644 index f0e6faab9..000000000 --- a/camel-idscp2-osgi/src/main/resources/META-INF/services/org/apache/camel/component/idscp2client +++ /dev/null @@ -1,17 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -class=de.fhg.aisec.ids.camel.idscp2.client.Idscp2ClientComponent diff --git a/camel-idscp2-osgi/src/main/resources/META-INF/services/org/apache/camel/component/idscp2server b/camel-idscp2-osgi/src/main/resources/META-INF/services/org/apache/camel/component/idscp2server deleted file mode 100644 index 95abf4615..000000000 --- a/camel-idscp2-osgi/src/main/resources/META-INF/services/org/apache/camel/component/idscp2server +++ /dev/null @@ -1,17 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -class=de.fhg.aisec.ids.camel.idscp2.server.Idscp2ServerComponent diff --git a/cxf-jaxws-patch/.gitignore b/cxf-jaxws-patch/.gitignore deleted file mode 100644 index 9773bdd32..000000000 --- a/cxf-jaxws-patch/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -/bin/ -/build/ -/generated/ -/generated-sources/ -/target/ diff --git a/cxf-jaxws-patch/LICENSE.txt b/cxf-jaxws-patch/LICENSE.txt deleted file mode 100644 index 261eeb9e9..000000000 --- a/cxf-jaxws-patch/LICENSE.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/cxf-jaxws-patch/README.md b/cxf-jaxws-patch/README.md deleted file mode 100644 index 3cabd13b8..000000000 --- a/cxf-jaxws-patch/README.md +++ /dev/null @@ -1,3 +0,0 @@ -The _cxf-jaxws-patch_ module "injects" the recent version of javax.xml.ws* packages into the bundle -org.apache.cxf.cxf-rt-frontend-jaxws to prevent the bundle from crashing due to class javax.xml.ws.WebServiceFeature -missing in the respective package in Apache Felix. diff --git a/cxf-jaxws-patch/bnd.bnd b/cxf-jaxws-patch/bnd.bnd deleted file mode 100644 index 4d35f73fe..000000000 --- a/cxf-jaxws-patch/bnd.bnd +++ /dev/null @@ -1,9 +0,0 @@ -Bundle-Name: IDS :: JAXWS patch for Apache CXF -Import-Package: * -Export-Package:\ - javax.xml.ws*;version="2.4.0",\ - javax.xml.soap*,\ - org.glassfish.hk2.osgiresourcelocator -# The following line makes this bundle a "Fragment" to cxf-rt-frontend-jaxws, -# i.e. its classes will simply be added to the class path of cxf-rt-frontend-jaxws. -Fragment-Host: org.apache.cxf.cxf-rt-frontend-jaxws \ No newline at end of file diff --git a/cxf-jaxws-patch/build.gradle.kts b/cxf-jaxws-patch/build.gradle.kts deleted file mode 100644 index faa04f48b..000000000 --- a/cxf-jaxws-patch/build.gradle.kts +++ /dev/null @@ -1,6 +0,0 @@ -@Suppress("UNCHECKED_CAST") -val libraryVersions = rootProject.extra.get("libraryVersions") as Map - -dependencies { - implementation("javax.xml.ws", "jaxws-api", libraryVersions["jaxwsApi"]) -} diff --git a/example-idscp2-client-server/build.gradle.kts b/example-idscp2-client-server/build.gradle.kts new file mode 100644 index 000000000..845cfda41 --- /dev/null +++ b/example-idscp2-client-server/build.gradle.kts @@ -0,0 +1,15 @@ +plugins { + application + id("org.springframework.boot") +} + +springBoot { + mainClassName = "de.fhg.aisec.ids.ExampleConnector" +} + +dependencies { + // can and should be replaced by a reference to a maven published artifact later + implementation(project(":ids-connector")) + + implementation("org.springframework.boot:spring-boot-starter") +} \ No newline at end of file diff --git a/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleConnector.kt b/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleConnector.kt new file mode 100644 index 000000000..d6fbd1b5b --- /dev/null +++ b/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleConnector.kt @@ -0,0 +1,34 @@ +/*- + * ========================LICENSE_START================================= + * example-idscp2-client-server + * %% + * Copyright (C) 2021 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids + +import org.springframework.boot.autoconfigure.SpringBootApplication +import org.springframework.boot.runApplication + +@SpringBootApplication +open class ExampleConnector : TrustedConnector() { + + companion object { + @JvmStatic + fun main(args: Array) { + runApplication(*args) + } + } +} diff --git a/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpClient.kt b/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpClient.kt new file mode 100644 index 000000000..5c19b83ad --- /dev/null +++ b/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpClient.kt @@ -0,0 +1,88 @@ +/*- + * ========================LICENSE_START================================= + * example-idscp2-client-server + * %% + * Copyright (C) 2021 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids + +import java.io.File +import org.apache.camel.RoutesBuilder +import org.apache.camel.builder.RouteBuilder +import org.apache.camel.support.jsse.KeyManagersParameters +import org.apache.camel.support.jsse.KeyStoreParameters +import org.apache.camel.support.jsse.SSLContextParameters +import org.apache.camel.support.jsse.TrustManagersParameters +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration + +@Configuration +open class ExampleIdscpClient { + + @Bean("clientSslContext") + open fun createSSLContext(): SSLContextParameters { + val ctx = SSLContextParameters() + ctx.certAlias = "1.0.1" + ctx.keyManagers = KeyManagersParameters() + ctx.keyManagers.keyStore = KeyStoreParameters() + ctx.keyManagers.keyStore.resource = + File( + Thread.currentThread() + .contextClassLoader + .getResource("etc/provider-core-protocol-test.p12") + .path + ) + .path + ctx.keyManagers.keyStore.password = "password" + ctx.trustManagers = TrustManagersParameters() + ctx.trustManagers.keyStore = KeyStoreParameters() + ctx.trustManagers.keyStore.resource = + File( + Thread.currentThread() + .contextClassLoader + .getResource("etc/truststore.p12") + .path + ) + .path + ctx.trustManagers.keyStore.password = "password" + + return ctx + } + + @Bean + open fun client(): RoutesBuilder { + return object : RouteBuilder() { + override fun configure() { + from("timer://tenSecondsTimer?fixedRate=true&period=10000") + .setBody() + .simple("PING") + .setHeader("idscp2-header") + .simple("ping") + .log("Client sends: \${body} (Header: \${headers[idscp2-header]})") + .to( + "idscp2client://localhost:29292?awaitResponse=true&sslContextParameters=#clientSslContext" + ) + .log("Client received: \${body} (Header: \${headers[idscp2-header]})") + .removeHeader( + "idscp2-header" + ) // Prevents the client consumer from sending the message back to the server + .setBody() + .simple("\${null}") + } + } + } + +} diff --git a/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpServer.kt b/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpServer.kt new file mode 100644 index 000000000..4183e3c54 --- /dev/null +++ b/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpServer.kt @@ -0,0 +1,59 @@ +package de.fhg.aisec.ids + +import org.apache.camel.RoutesBuilder +import org.apache.camel.builder.RouteBuilder +import org.apache.camel.support.jsse.KeyManagersParameters +import org.apache.camel.support.jsse.KeyStoreParameters +import org.apache.camel.support.jsse.SSLContextParameters +import org.apache.camel.support.jsse.TrustManagersParameters +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import java.io.File + +@Configuration +open class ExampleIdscpServer { + @Bean("serverSslContext") + open fun createSSLContext(): SSLContextParameters { + val ctx = SSLContextParameters() + ctx.certAlias = "1.0.1" + ctx.keyManagers = KeyManagersParameters() + ctx.keyManagers.keyStore = KeyStoreParameters() + ctx.keyManagers.keyStore.resource = + File( + Thread.currentThread() + .contextClassLoader + .getResource("etc/consumer-core-protocol-test.p12") + .path + ) + .path + ctx.keyManagers.keyStore.password = "password" + ctx.trustManagers = TrustManagersParameters() + ctx.trustManagers.keyStore = KeyStoreParameters() + ctx.trustManagers.keyStore.resource = + File( + Thread.currentThread() + .contextClassLoader + .getResource("etc/truststore.p12") + .path + ) + .path + ctx.trustManagers.keyStore.password = "password" + + return ctx + } + + @Bean + open fun server(): RoutesBuilder? { + return object : RouteBuilder() { + override fun configure() { + from("idscp2server://0.0.0.0:29292?sslContextParameters=#serverSslContext") + .log("Server received: \${body} (Header: \${headers[idscp2-header]})") + .setBody() + .simple("PONG") + .setHeader("idscp2-header") + .simple("pong") + .log("Server response: \${body} (Header: \${headers[idscp2-header]})") + } + } + } +} \ No newline at end of file diff --git a/example-idscp2-client-server/src/main/resources/etc/consumer-core-protocol-test.p12 b/example-idscp2-client-server/src/main/resources/etc/consumer-core-protocol-test.p12 new file mode 100644 index 0000000000000000000000000000000000000000..b9022b7f7b58878a01de63efdf91d0df67d3e00d GIT binary patch literal 2709 zcmV;G3TpK*f(nrW0Ru3C3ReaRDuzgg_YDCD0ic2kNCbikL@M3t zMH4m#0s;sCfPw_D1jn0KTM5L?cD$TEiH*GiT%7LX$$K5YWT3$BM{QQ!UXf65UZmKO znKc*^mEH!eqQ!n{@YC#^!6EdTAHKr9rmEJoeyR~Up(B>SK6I+sibm*N=H+&>`g87O zSO7D}Ie^D0nvxy7fgn=CF9&cA2>02ZoPP2Lv&L9Q<;;Vx$kyoDNf2;Iqwch$fhALw z&W%rZJ5lB@D&%-h=Fw!%oU&HmD~M<XlYK`Qo z1r*r;)$}qyxy3P(MF!?J1XZSmAjM2zJN)}2_cQ1PNO8)0qy>t(Zj%y<=F}%ukI8NCE;3X?cHnLS
-3?R$*)FBmO3H&PfaLGrXlZSY>& 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 literal 0 HcmV?d00001 diff --git a/example-idscp2-client-server/src/main/resources/etc/provider-core-protocol-test.p12 b/example-idscp2-client-server/src/main/resources/etc/provider-core-protocol-test.p12 new file mode 100644 index 0000000000000000000000000000000000000000..020b5f1cf2e0c3e9b3caf400585d671f0e1d8231 GIT binary patch literal 2709 zcmV;G3TpK*f(nrW0Ru3C3ReaRDuzgg_YDCD0ic2kNCbikL@#&XqvO}`@x{FpbPaYqN`AwT71 z8D%sq#jhA0rY+I#0mu}4Ajr8ZMpU!gvdSSZ!Y`NH@$T~=`sLD>p9jobG;`v9!?Wl zoPP!I30jxWYR+EOTirf$5172y;mGhCq!anUDRw4RddIx6v~v6yS`WjI3;5-a;fjf> zi6R}2Oj2H8oOq>2PBGMRawSt#OBEh@3-#bAQclm}pSrXiHbAPE`Z|<#AP0yX_O~rL zy_ArV4FX=0?ZKA)mc3otNf&OhaZCtj8WH2na5uZScyz$L*tDVp%z#sZ`k=B~_n$~h zp5G5X1wB!|4s11T`ysf{2gBC7<@)jdn@eF}$$#4?*BUzGUc_f7u^KBfn|J}G%lKFiY_g#TSPqtN&h`y#chP`45H zo6F;FPADgu?M8rRY`*2W2qw~dOn)((@50bod00YW_u9RtMOxLu%vxh~FZFlfkGj{GS-D$*{$9kq zD1Wsmx72QB+S<`l4Ia+oCA#nmI!DPNXBS~P>tZ-QdPHr}2{F|e)d4bnk!H#K9WU2r zM;L5C;5~01nU|Xu5;T6P+QOFKQi$X+Z2m#{Sy&xjIIOY}*Mpr!2M7QYcw_`0)m%|( zw{SA0EhldOn)rX9vn&We43h!I3-%E6eX5F!Ms&eH1470{KFd8aDxX-vPk3QZJyVg0 z^o2NdKC4{xhVA-LD;iQcGm`LvO{#1Jc)?&<6I}uSEmxXf#;sSPI@NWibeBqZ^YvH& z^pe`F?y)Ja^Z5k(Z@#(10E?!QS4tiG4<3}YvnfomEvs<72RC24XqzgW!-2Id4^0{x z$L?|kqYej&i%(ky9_dq9Z0n^oZ;5d(DzwvbyLuB!u)}HeD*kmP6>rUY=F?)4p&FEi z^N7Y1Krcd~%TR|=mpX2b*2STn{N=KD4PGjQy_#pB$Fs52HbVeIm@POHQmUA%w!H7Q zoA~q|+AB;C|F2}^r?TUsFoFd^1_>&LNQUS_k#WVg0I64gV|SwFPk4> zzhU$hQD6C@g6FogFvYM48T}n|T>REaBrnh5HO?i^8k9CO?lvw17MmUs)X3P6d0up= zn@uR5`xY7^DNiA$tcuJd~frPOng?y}J_(9T06#Lfv&KsA5wE zLGvGANKXCrNr9so8gl8&o+JFER4f2`OKd5la@P0nV528LIi zj!3fqjl895GFD--4Fqr}KuD>1t$1;r4Td#M@ZEV%g=>V*iEq$ndqh+De_2a2-!CEr$Is{!4~nkqZHTi#WSe(?24dQ6tYehKj%25F+vB+-DR%~y7^O`lcJ z#~~eCkm2t|{yy^(bN74yuRuM6QqA4Uu`pP1Y_Bf``R$$h!TGzOJi?aT|MBYD>?$%^ zBPeYJ1`7nW$7bj+Z6^XZP;GXrk_`0c?}5-gdrmWA zU5hiO8!HrOm)5}`>uoqx=)cU$~&vSTw+ehsjW*I+^m7Yg`|2#)*6Awfi$fu4pHv`|A7>KHQgm3zIXTW8i46 z&EqXgt=H-J-^%db4N;1?~aWvEt}Q`j1|M;c4}LSYo@Me z4i>5X1Hu&jri9uf9v77U8c$|Q7wZkAhLO=I&jdw=PKI!k1Fg0dbarhLso940zKDOf z@q;!r8v|Uw#Pr5fa2O&o&0CGtN$7*KqL!NcK5MWn@z+Z)XGu P6LsbnYPsWf0s;sC@3->f literal 0 HcmV?d00001 diff --git a/example-idscp2-client-server/src/main/resources/etc/provider-keystore.p12 b/example-idscp2-client-server/src/main/resources/etc/provider-keystore.p12 new file mode 100644 index 0000000000000000000000000000000000000000..7c45bd3087048bbef49cfcbf4d4cd40a338a82c2 GIT binary patch literal 2693 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 literal 0 HcmV?d00001 diff --git a/example-idscp2-client-server/src/main/resources/etc/truststore.p12 b/example-idscp2-client-server/src/main/resources/etc/truststore.p12 new file mode 100644 index 0000000000000000000000000000000000000000..aa430cd6cea20b45cab4ee93b93ddb5bfa565792 GIT binary patch literal 2266 zcmV<02qpJ0f(X_E0Ru3C2#*E{Duzgg_YDCD0ic2ifCPdFd@zCtcrbzpbOs43hDe6@ z4FLxRpn?cxFoFnS0s#Opf(Tj$2`Yw2hW8Bt2LUiC1_~;MNQU6_}Q(yvfcC^&_cW>yQk#7^I_Wt0KctQ=k1`yr(d# zb;{`+63xwPvoOWD9ETRg$o}Djc(-5VqqNAi(~e`$Jssy-(RDqQX(jg7`kr&|?5$;7qey&L;K;G+Ywjj}N zyBSX-knuHx5!^vju>gYVJS$SiB<3PylUj5JN$Oge=LS6)uZ^fpdXX|LY=6Rt9DQ04 zV`FUftPZ7LtfP>ly7142kK=tPtclXZt`W9mw?tUxQ~&@{9*sm@c~RQ-EPtNxmc@6n zNYN4id|h3hz66q~-rawCg6x+>bZV;ocRNT`p7V7!Qou70Y=6L0PphATL1)#C=iQz6 zOD3evIJ2?$EccK66fL11J|BHT$PEtY+(3L{RcW||w@38yKMMk}O(b^P0iic6jq>M>3mG6ysV;)*j6`OQ0GsWw>aN^MJ2x=0Ki2mw5yw-34ZHFA2V8}mPov2wN;{VLJuK&; zP1?@ngT_;Ep1~sA+dFa9u4axP`JwJV3PmfBYlvtO=}Gi%eHY#d7{d`l`=6dMcM@7v zWu&2v*Gt+agxuPlQ9F;83GAOfPB2K_i9)v%b6Xh|oeZ|sM;Sht&S{v0L_)%A@_VmM z-$B-p4lb?sOC3vPa+XpxB3^8#)HMa*ay(fD2%|IiNz!<6 zmk>&2zRy9ujZK5|V-VlNy!Cn|pK$UIA1NbF1Se;XjBz=s(z zV^V@==Qqs7q<|>BDUF1}teO2ER#Om~g;RBr;tx!6wS)G(ZZg4P#45d;`SLSaDev7c zA;y^Yx(dfE0+>3&jJ@D|*m#+fFIQGHmFs@B)oU9iCc>Ny3w$oKRSM`D@s#F3d?fmA*Gi6kO=F0`!4y1OKyUr|(u2g+l z771#owy3aSd-kkXZ=&`kr$gB*P@Pml5JwK$C8ghMXT+?zfjtR&dW3`?#n86oI`~#) z*7!By8c#@`#xb#77z0BEbZON;L*1f)Z$VF z|6;XpQE3sou*&^%u#v@oBtU)SASL-^RB+rd^yTi z@q{o;j4Ka_+`if-%mT{3vy>OaSJmx?i(1=>p6qr?8xWhl=7xD7?KX6aYADM6K8_0B zr+6l(!2Q^^5_nl!Efb`tbMl1<1z1x;-xb2ensA-Fk{P!8Ca*I8BWfkTK~bkue#Wb& zdd38WlkgkZ!WU}-d{9c+E>}MY&ISqAY{ph!foUms&aOjgYR4%#Dh21F0c(H<)OkVI z8?3lc+Ha#&8&2bqKo~3GH;N8ej3HD%8;!k+ZNMl1>7#^3lb!VoL?#o0VrZuT9Zdzf zK4;)R7!CsL6bcrh^tel4il$0nPl5U1209G^rJ~sqx~kcod%Bvw17L3X@Wd^X&J-F}B;tFlBx)wXUx6r`4 z)nc_2q~%*k1a4t56^Ldi01ZJ;v&NO)8(T5(2WJFuF8(18!kk)al}*tB_KY{^-qBte z%wvOgf>hFgG4w>LJbeEp=LET#9k%K)EHFMWAutIB1uG5%0vZJX1QaB+4I|w6w3iur oMHiK}SS7VKy59s8_s+sV^Tu!qIt)hP^g8I#Y)O}U0s{etp!Rk@DF6Tf literal 0 HcmV?d00001 diff --git a/ids-connector/build.gradle.kts b/ids-connector/build.gradle.kts new file mode 100644 index 000000000..7e5bba381 --- /dev/null +++ b/ids-connector/build.gradle.kts @@ -0,0 +1,38 @@ +@Suppress("UNCHECKED_CAST") +val libraryVersions = rootProject.extra.get("libraryVersions") as Map + +plugins { + application + id("org.springframework.boot") + + kotlin("jvm") + kotlin("plugin.spring") +} + +tasks.getByName("bootJar") { + launchScript() + layered() +} + +dependencies { + api(project(":ids-webconsole")) + api(project(":ids-settings")) + api(project(":ids-container-manager")) + api(project(":ids-route-manager")) + api(project(":ids-infomodel-manager")) + api(project(":ids-dataflow-control")) + + // Camel Spring Boot integration + implementation("org.apache.camel.springboot:camel-spring-boot-starter") + + // Camel components + implementation("org.apache.camel.springboot:camel-rest-starter") + implementation("org.apache.camel.springboot:camel-http-starter") + + implementation("de.fhg.aisec.ids", "camel-idscp2", libraryVersions["idscp2"]) { + exclude("org.slf4j", "slf4j-simple") // needed until https://github.com/industrial-data-space/idscp2-java/pull/4 is merged + } + + // Spring Boot + implementation("org.springframework.boot:spring-boot-starter") +} diff --git a/ids-connector/src/main/kotlin/de/fhg/aisec/ids/ConnectorConfiguration.kt b/ids-connector/src/main/kotlin/de/fhg/aisec/ids/ConnectorConfiguration.kt new file mode 100644 index 000000000..5782ca25d --- /dev/null +++ b/ids-connector/src/main/kotlin/de/fhg/aisec/ids/ConnectorConfiguration.kt @@ -0,0 +1,94 @@ +/*- + * ========================LICENSE_START================================= + * ids-connector + * %% + * Copyright (C) 2021 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids + +import de.fhg.aisec.ids.api.cm.ContainerManager +import de.fhg.aisec.ids.api.infomodel.InfoModel +import de.fhg.aisec.ids.rm.RouteManagerService +import java.util.* +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.CommandLineRunner +import org.springframework.context.ApplicationContext +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration + +@Configuration +class ConnectorConfiguration { + + @Autowired(required = false) private var cml: ContainerManager? = null + + @Autowired private lateinit var im: InfoModel + + @Autowired private lateinit var rm: RouteManagerService + + @Bean + fun listBeans(ctx: ApplicationContext): CommandLineRunner? { + return CommandLineRunner { + val beans: Array = ctx.beanDefinitionNames + + Arrays.sort(beans) + + for (bean in beans) { + TrustedConnector.LOG.info("Loaded bean: {}", bean) + } + } + } + + @Bean + fun listContainers(ctx: ApplicationContext): CommandLineRunner? { + return CommandLineRunner { + val containers = cml?.list(false) + + for (container in containers ?: emptyList()) { + TrustedConnector.LOG.debug("Container: {}", container.names) + } + } + } + + @Bean + fun showConnectorProfile(ctx: ApplicationContext): CommandLineRunner? { + return CommandLineRunner { + val connector = im.connector + + if (connector == null) { + TrustedConnector.LOG.info("No connector profile stored yet.") + } else { + TrustedConnector.LOG.info("Connector profile: {}", connector) + } + } + } + + @Bean + fun showCamelInfo(ctx: ApplicationContext): CommandLineRunner? { + return CommandLineRunner { + val routes = rm.routes + + for (route in routes) { + TrustedConnector.LOG.debug("Route: {}", route.shortName) + } + + val components = rm.listComponents() + + for (component in components) { + TrustedConnector.LOG.debug("Component: {}", component.bundle) + } + } + } +} diff --git a/ids-connector/src/main/kotlin/de/fhg/aisec/ids/TrustedConnector.kt b/ids-connector/src/main/kotlin/de/fhg/aisec/ids/TrustedConnector.kt new file mode 100644 index 000000000..3e6e22821 --- /dev/null +++ b/ids-connector/src/main/kotlin/de/fhg/aisec/ids/TrustedConnector.kt @@ -0,0 +1,40 @@ +/*- + * ========================LICENSE_START================================= + * ids-connector + * %% + * Copyright (C) 2021 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids + +import java.util.* +import org.slf4j.LoggerFactory +import org.springframework.boot.autoconfigure.SpringBootApplication +import org.springframework.boot.runApplication + +/** Main startup class for the Trusted Connector using Spring Boot. */ +@SpringBootApplication +class TrustedConnector { + + companion object { + + val LOG = LoggerFactory.getLogger(TrustedConnector::class.java) + + @JvmStatic + fun main(args: Array) { + runApplication(*args) + } + } +} diff --git a/ids-connector/src/main/resources/application.yml b/ids-connector/src/main/resources/application.yml new file mode 100644 index 000000000..c6cea2df2 --- /dev/null +++ b/ids-connector/src/main/resources/application.yml @@ -0,0 +1,4 @@ +logging: + level: + ROOT: INFO + de.fhg.aisec: DEBUG \ No newline at end of file diff --git a/ids-connector/src/main/resources/deploy/flow-policy-example.pl b/ids-connector/src/main/resources/deploy/flow-policy-example.pl new file mode 100644 index 000000000..5d94233a6 --- /dev/null +++ b/ids-connector/src/main/resources/deploy/flow-policy-example.pl @@ -0,0 +1,45 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Prolog representation of a data flow policy +% +% Source: default +% +% Do not edit this file, it has been generated automatically +% by XText/Xtend. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% Only required for SWI-Prolog +% Allow the following predicates to be scattered around the prolog file. +% Otherwise Prolog will issue a warning if they are not stated in subsequent lines. +%:- discontiguous service/1. +%:- discontiguous has_endpoint/2. +%:- discontiguous creates_label/2. +%:- discontiguous removes_label/2. +%:- discontiguous rule/1. +%:- discontiguous rule_priority/2. +%:- discontiguous receives_label/1. +%:- discontiguous has_decision/2. +%:- discontiguous has_target/2. +%:- discontiguous has_capability/2. +%:- discontiguous has_property/3. +%:- discontiguous requires_prerequisites/2. +%:- discontiguous has_alternativedecision/2. +%:- discontiguous has_obligation/2. + +%%%%%%%%% Basic Blocking Rule %%%%%%%%%% +rule(dropAll). +rule_priority(dropAll,0). +has_decision(dropAll,drop). +receives_label(dropAll). +has_target(dropAll,serviceAll). + +%%%%%%%%%% Catch All Service %%%%%%%%%%% +service(serviceAll). +has_endpoint(serviceAll,'.*'). + +%%%%%%%%%%%%%%%% Rules %%%%%%%%%%%%%%%%% +% Allow everything +rule(allowAll). +rule_priority(allowAll, 1). +has_target(allowAll, serviceAll). +receives_label(allowAll). +has_decision(allowAll, allow). \ No newline at end of file diff --git a/ids-connector/src/main/resources/etc/custom.properties b/ids-connector/src/main/resources/etc/custom.properties new file mode 100644 index 000000000..9e1ee6462 --- /dev/null +++ b/ids-connector/src/main/resources/etc/custom.properties @@ -0,0 +1,41 @@ +################################################################################ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +################################################################################ + +# +# All the values specified here will override the default values given +# in config.properties. +# + +karaf.systemBundlesStartLevel=50 + +# +# You can place any customized configuration here. +# + +java.net.preferIPv4Stack=true + +# Disable shutdown port +karaf.shutdown.port=-1 + +# Re-enabled SSH server to allow attaching to a running Docker-version of the Trusted Connector. +# TODO: find a better solution to handle this. Pivotal story id: #157912999 +karaf.startRemoteShell=true + +# Reduce the default 20 threads to a reasonable size +org.apache.felix.eventadmin.ThreadPoolSize=3 diff --git a/ids-connector/src/main/resources/etc/de.fhg.dfcontrol.rules.cfg b/ids-connector/src/main/resources/etc/de.fhg.dfcontrol.rules.cfg new file mode 100644 index 000000000..fff7023ca --- /dev/null +++ b/ids-connector/src/main/resources/etc/de.fhg.dfcontrol.rules.cfg @@ -0,0 +1,5 @@ +LABEL .*input AS raw +LABEL .*process AS processed +REMOVELABEL raw FROM .*process +ALLOW raw TO .*process +ALLOW processed TO hdfs.* diff --git a/ids-connector/src/main/resources/etc/idscp2/aisecconnector1-keystore.jks b/ids-connector/src/main/resources/etc/idscp2/aisecconnector1-keystore.jks new file mode 100644 index 0000000000000000000000000000000000000000..8cac581c388491153679329a43ce082c6877ea64 GIT binary patch literal 2527 zcma)7c{tSD8=vo(rOY5ROvSaAvW@Q;W9<$ajeQA~J+ojcjL@Yd3?sU>a4(}|m+jh; zx}{vCv6gb_whA{(wh^w914=XpP8dEax+^LgL1F}pDffk2?b4s3UT zAhcMvQr6872pkG>U>l$~LR13*zyNiqBmlr6Fb?cv-KJ@&kq+ja7sO?NWIV!)lDM=O zThg^J9CI+W@tY}GMCmQHwPuFO4OMd*!6A0xpjm7WT$Jq;=N;vugZ0+`MTS{zD>ob%e25AL~8DpY!z+nh%`@Isikt8I|+syQq@DJ$T5ru^A<5_ z<5GeLvAa6URbw>9DO*ReBEe0gbu34*Fjx9Uw1SWO@vo@`CEw+zD;5@4)kIvL7DWQs z>wn}V55|=hni6%XxVPt3Q~Zu+g)Zh4m2{7jvk<(sXMOi0>Vx?uFT}5N6V;Whdf?h-# zF)%Ym?Y%C`pDCl%9kOP3iu>#0*-p=6vS#Wp2QWgGSEL>sbeek>pR_TDJ6rZL@3fQ$52GK0S*iZc4I!AjxXz z9ZS`(rv^gF&F^({3vtVYGQ?!#m2Zq_?N7?LzMDc;)-dT?x@B@Yr)RU*YcA$wtHB$` zW4`l;35;H~pFH;%w`hJk+2gp`J%NJe(K2t#lbkujMcn*G%N~o#@qzdTR{5Eduuznu zaa-d8WC4Dtn1=yNl6zgWkmFOeN~-PGaEfmj-CB;R{==+(@PLO=IJoj`)NNHl!NP-IW2ci9o%D z;`e$(i{u|?DCsBZCk^Gls^0;iKF3(BkAUESWDk)I5A%zNk4G&@i1J<=|rDKxcg?8b`JJUvrh;A*42y_ zO`nO8bz*v?x6g?FN}i;P_0t5~q&&`JLhA3N`)l#H*NVPBJ~!w3B|f5^$JL=eFQ~+eH!XiYI}F z5D4s=upnlG9Fgb(5hwtK0=q#m#7^}D%Y+p%06@VZpeX?b?nHdD%Va*re01^=4xG0nZ0FdmnT&-%}gEpi@(v+f^roH&% zUI#1VhTG`!^?Y?Cr8xb<_pMZPP8%yoY!3p%JMC#{FRPvEacVfR{WNO~F&m}UlocGF zG7~O%=5Nh9KkU^74LLNkDF1W(wPNYpX2@GDvsZQcKk1ED&(>9VrY^HD+-P$9w!wkL z!?w*{jc`Da0~us_>IB?WBV*&-Q;;-7*>Svea-JyX!WD=ZrRJ%lI#ON&#LD_uKf;42 z(yfd@8V|g;Y&2e6{tWPhE=HP0k`8k#* ziWjRVvz04*>r`keuZ|GlQ+^(=dS9o_EiVq^xKI%Q0u*zA^THQ72g(VbR!$s-gGs&Z zSx05Y69LI-udJ-ZhY?XH)~rE=t!Wk59uOBJ)sxI`;+`*8DeIB0+U=-4?o08S+?IUHMW&C-~{V*IT^|w0_=sy+!25y~J66OaoIXeT`3|at-9U8__5}t{{4hr&Rgt0>i z{}t;pOqgMi%P>&@DzS~bwo!5$G24jUMyYL--bUQNn^FLWI{ zI(_X2>9eX`jj#DAwSwUTF9md(%G;w@lV2Zy^Sm+csb*owj;iw0Bj^`FxKTT?rF^)^ zlz&xAU<_9rs!uhGbzFO*`^zKKYIm$>pi9i7OSx+nKcS}y#7%VY;d*{_{}Zc^dQZoE zWT}Kz61-k76P>5M-}b}uRIpwIW2PMWE-H$sj5G+AiE&fSef4pl+++mHKXHnOm9HOa zm>s=oQy#+pRQ-f`FS5ayvR35W)^RHF0OHIpj_wHm3g0$3lLuzR+9kffzq;>tzK;(h zr&(_oKJ`&#yUR$a4e7dDcq!SG$1tbpONmRd4^J$1DZPNN6y$1Pyv9;8RB%nIvx`Fs KwRVuWxBmm2L>qhn literal 0 HcmV?d00001 diff --git a/ids-connector/src/main/resources/etc/idscp2/client-truststore_new.jks b/ids-connector/src/main/resources/etc/idscp2/client-truststore_new.jks new file mode 100644 index 0000000000000000000000000000000000000000..998f04c7d601ba0540b4d4d15fe86bdcb7af0bbf GIT binary patch literal 1974 zcmezO_TO6u1_mZLW=c+EU|`Jf5m7g0V2#i-HLzr0V9qvZVoo<`V)9?W%*4pV#L2LU z@x9*Bv>WXPylk9WZ60mkc^Mg5Ss4tR47m+B*_cCF*o2u}Tn&W{1VJ1w9xk_{#L~Qs z{It{}LpcK(kRUUUsHaP?LQsBwi9$$fafyPnqk@rvp@o5*IIp3Fp@FfXp_!qPfl-t= zuQ8BoWCrC@#f~OMC1j^FvNA9?G4eAQG%<29H8CvpkK@{zD!3fL8WmPNPq_~x&Fw@qo$5yw>f^z%Zipp*lu$0)ca^by}UFXjJ-QyZ?{>+ZV)9WPPWv_2jS{fCjs&lH-W0AJn z^d`@i3n>%5^?q;5x~aP$C}VQp@AKi}X;aJWgPVg@UHk&fq9!lNkFaBXHhY0NA8+i_ z0|h1%t(fN-%nR$yK6gH$%}Ddu&jpRiqF$e_G?cswTARIFYr)q`)f4V%ADcNjK_c{Q z_q-7GTP|1ZCae^(R(4Tf{QLLpf@vwwp0dPEJAHcYPH;|SEiO$0XT+SFY+JMu8SxV^ zBfbM>#A}d@$jFEsg4{I8fF{5U2+Vv2MwZ|VXcA@MKtv{&F^~erGcc12gEBcde+QQ) z!Lm4^?6+E_C(QqrT35-%gSVdjJEkXlX2wb9;|r=H&qqG5@jDQwm3?>1vkmJM4k%n( zWv&{pG$U!(o-1X4P89uFp5kG)-PAZD(@k=FV1bFvhNg&8W6iMqlh41(Dg6<-eZFGO zN~O6gqQ3`)HTed1&Qp6Y(r*y`BceUJ`C-GRNBlWeWeayq(t8#haQL8tV;V2-&qF^h zo0Pr35$7su*`aXqw@F9hk+cPe1tJctZOfML_ddntp6}9fIC9deG*Ly7N>#??wqo-l z84qW^R&lRtdE3}~FXyK<>)157N;ibrNN7Cy_8h_%#>n1pqxPn8;3R< zu*_#?WMuI$a5Hd$@eP>TETCqjMyJrDyeHG|6o z!KqSj-)zyd{agKa!QYw;4yWw+wJm3*g11jl;{112E#n$j-WJx6t=(6%)q*aUGGw#; zy5KBQD;fNflWV%jv40{$Cu%Mn59m$5oqTVV=eg`$_O5mFERRlnzrL02cVNM#Bj2{L zt8KjXc+FOed5P!u`?=4S4b1Y%-??DNvK1R{JxO@1*&4G}H&rvC`l;9g`I=)%Z~u9) zG}_O%emwg|cZGCR_eZxl%g_5C^<^ZTee+9vMniO0Y-gh0r`;LVbKcZFJ($0dnWyoe zYrYYqA=e$%<_Ut+7Vmn}bu&WYORM6`YKBXK_xC*O*&X-8P$I!$Zrc3ySu?wxy5@h* jKJsPXQbv^>U)0#*vbc9$N>rMBDW~+|HRjd{yhWM-qpIG& literal 0 HcmV?d00001 diff --git a/ids-connector/src/main/resources/etc/import_ca_chain_into_keystore.sh b/ids-connector/src/main/resources/etc/import_ca_chain_into_keystore.sh new file mode 100644 index 000000000..b4875954e --- /dev/null +++ b/ids-connector/src/main/resources/etc/import_ca_chain_into_keystore.sh @@ -0,0 +1,10 @@ +#!/bin/bash +# +# Imports CA chain and connector cert into karaf keystore. Execute in $(Karaf-dir)/etc/keystores/ +# Then, build karaf. The keystore is automatically deployed. + +keytool -keystore keystore.jks -storepass password -importcert -trustcacerts -noprompt -alias root -file ../../../../../ssl/ca/rootca.cert +keytool -keystore keystore.jks -storepass password -importcert -alias ca -file ../../../../../ssl/ca/subca.cert +keytool -keystore keystore.jks -storepass password -importcert -alias client -file ../../../../../ssl/certs/client.cert +keytool -keystore keystore.jks -storepass password -importcert -alias server -file ../../../../../ssl/certs/server.cert + diff --git a/ids-connector/src/main/resources/etc/jetty.xml b/ids-connector/src/main/resources/etc/jetty.xml new file mode 100644 index 000000000..98e1ca6a5 --- /dev/null +++ b/ids-connector/src/main/resources/etc/jetty.xml @@ -0,0 +1,91 @@ + + + + + + + + https + + + + + + + + + + + + + + + + + + + + + /etc/tls-webconsole/keystore_latest.jks + + ids + ids + + + + + + SSL + SSLv2 + SSLv2Hello + SSLv3 + + + + + ^.*_(MD5|SHA|SHA1)$ + ^TLS_RSA_.*$ + ^SSL_.*$ + ^.*_NULL_.*$ + ^.*_anon_.*$ + + + + + + + + + + + + + + + + + + + http/1.1 + + + + + + + + + + + + + 0.0.0.0:8443 + + + + + + + + + \ No newline at end of file diff --git a/ids-connector/src/main/resources/etc/karaf_maven_settings.xml b/ids-connector/src/main/resources/etc/karaf_maven_settings.xml new file mode 100644 index 000000000..7f8349b4d --- /dev/null +++ b/ids-connector/src/main/resources/etc/karaf_maven_settings.xml @@ -0,0 +1,6 @@ + + \ No newline at end of file diff --git a/ids-connector/src/main/resources/etc/org.apache.felix.fileinstall-deploy.cfg b/ids-connector/src/main/resources/etc/org.apache.felix.fileinstall-deploy.cfg new file mode 100644 index 000000000..966ff752c --- /dev/null +++ b/ids-connector/src/main/resources/etc/org.apache.felix.fileinstall-deploy.cfg @@ -0,0 +1,25 @@ +################################################################################ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +################################################################################ + +felix.fileinstall.dir = ${karaf.base}/deploy +felix.fileinstall.tmpdir = ${karaf.data}/generated-bundles +felix.fileinstall.poll = 15000 +felix.fileinstall.start.level = 80 +felix.fileinstall.active.level = 80 +felix.fileinstall.log.level = 3 diff --git a/ids-connector/src/main/resources/etc/org.apache.karaf.management.cfg b/ids-connector/src/main/resources/etc/org.apache.karaf.management.cfg new file mode 100644 index 000000000..9a4141c9e --- /dev/null +++ b/ids-connector/src/main/resources/etc/org.apache.karaf.management.cfg @@ -0,0 +1,112 @@ + +# +# The properties in this file define the configuration of Apache Karaf's JMX Management +# + +# +# Port number for RMI registry connection +# +#rmiRegistryPort = 1099 +#rmiRegistryPort = -1 + +# +# Host for RMI registry +# +#rmiRegistryHost = 127.0.0.1 + +# +# Port number for RMI server connection +# +#rmiServerPort = 44444 +#rmiServerPort = -1 + +# +# Host for RMI server +# +#rmiServerHost = 127.0.0.1 + +# +# Name of the JAAS realm used for authentication +# +jmxRealm = karaf + +# +# The service URL for the JMXConnectorServer +# +#serviceUrl = service:jmx:rmi://127.0.0.1:44444/jndi/rmi://127.0.0.1:1099/karaf-root +# Empty service URL disabled JMXConnectorServer. This will generate an error in the logs but this is intended +serviceUrl = + +# +# Whether any threads started for the JMXConnectorServer should be started as daemon threads +# +daemon = true + +# +# Whether the JMXConnectorServer should be started in a separate thread +# +threaded = true + +# +# The ObjectName used to register the JMXConnectorServer +# +#objectName = connector:name=rmi + +# +# Timeout to lookup for the keystore in case of SSL authentication usage +# +#keyStoreAvailabilityTimeout = 5000 + +# +# The type of authentication +# +#authenticatorType = password +authenticatorType = password + +# +# Enable or not SSL/TLS +# +#secured = false + +# +# Secure algorithm to use +# +#secureAlgorithm = default + +# +# Secure protocol to use +# +#secureProtocol = TLS + +# +# Keystore to use for secure mode +# +#keyStore = karaf.ks + +# +# Alias of the key to use in the keystore +# +#keyAlias = karaf + +# +# Truststore to use for secure mode +# +#trustStore = karaf.ts + +# +# Create the JMX RMI registry +# +#createRmiRegistry = true +createRmiRegistry = false + +# +# Locate the JMX RMI registry +# +#locateRmiRegistry = true +locateRmiRegistry = false + +# +# Locate an existing MBean server if possible (useful when Karaf is embedded) +# +#locateExistingMBeanServerIfPossible = true + diff --git a/ids-connector/src/main/resources/etc/org.ops4j.pax.logging.cfg b/ids-connector/src/main/resources/etc/org.ops4j.pax.logging.cfg new file mode 100644 index 000000000..0964e6264 --- /dev/null +++ b/ids-connector/src/main/resources/etc/org.ops4j.pax.logging.cfg @@ -0,0 +1,102 @@ +################################################################################ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +################################################################################ + +# Common pattern layout for appenders +log4j2.pattern = %d{ISO8601} | %-5p | %-16t | %-32c{1} | %X{bundle.id} - %X{bundle.name} - %X{bundle.version} | %m%n + +# Root logger +log4j2.rootLogger.level = INFO +# uncomment to use asynchronous loggers, which require mvn:com.lmax/disruptor/3.3.2 library +#log4j2.rootLogger.type = asyncRoot +#log4j2.rootLogger.includeLocation = false +log4j2.rootLogger.appenderRef.RollingFile.ref = RollingFile +log4j2.rootLogger.appenderRef.PaxOsgi.ref = PaxOsgi +log4j2.rootLogger.appenderRef.Console.ref = Console +log4j2.rootLogger.appenderRef.Console.filter.threshold.type = ThresholdFilter +log4j2.rootLogger.appenderRef.Console.filter.threshold.level = OFF + +# Loggers configurations useful for debugging + +log4j2.logger.ids.name = de.fhg.aisec.ids +log4j2.logger.ids.level = DEBUG + +# Felix logger +#log4j2.logger.felix.name = org.apache.felix +#log4j2.logger.felix.level = DEBUG + +# Karaf logger +#log4j2.logger.karaf.name = org.apache.karaf +#log4j2.logger.karaf.level = DEBUG + +# Spifly logger +log4j2.logger.spifly.name = org.apache.aries.spifly +log4j2.logger.spifly.level = INFO + +# Security audit logger +log4j2.logger.audit.name = org.apache.karaf.jaas.modules.audit +log4j2.logger.audit.level = INFO +log4j2.logger.audit.additivity = false +log4j2.logger.audit.appenderRef.AuditRollingFile.ref = AuditRollingFile + +# Appenders configuration + +# Console appender not used by default (see log4j2.rootLogger.appenderRefs) +log4j2.appender.console.type = Console +log4j2.appender.console.name = Console +log4j2.appender.console.layout.type = PatternLayout +log4j2.appender.console.layout.pattern = %d{ISO8601} | %-5p | %-16t | %-32c{1} | %X{bundle.id} - %X{bundle.name} - %X{bundle.version} | %m%n + +# Rolling file appender +log4j2.appender.rolling.type = RollingRandomAccessFile +log4j2.appender.rolling.name = RollingFile +log4j2.appender.rolling.fileName = log/karaf.log +log4j2.appender.rolling.filePattern = log/karaf.log.%i +# uncomment to not force a disk flush +#log4j2.appender.rolling.immediateFlush = false +log4j2.appender.rolling.append = true +log4j2.appender.rolling.layout.type = PatternLayout +log4j2.appender.rolling.layout.pattern = %d{ISO8601} | %-5p | %-16t | %-32c{1} | %X{bundle.id} - %X{bundle.name} - %X{bundle.version} | %m%n +log4j2.appender.rolling.policies.type = Policies +log4j2.appender.rolling.policies.size.type = SizeBasedTriggeringPolicy +log4j2.appender.rolling.policies.size.size = 16MB + +# Audit file appender +log4j2.appender.audit.type = RollingRandomAccessFile +log4j2.appender.audit.name = AuditRollingFile +log4j2.appender.audit.fileName = security/audit.log +log4j2.appender.audit.filePattern = security/audit.log.%i +log4j2.appender.audit.append = true +log4j2.appender.audit.layout.type = PatternLayout +log4j2.appender.audit.layout.pattern = %d{ISO8601} | %-5p | %-16t | %-32c{1} | %X{bundle.id} - %X{bundle.name} - %X{bundle.version} | %m%n +log4j2.appender.audit.policies.type = Policies +log4j2.appender.audit.policies.size.type = SizeBasedTriggeringPolicy +log4j2.appender.audit.policies.size.size = 8MB + +# OSGi appender +log4j2.appender.osgi.type = PaxOsgi +log4j2.appender.osgi.name = PaxOsgi +log4j2.appender.osgi.filter = * + +# help with identification of maven-related problems with pax-url-aether +#log4j2.logger.aether.name = shaded.org.eclipse.aether +#log4j2.logger.aether.level = TRACE +#log4j2.logger.http-headers.name = shaded.org.apache.http.headers +#log4j2.logger.http-headers.level = DEBUG +#log4j2.logger.maven.name = org.ops4j.pax.url.mvn +#log4j2.logger.maven.level = TRACE diff --git a/ids-connector/src/main/resources/etc/org.ops4j.pax.url.mvn.cfg b/ids-connector/src/main/resources/etc/org.ops4j.pax.url.mvn.cfg new file mode 100644 index 000000000..b675f9cb8 --- /dev/null +++ b/ids-connector/src/main/resources/etc/org.ops4j.pax.url.mvn.cfg @@ -0,0 +1,42 @@ +################################################################################## +# +# This overrides Karaf's default org.ops4j.pax.url.mvn.cfg file to make sure +# that Karaf does not use any online repositories to pull in features or bundles. +# +################################################################################## + +# Make sure that no custom maven settings are used +org.ops4j.pax.url.mvn.settings=${karaf.home}/etc/karaf_maven_settings.xml + +# Local repositories containing all required core bundles +org.ops4j.pax.url.mvn.defaultRepositories=file:${karaf.home}/system@snapshots +org.ops4j.pax.url.mvn.localRepository=${karaf.home}/system@snapshots +org.ops4j.pax.url.mvn.useFallbackRepositories=false + + +# Remote repositories that are used when resolution of "org.ops4j.pax.url.mvn.defaultRepositories" fails +org.ops4j.pax.url.mvn.repositories= \ + https://repo1.maven.org/maven2@id=central, \ + https://repository.apache.org/content/groups/snapshots-group@id=apache@snapshots@noreleases, \ + https://oss.sonatype.org/content/repositories/ops4j-snapshots@id=ops4j.sonatype.snapshots.deploy@snapshots@noreleases + +# +# default value for connection and read timeouts, when socket.readTimeout and socket.connectionTimeout +# are not specified +org.ops4j.pax.url.mvn.timeout = 5000 +# timeout in ms when establishing http connection during artifact resolution +org.ops4j.pax.url.mvn.socket.connectionTimeout = 5000 +# timeout in ms when reading data after connecting to remote repository +org.ops4j.pax.url.mvn.socket.readTimeout = 30000 +# SO_KEEPALIVE option for sockets, defaults to false +org.ops4j.pax.url.mvn.socket.keepAlive = false +# SO_LINGER option for sockets, defaults to -1 +org.ops4j.pax.url.mvn.socket.linger = -1 +# SO_REUSEADDR option for sockets, defaults to false +org.ops4j.pax.url.mvn.socket.reuseAddress = false +# TCP_NODELAY option for sockets, defaults to true +org.ops4j.pax.url.mvn.socket.tcpNoDelay = true +# Configure buffer size for HTTP connections (output and input buffers), defaults to 8192 bytes +org.ops4j.pax.url.mvn.connection.bufferSize = 8192 +# Number of connection retries after failure is detected in http client. httpclient uses default value "3" +org.ops4j.pax.url.mvn.connection.retryCount = 3 \ No newline at end of file diff --git a/ids-connector/src/main/resources/etc/org.ops4j.pax.web.cfg b/ids-connector/src/main/resources/etc/org.ops4j.pax.web.cfg new file mode 100644 index 000000000..8463d022d --- /dev/null +++ b/ids-connector/src/main/resources/etc/org.ops4j.pax.web.cfg @@ -0,0 +1,64 @@ +# Explicitly make pax-web aware of our jetty configuration +org.ops4j.pax.web.config.file = ${karaf.etc}/jetty.xml + +# +# min server threads +# +org.ops4j.pax.web.server.minThreads = 1 + +# +# max server threads +# +org.ops4j.pax.web.server.maxThreads = 20 + +# +# enable https +# +org.osgi.service.http.secure.enabled = true + +# +# http port. +# This is currently also in the setenv +org.osgi.service.http.port = 8181 + +# +# https port, default is 8443. +# This is currently also in the setenv +org.osgi.service.http.port.secure = 8443 + +org.ops4j.pax.web.ssl.keystore = ${karaf.etc}/test.jks +org.ops4j.pax.web.ssl.password = ids +org.ops4j.pax.web.ssl.keypassword = ids + +# +# The number of minutes after which an inactive session will timeout. +# +org.ops4j.pax.web.session.timeout = 2 + +# +# Specifies if the connections established use the nio classes from java. +# +org.osgi.service.http.useNIO = true + +# +# Set to true if certificate-based client authentication at the server is "wanted". +# +org.ops4j.pax.web.ssl.clientauthwanted = false + +# +# Set to true if certificate-based client authentication at the server is "required". +# +org.ops4j.pax.web.ssl.clientauthneeded = false + +# +# The time in milliseconds that the connection can be idle before it is closed. +# +org.ops4j.pax.web.server.idleTimeout = 10000 + +# +# Listening addresses. This should match host in the sslconnector/name attribute in jetty.xml +# Default is 0.0.0.0 +# This is currently also in the setenv +# +#org.ops4j.pax.web.listening.addresses = 0.0.0.0 + diff --git a/ids-connector/src/main/resources/etc/settings.mapdb b/ids-connector/src/main/resources/etc/settings.mapdb new file mode 100644 index 0000000000000000000000000000000000000000..dae8b18ff5a441150281270e9f64152dfcab9745 GIT binary patch literal 2097152 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 zovVeL>y00N>DSI?@2t0n009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ lfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+z^|mh{{qWg%iRC~ literal 0 HcmV?d00001 diff --git a/ids-connector/src/main/resources/etc/system.properties b/ids-connector/src/main/resources/etc/system.properties new file mode 100644 index 000000000..3c042fc0d --- /dev/null +++ b/ids-connector/src/main/resources/etc/system.properties @@ -0,0 +1,155 @@ +################################################################################ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +################################################################################ + +# +# The properties defined in this file will be made available through system +# properties at the very beginning of the Karaf's boot process. +# + + +# Log level when the pax-logging service is not available +# This level will only be used while the pax-logging service bundle +# is not fully available. +# To change log levels, please refer to the org.ops4j.pax.logging.cfg file +# instead. +org.ops4j.pax.logging.DefaultServiceLog.level = ERROR + +# +# Name of this Karaf instance. +# +karaf.name = root + +# +# Default repository where bundles will be loaded from before using +# other Maven repositories. For the full Maven configuration, see +# the org.ops4j.pax.url.mvn.cfg file. +# +karaf.default.repository = system + +# +# Location of a shell script that will be run when starting a shell +# session. This script can be used to create aliases and define +# additional commands. +# +karaf.shell.init.script = shell.init.script + +# +# Sets the maximum size of the shell command history. If not set, +# defaults to 500 entries. Setting to 0 will disable history. +# +# karaf.shell.history.maxSize = 0 + +# +# Deletes the entire karaf.data directory at every start +# +karaf.clean.all = false + +# +# Deletes the karaf.data/cache directory at every start +# +karaf.clean.cache = true + +# +# User name for the Karaf local console +# +karaf.local.user = karaf + +# +# Roles to use when for the default user in the local Karaf console. +# +# The syntax is the following: +# [classname:]principal +# where classname is the class name of the principal object +# (defaults to org.apache.karaf.jaas.modules.RolePrincipal) +# and principal is the name of the principal of that class +# (defaults to instance). +# +karaf.local.roles = admin,manager,viewer,systembundles + +# +# Set this empty property to avoid errors when validating xml documents. +# +xml.catalog.files = + +# +# Suppress the bell in the console when hitting backspace too many times +# for example +# +jline.nobell = true + +# +# ServiceMix specs options +# +org.apache.servicemix.specs.debug = false +org.apache.servicemix.specs.timeout = 0 + +# +# Settings for the OSGi 4.3 Weaving +# By default, we will not weave any classes. Change this setting to include classes +# that you application needs to have woven. +# +org.apache.aries.proxy.weaving.enabled = none +# Classes not to weave - Aries default + Xerces which is known to have issues. +org.apache.aries.proxy.weaving.disabled = org.objectweb.asm.*,org.slf4j.*,org.apache.log4j.*,javax.*,org.apache.xerces.* + +# +# By default, only Karaf shell commands are secured, but additional services can be +# secured by expanding this filter +# +karaf.secured.services = (&(osgi.command.scope=*)(osgi.command.function=*)) + +# +# By default, if there's no ACL policy for a certain karaf command, this command is allowed to access +# without the RBAC. We can change this behavior by enable the following property, which means +# if a karaf command has no corresponding ACL then access it must have one of the karaf.secured.command.compulsory.roles +# +#karaf.secured.command.compulsory.roles=admin + +# +# Security properties +# +# To enable OSGi security, uncomment the properties below, +# install the framework-security feature and restart. +# +#java.security.policy=${karaf.etc}/all.policy +#org.osgi.framework.security=osgi +#org.osgi.framework.trust.repositories=${karaf.etc}/trustStore.ks + +# +# HA/Lock configuration +# +# Karaf uses a lock mechanism to know which instance is the master (HA) +# The lock can be on the filesystem (default) or on a database. +# +# See http://karaf.apache.org/manual/latest/users-guide/failover.html for details. +# +# Even using a single instance, Karaf creates the lock file +# You can specify the location of the lock file using the +# karaf.lock.dir=/path/to/the/directory/containing/the/lock +# +# By default, the slave instances start but are passive. +# If you want to prevent the slave instances startup, you can use +# the karaf.lock.slave.block property (false by default): +# karaf.lock.slave.block=true + +javax.net.ssl.keyStore=${karaf.etc}/provider-keystore.p12 +javax.net.ssl.keyStorePassword=password +javax.net.ssl.trustStore=${karaf.etc}/truststore.p12 +javax.net.ssl-trustStorePassword=password + diff --git a/ids-connector/src/main/resources/etc/tls-webconsole/keystore_latest.jks b/ids-connector/src/main/resources/etc/tls-webconsole/keystore_latest.jks new file mode 100644 index 0000000000000000000000000000000000000000..bd19b8f5c0b2c5fd6a92e95e34065036fbfd9bb3 GIT binary patch literal 5239 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 literal 0 HcmV?d00001 diff --git a/ids-connector/src/main/resources/etc/users.properties b/ids-connector/src/main/resources/etc/users.properties new file mode 100644 index 000000000..7a8e789be --- /dev/null +++ b/ids-connector/src/main/resources/etc/users.properties @@ -0,0 +1,37 @@ +################################################################################ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +################################################################################ + +# +# This file contains the users, groups, and roles. +# Each line has to be of the format: +# +# USER=PASSWORD,ROLE1,ROLE2,... +# USER=PASSWORD,_g_:GROUP,... +# _g_\:GROUP=ROLE1,ROLE2,... +# +# All users, groups, and roles entered in this file are available after Karaf startup +# and modifiable via the JAAS command group. These users reside in a JAAS domain +# with the name "karaf". +# +karaf = karaf,_g_:admingroup +ids = ids,_g_:idsgroup +# Re-enabled SSH server to allow attaching to a running Docker-version of the Trusted Connector. +# TODO: find a better solution to handle this. Pivotal story id: #157912999 +_g_\:admingroup = group,admin,manager,viewer,systembundles,ssh +_g_\:idsgroup = group,manager,api,viewer diff --git a/ids-container-manager/build.gradle.kts b/ids-container-manager/build.gradle.kts index 92875d3fd..4d0890b69 100644 --- a/ids-container-manager/build.gradle.kts +++ b/ids-container-manager/build.gradle.kts @@ -33,6 +33,8 @@ configure { dependencies { providedByBundle(project(":ids-api")) { isTransitive = false } + implementation("org.springframework.boot:spring-boot-starter") + // Provided dependency of docker-java-api providedByBundle("org.glassfish", "javax.json", libraryVersions["javaxJson"]) // Required until our library PR has been accepted @@ -40,7 +42,9 @@ dependencies { exclude("com.github.jnr", "jnr-unixsocket") } - implementation(project(":jnr-unixsocket-wrapper")) + //implementation(project(":jnr-unixsocket-wrapper")) + implementation("com.github.jnr", "jnr-unixsocket", libraryVersions["jnrunix"]) + implementation("com.github.jnr", "jnr-ffi", libraryVersions["jnrffi"]) providedByBundle("com.google.protobuf", "protobuf-java", libraryVersions["protobuf"]) diff --git a/ids-container-manager/src/main/java/de/fhg/aisec/ids/cm/ContainerManagerService.java b/ids-container-manager/src/main/java/de/fhg/aisec/ids/cm/ContainerManagerService.java index 63210c356..b8b83d447 100644 --- a/ids-container-manager/src/main/java/de/fhg/aisec/ids/cm/ContainerManagerService.java +++ b/ids-container-manager/src/main/java/de/fhg/aisec/ids/cm/ContainerManagerService.java @@ -43,10 +43,15 @@ * @author Julian Schütte (julian.schuette@aisec.fraunhofer.de) */ @Component(name = "ids-cml", immediate = true) +@org.springframework.stereotype.Component public class ContainerManagerService implements ContainerManager { private static final Logger LOG = LoggerFactory.getLogger(ContainerManagerService.class); private ContainerManager containerManager = null; + public ContainerManagerService() { + activate(); + } + @Activate protected void activate() { LOG.info("Activating Container Manager"); diff --git a/ids-container-manager/src/main/java/de/fhg/aisec/ids/cm/impl/docker/DockerCM.kt b/ids-container-manager/src/main/java/de/fhg/aisec/ids/cm/impl/docker/DockerCM.kt index 4e83dc66a..5cf1f0412 100644 --- a/ids-container-manager/src/main/java/de/fhg/aisec/ids/cm/impl/docker/DockerCM.kt +++ b/ids-container-manager/src/main/java/de/fhg/aisec/ids/cm/impl/docker/DockerCM.kt @@ -50,6 +50,7 @@ class DockerCM : ContainerManager { listOf(ChronoUnit.YEARS, ChronoUnit.MONTHS, ChronoUnit.DAYS) private val DURATION_UNITS = listOf(ChronoUnit.HOURS, ChronoUnit.MINUTES, ChronoUnit.SECONDS) + /** * Returns true if Docker is supported. * @@ -59,10 +60,11 @@ class DockerCM : ContainerManager { get() { return try { DOCKER_CLIENT.ping() - } catch (e: Exception) { + } catch (e: Throwable) { when (e) { is UninitializedPropertyAccessException -> LOG.warn("Docker client is not available") + is UnsatisfiedLinkError -> LOG.warn("Docker client is not available") else -> LOG.error(e.message, e) } false diff --git a/ids-dataflow-control/build.gradle.kts b/ids-dataflow-control/build.gradle.kts index 610ecd901..57a9d01e6 100644 --- a/ids-dataflow-control/build.gradle.kts +++ b/ids-dataflow-control/build.gradle.kts @@ -6,6 +6,8 @@ dependencies { providedByBundle(project(":ids-api")) { isTransitive = false } + implementation("org.springframework.boot:spring-boot-starter") + providedByBundle("com.google.guava", "guava", libraryVersions["guava"]) implementation("it.unibo.alice.tuprolog", "2p-core", libraryVersions["2p"]) diff --git a/ids-dataflow-control/src/main/kotlin/de/fhg/aisec/ids/dataflowcontrol/PolicyDecisionPoint.kt b/ids-dataflow-control/src/main/kotlin/de/fhg/aisec/ids/dataflowcontrol/PolicyDecisionPoint.kt index 9b37ec292..6e46b6d8f 100644 --- a/ids-dataflow-control/src/main/kotlin/de/fhg/aisec/ids/dataflowcontrol/PolicyDecisionPoint.kt +++ b/ids-dataflow-control/src/main/kotlin/de/fhg/aisec/ids/dataflowcontrol/PolicyDecisionPoint.kt @@ -37,18 +37,20 @@ import java.io.File import java.util.* import java.util.concurrent.ExecutionException import java.util.concurrent.TimeUnit +import javax.annotation.PostConstruct import org.osgi.service.component.ComponentContext import org.osgi.service.component.annotations.* import org.slf4j.LoggerFactory +import org.springframework.beans.factory.annotation.Autowired /** - * servicefactory=false is the default and actually not required. But we want to make clear that - * this is a singleton, i.e. there will only be one instance of PolicyDecisionPoint within the whole + * This is a singleton, i.e. there will only be one instance of PolicyDecisionPoint within the whole * runtime. * * @author Julian Schuette (julian.schuette@aisec.fraunhofer.de) */ @Component(immediate = true, name = "ids-dataflow-control") +@org.springframework.stereotype.Component class PolicyDecisionPoint : PDP, PAP { // Convenience val for this thread's LuconEngine instance @@ -57,6 +59,7 @@ class PolicyDecisionPoint : PDP, PAP { @Reference(cardinality = ReferenceCardinality.OPTIONAL, policy = ReferencePolicy.DYNAMIC) @Volatile + @Autowired(required = false) private var routeManager: RouteManager? = null private val transformationCache = @@ -146,12 +149,16 @@ class PolicyDecisionPoint : PDP, PAP { loadPolicies() } + @PostConstruct fun loadPolicies() { // Try to load existing policies from deploy dir at activation - val dir = File(System.getProperty("karaf.base") + File.separator + "deploy") - val directoryListing = dir.listFiles() - if (directoryListing == null || !dir.isDirectory) { - LOG.warn("Unexpected or not running in karaf: Not a directory: " + dir.absolutePath) + // val dir = File(System.getProperty("karaf.base") + File.separator + "deploy") + val url = Thread.currentThread().contextClassLoader.getResource("deploy") ?: return + val file = File(url.path) + + val directoryListing = file.listFiles() + if (directoryListing == null || !file.isDirectory) { + LOG.warn("Unexpected or not running in karaf: Not a directory: " + file.absolutePath) return } diff --git a/ids-infomodel-manager/build.gradle.kts b/ids-infomodel-manager/build.gradle.kts index 65e5c4f76..6010a2791 100644 --- a/ids-infomodel-manager/build.gradle.kts +++ b/ids-infomodel-manager/build.gradle.kts @@ -38,4 +38,6 @@ dependencies { infomodelBundle("com.fasterxml.jackson.core", "jackson-databind", libraryVersions["jackson"]) osgiCore("org.osgi", "osgi.cmpn", libraryVersions["osgiCompendium"]) + + implementation("org.springframework.boot:spring-boot-starter") } diff --git a/ids-infomodel-manager/src/main/kotlin/de/fhg/aisec/ids/informationmodelmanager/InfoModelService.kt b/ids-infomodel-manager/src/main/kotlin/de/fhg/aisec/ids/informationmodelmanager/InfoModelService.kt index 004abd6e3..2e613e531 100644 --- a/ids-infomodel-manager/src/main/kotlin/de/fhg/aisec/ids/informationmodelmanager/InfoModelService.kt +++ b/ids-infomodel-manager/src/main/kotlin/de/fhg/aisec/ids/informationmodelmanager/InfoModelService.kt @@ -30,17 +30,22 @@ import de.fraunhofer.iais.eis.util.TypedLiteral import java.net.URI import java.net.URISyntaxException import java.util.* -import org.osgi.service.component.annotations.Component import org.osgi.service.component.annotations.Reference import org.osgi.service.component.annotations.ReferenceCardinality import org.slf4j.LoggerFactory +import org.springframework.beans.factory.annotation.Autowired /** IDS Info Model Manager. */ -@Component(name = "ids-infomodel-manager", immediate = true) +// @Component(name = "ids-infomodel-manager", immediate = true) +@org.springframework.stereotype.Component class InfoModelService : InfoModel { - @Reference(cardinality = ReferenceCardinality.MANDATORY) private lateinit var settings: Settings + @Reference(cardinality = ReferenceCardinality.MANDATORY) + @Autowired + private lateinit var settings: Settings + @Reference(cardinality = ReferenceCardinality.OPTIONAL) + @Autowired(required = false) private var connectionManager: ConnectionManager? = null private val connectorProfile: ConnectorProfile diff --git a/ids-route-manager/build.gradle.kts b/ids-route-manager/build.gradle.kts index 9a7aad96d..3e7aff88f 100644 --- a/ids-route-manager/build.gradle.kts +++ b/ids-route-manager/build.gradle.kts @@ -4,6 +4,10 @@ dependencies { providedByBundle(project(":ids-api")) { isTransitive = false } + implementation("org.apache.camel.springboot:camel-spring-boot-starter") + implementation("org.springframework.boot:spring-boot-starter") + implementation("org.apache.camel.springboot:camel-spring-boot-starter") + implementation("de.fraunhofer.iais.eis.ids.infomodel", "java", libraryVersions["infomodel"]) providedByFeature("javax.xml.bind", "jaxb-api", libraryVersions["jaxbApi"]) diff --git a/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/RouteManagerService.kt b/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/RouteManagerService.kt index 6f78f2ff5..c5ad086f5 100644 --- a/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/RouteManagerService.kt +++ b/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/RouteManagerService.kt @@ -37,27 +37,21 @@ import org.apache.camel.management.DefaultManagementAgent import org.apache.camel.model.ModelCamelContext import org.apache.camel.model.ModelHelper import org.apache.camel.model.RouteDefinition +import org.apache.camel.spring.boot.ComponentConfigurationPropertiesCommon import org.apache.camel.support.dump.RouteStatDump -import org.osgi.framework.FrameworkUtil -import org.osgi.framework.InvalidSyntaxException -import org.osgi.service.component.ComponentContext -import org.osgi.service.component.annotations.Activate -import org.osgi.service.component.annotations.Component import org.slf4j.LoggerFactory +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.context.ApplicationContext +import org.springframework.stereotype.Component /** * Manages Camel routes. * * @author Julian Schuette (julian.schuette@aisec.fraunhofer.de) */ -@Component(immediate = true, name = "ids-routemanager") +@Component class RouteManagerService : RouteManager { - private lateinit var ctx: ComponentContext - - @Activate - private fun activate(ctx: ComponentContext) { - this.ctx = ctx - } + @Autowired private lateinit var ctx: ApplicationContext override fun getRoutes(): List { val result: MutableList = ArrayList() @@ -118,27 +112,23 @@ class RouteManagerService : RouteManager { } override fun listComponents(): List { - val componentNames: MutableList = ArrayList() - val bCtx = - FrameworkUtil.getBundle(RouteManagerService::class.java).bundleContext - ?: return componentNames - try { - val services = bCtx.getServiceReferences("org.apache.camel.spi.ComponentResolver", null) - for (sr in services) { - var bundle = sr.bundle.headers["Bundle-Name"] - if (bundle == null || "" == bundle) { - bundle = sr.bundle.symbolicName - } - var description = sr.bundle.headers["Bundle-Description"] - if (description == null) { - description = "" + val beanNamesForType = + ctx.getBeanNamesForType(ComponentConfigurationPropertiesCommon::class.java) + + // yes, this is a bit hacky but will do fow now + return Arrays.stream(beanNamesForType) + .map { name -> + val first = name.split("-org")[0] + + if (first.equals("camel.component")) { + return@map null } - componentNames.add(RouteComponent(bundle, description)) + + return@map RouteComponent("camel-" + first.split("camel.component.")[1], "") } - } catch (e: InvalidSyntaxException) { - LOG.error(e.message, e) - } - return componentNames + .filter { Objects.nonNull(it) } + .collect(Collectors.toList()) as + List } override fun getEndpoints(): Map> { @@ -228,12 +218,11 @@ class RouteManagerService : RouteManager { private val camelContexts: List get() { return try { - ctx.bundleContext.getServiceReferences(CamelContext::class.java.name, null)?.run { - mapNotNull { reference -> ctx.bundleContext.getService(reference) } - .map { CamelContext::class.java.cast(it) } - .sortedWith(Comparator.comparing { it.name }) - } - ?: emptyList() + val contexts = ctx.getBeansOfType(CamelContext::class.java).values.toMutableList() + + contexts.sortWith(Comparator.comparing { it.name }) + + return contexts } catch (e: Exception) { LOG.warn("Cannot retrieve the list of Camel contexts.", e) emptyList() diff --git a/ids-settings/build.gradle.kts b/ids-settings/build.gradle.kts index 608e13049..b0d016030 100644 --- a/ids-settings/build.gradle.kts +++ b/ids-settings/build.gradle.kts @@ -13,4 +13,6 @@ dependencies { } osgiCore("org.osgi", "osgi.cmpn", libraryVersions["osgiCompendium"]) + + implementation("org.springframework.boot:spring-boot-starter") } \ No newline at end of file diff --git a/ids-settings/src/main/kotlin/de/fhg/aisec/ids/settings/SettingsComponent.kt b/ids-settings/src/main/kotlin/de/fhg/aisec/ids/settings/SettingsComponent.kt index 249779ce7..0e317bb80 100644 --- a/ids-settings/src/main/kotlin/de/fhg/aisec/ids/settings/SettingsComponent.kt +++ b/ids-settings/src/main/kotlin/de/fhg/aisec/ids/settings/SettingsComponent.kt @@ -27,20 +27,25 @@ import de.fhg.aisec.ids.api.settings.Settings import java.nio.file.FileSystems import java.util.* import java.util.concurrent.ConcurrentMap +import javax.annotation.PreDestroy import kotlin.collections.HashMap import org.mapdb.DB import org.mapdb.DBMaker import org.mapdb.Serializer -import org.osgi.service.component.annotations.Activate -import org.osgi.service.component.annotations.Component -import org.osgi.service.component.annotations.Deactivate import org.slf4j.LoggerFactory -@Component(immediate = true, name = "ids-settings") +@org.springframework.stereotype.Component class SettingsComponent : Settings { - @Activate + + constructor() { + activate() + } + fun activate() { LOG.debug("Open Settings Database...") + + DB_PATH.toFile().parentFile.mkdirs() + // Use default reliable (non-mmap) mode and WAL for transaction safety mapDB = DBMaker.fileDB(DB_PATH.toFile()).transactionEnable().make() var dbVersion = settingsStore.getOrPut(DB_VERSION_KEY, { 1 }) as Int @@ -85,7 +90,7 @@ class SettingsComponent : Settings { } } - @Deactivate + @PreDestroy fun deactivate() { LOG.debug("Close Settings Database...") mapDB.close() diff --git a/ids-webconsole/build.gradle.kts b/ids-webconsole/build.gradle.kts index f8dc46d06..e45cfbf65 100644 --- a/ids-webconsole/build.gradle.kts +++ b/ids-webconsole/build.gradle.kts @@ -6,7 +6,7 @@ val libraryVersions = rootProject.extra.get("libraryVersions") as Map list() { - ContainerManager cml = WebConsoleComponent.getContainerManager(); - if (cml == null) { - return new ArrayList<>(); - } - List result = cml.list(false); result.sort( (app1, app2) -> { @@ -97,18 +101,16 @@ public List list() { @GET @Path("start/{containerId}") @ApiOperation( - value = "Start an application", - notes = - "Starting an application may take some time. This method will start the app asynchronously and return immediately. This method starts the latest version of the app.", - response = Boolean.class - ) + value = "Start an application", + notes = + "Starting an application may take some time. This method will start the app asynchronously and return immediately. This method starts the latest version of the app.", + response = Boolean.class) @ApiResponses( @ApiResponse( - code = 200, - message = - "true if the app has been requested to be started. " - + "false if no container management layer is available" - )) + code = 200, + message = + "true if the app has been requested to be started. " + + "false if no container management layer is available")) @Produces(MediaType.APPLICATION_JSON) @AuthorizationRequired public boolean start( @@ -119,18 +121,16 @@ public boolean start( @GET @Path("start/{containerId}/{key}") @ApiOperation( - value = "Start an application", - notes = - "Starting an application may take some time. This method will start the app asynchronously and return immediately. This methods starts a specific version of the app.", - response = Boolean.class - ) + value = "Start an application", + notes = + "Starting an application may take some time. This method will start the app asynchronously and return immediately. This methods starts a specific version of the app.", + response = Boolean.class) @ApiResponses( @ApiResponse( - code = 200, - message = - "true if the app has been requested to be started. " - + "false if no container management layer is available" - )) + code = 200, + message = + "true if the app has been requested to be started. " + + "false if no container management layer is available")) @Produces(MediaType.APPLICATION_JSON) @AuthorizationRequired public boolean start( @@ -138,14 +138,8 @@ public boolean start( @ApiParam(value = "Key for user token (required for trustX containers)") @PathParam("key") String key) { try { - ContainerManager cml = WebConsoleComponent.getContainerManager(); - if (cml != null) { - cml.startContainer(containerId, key); - return true; - } else { - LOG.warn("Container manager not available"); - return false; - } + cml.startContainer(containerId, key); + return true; } catch (NoContainerExistsException | ServiceUnavailableException e) { LOG.error("Error starting container", e); return false; @@ -155,31 +149,23 @@ public boolean start( @GET @Path("stop/{containerId}") @ApiOperation( - value = "Stop an app", - notes = - "Stops an application. The application will remain installed and can be re-started later. All temporary data will be lost, however.", - response = Boolean.class - ) + value = "Stop an app", + notes = + "Stops an application. The application will remain installed and can be re-started later. All temporary data will be lost, however.", + response = Boolean.class) @ApiResponses( @ApiResponse( - code = 200, - message = - "true if the app has been requested to be stopped. " - + "false if no container management layer is available" - )) + code = 200, + message = + "true if the app has been requested to be stopped. " + + "false if no container management layer is available")) @Produces(MediaType.APPLICATION_JSON) @AuthorizationRequired public boolean stop( @ApiParam(value = "ID of the app to stop") @PathParam("containerId") String containerId) { try { - ContainerManager cml = WebConsoleComponent.getContainerManager(); - if (cml != null) { - cml.stopContainer(containerId); - return true; - } else { - LOG.warn("Container manager not available"); - return false; - } + cml.stopContainer(containerId); + return true; } catch (NoContainerExistsException | ServiceUnavailableException e) { LOG.error(e.getMessage(), e); return false; @@ -187,32 +173,28 @@ public boolean stop( } @POST - @OPTIONS + // @OPTIONS @Path("install") @ApiOperation( - value = "Install an app", - notes = "Requests to install an app.", - response = Boolean.class - ) + value = "Install an app", + notes = "Requests to install an app.", + response = Boolean.class) @ApiResponses({ @ApiResponse( - code = 200, - message = - "If the app has been requested to be installed. " - + "The actual installation takes place asynchronously in the background " - + "and will terminate after a timeout of 20 minutes", - response = Boolean.class - ), + code = 200, + message = + "If the app has been requested to be installed. " + + "The actual installation takes place asynchronously in the background " + + "and will terminate after a timeout of 20 minutes", + response = Boolean.class), @ApiResponse( - code = 500, - message = "_No cmld_: If no container management layer is available", - response = String.class - ), + code = 500, + message = "_No cmld_: If no container management layer is available", + response = String.class), @ApiResponse( - code = 500, - message = "_Null image_: If imageID not given", - response = String.class - ) + code = 500, + message = "_Null image_: If imageID not given", + response = String.class) }) @Produces(MediaType.APPLICATION_JSON) @AuthorizationRequired @@ -221,11 +203,6 @@ public String install( Map apps) { ApplicationContainer app = apps.get("app"); LOG.debug("Request to load {}", app.getImage()); - final ContainerManager cm = WebConsoleComponent.getContainerManager(); - if (cm == null) { - LOG.warn("Container manager not available"); - throw new InternalServerErrorException("Null image"); - } final String image = app.getImage(); if (image == null) { @@ -240,7 +217,7 @@ public String install( final Future handler = executor.submit( () -> { - Optional containerId = cm.pullImage(app); + Optional containerId = cml.pullImage(app); return containerId.orElse(null); }); // Cancel pulling after 20 minutes, just in case. @@ -259,10 +236,6 @@ public String install( public String wipe( @ApiParam(value = "ID of the app to wipe") @QueryParam("containerId") String containerId) { try { - ContainerManager cml = WebConsoleComponent.getContainerManager(); - if (cml == null) { - return "No container manager"; - } cml.wipe(containerId); } catch (NullPointerException | NoContainerExistsException e) { LOG.error(e.getMessage(), e); @@ -273,17 +246,12 @@ public String wipe( @GET @Path("cml_version") @ApiOperation( - value = "Returns the version of the currently active container management layer", - response = Map.class - ) + value = "Returns the version of the currently active container management layer", + response = Map.class) @Produces(MediaType.APPLICATION_JSON) @AuthorizationRequired public Map getCml() { try { - ContainerManager cml = WebConsoleComponent.getContainerManager(); - if (cml == null) { - return Collections.emptyMap(); - } Map result = new HashMap<>(); result.put("cml_version", cml.getVersion()); return result; @@ -301,11 +269,6 @@ public List search(AppSearchRequest searchRequest) { String term = searchRequest.getSearchTerm(); try { Client client = ClientBuilder.newBuilder().build(); - Settings settings = WebConsoleComponent.getSettings(); - if (settings == null) { - LOG.warn("No settings available"); - return new ArrayList<>(); - } String url = settings.getConnectorConfig().getAppstoreUrl(); String r = client.target(url).request(MediaType.APPLICATION_JSON).get(String.class); diff --git a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/CertApi.java b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/CertApi.java index 9d9dc1d54..446fe8803 100644 --- a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/CertApi.java +++ b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/CertApi.java @@ -7,9 +7,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -30,8 +30,11 @@ import io.swagger.annotations.*; import org.apache.cxf.jaxrs.ext.multipart.Attachment; import org.apache.cxf.jaxrs.ext.multipart.Multipart; +import org.checkerframework.checker.nullness.qual.NonNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; import javax.ws.rs.*; import javax.ws.rs.core.MediaType; @@ -60,32 +63,33 @@ * * @author Hamed Rasifard (hamed.rasifard@aisec.fraunhofer.de) */ +@Component @Path("/certs") @Api( - value = "Identities and Certificates", - authorizations = {@Authorization(value = "oauth2")} -) + value = "Identities and Certificates", + authorizations = {@Authorization(value = "oauth2")}) public class CertApi { private static final Logger LOG = LoggerFactory.getLogger(CertApi.class); private static final String KEYSTORE_PWD = "password"; private static final String TRUSTSTORE_FILE = "truststore.p12"; private static final String KEYSTORE_FILE = "provider-keystore.p12"; + private final Settings settings; + + public CertApi(@Autowired @NonNull Settings settings) { + this.settings = settings; + } + @GET @ApiOperation(value = "Starts ACME renewal over X509v3 certificates") @Path("acme_renew/{target}") @AuthorizationRequired - public void getAcmeCert( + public boolean getAcmeCert( @ApiParam( - value = - "Identifier of the component to renew. Currently, the only valid value is __webconsole__" - ) + value = + "Identifier of the component to renew. Currently, the only valid value is __webconsole__") @PathParam("target") String target) { - Settings settings = WebConsoleComponent.getSettings(); - if (settings == null) { - return; - } ConnectorConfig config = settings.getConnectorConfig(); AcmeClient acmeClient = WebConsoleComponent.getAcmeClient(); if ("webconsole".equals(target) && acmeClient != null) { @@ -94,16 +98,19 @@ public void getAcmeCert( URI.create(config.getAcmeServerWebcon()), config.getAcmeDnsWebcon().trim().split("\\s*,\\s*"), config.getAcmePortWebcon()); + + return true; } else { LOG.warn("ACME renewal for services other than WebConsole is not yet implemented!"); + + return false; } } @GET @ApiOperation( - value = "Retrieves the Terms of Service (tos) of the ACME endpoint", - response = AcmeTermsOfService.class - ) + value = "Retrieves the Terms of Service (tos) of the ACME endpoint", + response = AcmeTermsOfService.class) @Path("acme_tos") @AuthorizationRequired public AcmeTermsOfService getAcmeTermsOfService( @@ -118,9 +125,8 @@ public AcmeTermsOfService getAcmeTermsOfService( @GET @Path("list_certs") @ApiOperation( - value = "List installed certificates from trust store.", - notes = "Certificates in this list refer to public keys that are trusted by this connector." - ) + value = "List installed certificates from trust store.", + notes = "Certificates in this list refer to public keys that are trusted by this connector.") @ApiResponses({ @ApiResponse(code = 200, message = "List of certificates"), @ApiResponse(code = 500, message = "_Truststore not found_: If no trust store available"), @@ -135,10 +141,9 @@ public List listCerts() { @GET @Path("list_identities") @ApiOperation( - value = "List installed certificates from the private key store.", - notes = - "Certificates in this list refer to private keys that can be used as identities by the connector." - ) + value = "List installed certificates from the private key store.", + notes = + "Certificates in this list refer to private keys that can be used as identities by the connector.") @Produces(MediaType.APPLICATION_JSON) @AuthorizationRequired public List listIdentities() { @@ -314,7 +319,8 @@ private File getKeystoreFile(String fileName) { } throw new NotFoundException( - "Keystore/truststore file could not be found. Cannot continue. Given filename: " + fileName); + "Keystore/truststore file could not be found. Cannot continue. Given filename: " + + fileName); } /** Returns all entries (private keys and certificates) from a Java keystore. */ @@ -396,29 +402,29 @@ private void doGenKeyPair( * as sun.security.* or oracle.*. */ String[] keytoolCmd = - new String[] { - "/bin/sh", - "-c", - "keytool", - "-genkey", - "-alias", - alias, - "-keyalg", - keyAlgName, - "-keysize", - Integer.toString(keySize), - "-sigalg", - sigAlgName, - "-keystore", - keyStoreFile.getAbsolutePath(), - "-dname", - "CN=" + spec.cn + ", OU=" + spec.ou + ", O=" + spec.o + ", L=" + spec.l + ", S=" + spec.s - + ", C=" + spec.c, - "-storepass", - KEYSTORE_PWD, - "-keypass", - KEYSTORE_PWD - }; + new String[] { + "/bin/sh", + "-c", + "keytool", + "-genkey", + "-alias", + alias, + "-keyalg", + keyAlgName, + "-keysize", + Integer.toString(keySize), + "-sigalg", + sigAlgName, + "-keystore", + keyStoreFile.getAbsolutePath(), + "-dname", + "CN=" + spec.cn + ", OU=" + spec.ou + ", O=" + spec.o + ", L=" + spec.l + ", S=" + spec.s + + ", C=" + spec.c, + "-storepass", + KEYSTORE_PWD, + "-keypass", + KEYSTORE_PWD + }; ByteArrayOutputStream bos = new ByteArrayOutputStream(); new ProcessExecutor().execute(keytoolCmd, bos, bos); LOG.debug("Keytool: " + new String(bos.toByteArray(), StandardCharsets.UTF_8)); diff --git a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/ConfigApi.java b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/ConfigApi.java index 0eb4e5127..d13290c10 100644 --- a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/ConfigApi.java +++ b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/ConfigApi.java @@ -30,6 +30,9 @@ import de.fhg.aisec.ids.api.settings.Settings; import de.fhg.aisec.ids.webconsole.WebConsoleComponent; import io.swagger.annotations.*; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; import javax.ws.rs.*; import javax.ws.rs.core.MediaType; @@ -49,6 +52,7 @@ * @author Gerd Brost (gerd.brost@aisec.fraunhofer.de) * @author Michael Lux (michael.lux@aisec.fraunhofer.de) */ +@Component @Path("/config") @Api( value = "Connector Configuration", @@ -57,21 +61,25 @@ public class ConfigApi { private static final Pattern CONNECTION_CONFIG_PATTERN = Pattern.compile(".* - ([^ ]+)$"); + private Settings settings; + private RouteManager routeManager; + + public ConfigApi(@Autowired @NonNull Settings settings,@Autowired @NonNull RouteManager routeManager) { + this.settings = settings; + this.routeManager = routeManager; + } + @GET @ApiOperation(value = "Retrieves the current configuration", response = ConnectorConfig.class) @Path("/connectorConfig") @Produces(MediaType.APPLICATION_JSON) @AuthorizationRequired public ConnectorConfig get() { - Settings settings = WebConsoleComponent.getSettings(); - if (settings == null) { - return null; - } return settings.getConnectorConfig(); } @POST - @OPTIONS + //@OPTIONS @Path("/connectorConfig") @ApiOperation(value = "Sets the overall configuration of the connector") @ApiResponses( @@ -87,10 +95,6 @@ public String set(ConnectorConfig config) { throw new BadRequestException("No valid preferences received!"); } - Settings settings = WebConsoleComponent.getSettings(); - if (settings == null) { - return "No settings available"; - } settings.setConnectorConfig(config); return "OK"; @@ -119,11 +123,6 @@ public Response setConnectionConfigurations( Response.serverError().entity("No valid connection settings received!").build(); } - Settings settings = WebConsoleComponent.getSettings(); - if (settings == null) { - return Response.serverError().build(); - } - //connection has format " - host:port" //store only "host:port" in database to make connection available in other parts of the application // where rout_id is not available @@ -158,11 +157,6 @@ public Response setConnectionConfigurations( @Produces(MediaType.APPLICATION_JSON) @AuthorizationRequired public ConnectionSettings getConnectionConfigurations(@PathParam("con") String connection) { - Settings settings = WebConsoleComponent.getSettings(); - if (settings == null) { - return null; - } - return settings.getConnectionSettings(connection); } @@ -184,10 +178,7 @@ public ConnectionSettings getConnectionConfigurations(@PathParam("con") String c @Produces(MediaType.APPLICATION_JSON) @AuthorizationRequired public Map getAllConnectionConfigurations() { - Settings settings = WebConsoleComponent.getSettings(); ConnectionManager connectionManager = WebConsoleComponent.getConnectionManager(); - RouteManager routeManager = WebConsoleComponent.getRouteManager(); - if (settings == null || connectionManager == null || routeManager == null) { return Collections.emptyMap(); } diff --git a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/ConnectionAPI.java b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/ConnectionAPI.java index 8c941963b..fbf654062 100644 --- a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/ConnectionAPI.java +++ b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/ConnectionAPI.java @@ -27,6 +27,8 @@ import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.Authorization; +import org.springframework.stereotype.Component; + import java.util.ArrayList; import java.util.List; import javax.ws.rs.GET; @@ -41,6 +43,7 @@ * * @author Gerd Brost (gerd.brost@aisec.fraunhofer.de) */ +@Component @Path("/connections") @Api( value = "IDSCP Connections", diff --git a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/MetricAPI.java b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/MetricAPI.java index ee82bdd7f..2c07916e0 100644 --- a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/MetricAPI.java +++ b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/MetricAPI.java @@ -20,6 +20,8 @@ package de.fhg.aisec.ids.webconsole.api; import io.swagger.annotations.*; +import org.springframework.stereotype.Component; + import java.lang.management.*; import java.text.DecimalFormat; import java.util.HashMap; @@ -36,6 +38,7 @@ * * @author Julian Schuette (julian.schuette@aisec.fraunhofer.de) */ +@Component @Path("/metric") @Api( value = "Runtime Metrics", diff --git a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/PolicyApi.java b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/PolicyApi.java index 5900c9213..cea42d339 100644 --- a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/PolicyApi.java +++ b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/PolicyApi.java @@ -26,9 +26,11 @@ import java.util.List; import javax.ws.rs.*; import javax.ws.rs.core.MediaType; + import org.apache.cxf.jaxrs.ext.multipart.Multipart; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; /** * REST API interface for managing usage control policies in the connector. @@ -37,6 +39,7 @@ * * @author Julian Schuette (julian.schuette@aisec.fraunhofer.de) */ +@Component @Path("/policies") @Api( value = "Usage Control Policies", @@ -84,15 +87,15 @@ public String getPolicyProlog() { } @POST - @OPTIONS + //@OPTIONS @Path("install") @ApiOperation(value = "Installs a new usage control policy as a Prolog theory file") @Consumes(MediaType.MULTIPART_FORM_DATA) @AuthorizationRequired public String install( - @Multipart(value = "policy_name") @DefaultValue(value = "default policy") String policyName, - @Multipart(value = "policy_description") @DefaultValue(value = "") String policyDescription, - @Multipart(value = "policy_file") String policy) { + @FormParam(value = "policy_name") @DefaultValue(value = "default policy") String policyName, + @FormParam(value = "policy_description") @DefaultValue(value = "") String policyDescription, + @FormParam(value = "policy_file") String policy) { LOG.info("Received policy file. name: {}, desc: {}", policyName, policyDescription); PAP pap = WebConsoleComponent.getPolicyAdministrationPoint(); if (pap == null) { diff --git a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/RouteApi.java b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/RouteApi.java index e947c0415..6d438e7a5 100644 --- a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/RouteApi.java +++ b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/RouteApi.java @@ -20,8 +20,10 @@ package de.fhg.aisec.ids.webconsole.api; import de.fhg.aisec.ids.api.Result; +import de.fhg.aisec.ids.api.cm.ContainerManager; import de.fhg.aisec.ids.api.policy.PAP; import de.fhg.aisec.ids.api.router.*; +import de.fhg.aisec.ids.api.settings.Settings; import de.fhg.aisec.ids.webconsole.WebConsoleComponent; import de.fhg.aisec.ids.webconsole.api.data.ValidationInfo; import io.swagger.annotations.Api; @@ -31,6 +33,8 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; import javax.ws.rs.*; import javax.ws.rs.core.MediaType; @@ -49,6 +53,7 @@ * * @author Julian Schuette (julian.schuette@aisec.fraunhofer.de) */ +@Component @Path("/routes") @Api( value = "Message Routing", @@ -57,6 +62,12 @@ public class RouteApi { private static final Logger LOG = LoggerFactory.getLogger(RouteApi.class); + private @NonNull RouteManager rm; + + public RouteApi(@Autowired @NonNull RouteManager rm) { + this.rm = rm; + } + /** * Returns map from camel context to list of camel routes. * @@ -77,10 +88,6 @@ public class RouteApi { @Produces(MediaType.APPLICATION_JSON) @AuthorizationRequired public List list() { - RouteManager rm = WebConsoleComponent.getRouteManager(); - if (rm == null) { - return new ArrayList<>(); - } return rm.getRoutes(); } @@ -90,10 +97,6 @@ public List list() { @Produces(MediaType.APPLICATION_JSON) @AuthorizationRequired public RouteObject get(@ApiParam(value = "Route ID") @PathParam("id") @NonNull String id) { - RouteManager rm = WebConsoleComponent.getRouteManager(); - if (rm == null) { - throw new InternalServerErrorException(); - } RouteObject oRoute = rm.getRoute(id); if (oRoute == null) { throw new NotFoundException("Route not found"); @@ -107,10 +110,6 @@ public RouteObject get(@ApiParam(value = "Route ID") @PathParam("id") @NonNull S @Produces(MediaType.TEXT_PLAIN) @AuthorizationRequired public String getAsString(@ApiParam(value = "Route ID") @PathParam("id") String id) { - RouteManager rm = WebConsoleComponent.getRouteManager(); - if (rm == null) { - throw new InternalServerErrorException(); - } String routeAsString = rm.getRouteAsString(id); if (routeAsString == null) { throw new NotFoundException("Route not found"); @@ -126,10 +125,6 @@ public String getAsString(@ApiParam(value = "Route ID") @PathParam("id") String @AuthorizationRequired public Result startRoute(@PathParam("id") String id) { try { - RouteManager rm = WebConsoleComponent.getRouteManager(); - if (rm == null) { - throw new InternalServerErrorException(); - } rm.startRoute(id); return new Result(); } catch (Exception e) { @@ -146,10 +141,6 @@ public Result startRoute(@PathParam("id") String id) { @AuthorizationRequired public Result saveRoute(@PathParam("id") @NonNull String id, @NonNull String routeDefinition) { try { - RouteManager rm = WebConsoleComponent.getRouteManager(); - if (rm == null) { - throw new InternalServerErrorException(); - } rm.saveRoute(id, routeDefinition); return new Result(); } catch (Exception e) { @@ -166,10 +157,6 @@ public Result saveRoute(@PathParam("id") @NonNull String id, @NonNull String rou @AuthorizationRequired public Result addRoute(@NonNull String routeDefinition) { try { - RouteManager rm = WebConsoleComponent.getRouteManager(); - if (rm == null) { - throw new InternalServerErrorException(); - } rm.addRoute(routeDefinition); return new Result(); } catch (Exception e) { @@ -189,10 +176,6 @@ public Result addRoute(@NonNull String routeDefinition) { @AuthorizationRequired public Result stopRoute(@PathParam("id") String id) { try { - RouteManager rm = WebConsoleComponent.getRouteManager(); - if (rm == null) { - throw new InternalServerErrorException(); - } rm.stopRoute(id); return new Result(); } catch (Exception e) { @@ -207,10 +190,6 @@ public Result stopRoute(@PathParam("id") String id) { @Path("/metrics/{id}") @AuthorizationRequired public RouteMetrics getMetrics(@PathParam("id") String routeId) { - RouteManager rm = WebConsoleComponent.getRouteManager(); - if (rm == null) { - throw new InternalServerErrorException(); - } return rm.getRouteMetrics().get(routeId); } @@ -223,10 +202,6 @@ public RouteMetrics getMetrics(@PathParam("id") String routeId) { @Path("/metrics") @AuthorizationRequired public RouteMetrics getMetrics() { - RouteManager rm = WebConsoleComponent.getRouteManager(); - if (rm == null) { - throw new InternalServerErrorException(); - } return aggregateMetrics(rm.getRouteMetrics().values()); } @@ -271,10 +246,6 @@ private RouteMetrics aggregateMetrics(Collection currentMetrics) { @Produces(MediaType.APPLICATION_JSON) @AuthorizationRequired public List getComponents() { - RouteManager rm = WebConsoleComponent.getRouteManager(); - if (rm == null) { - throw new InternalServerErrorException(); - } return rm.listComponents(); } @@ -283,10 +254,6 @@ public List getComponents() { @Path("/list_endpoints") @AuthorizationRequired public Map listEndpoints() { - RouteManager rm = WebConsoleComponent.getRouteManager(); - if (rm == null) { - throw new InternalServerErrorException(); - } return rm.listEndpoints(); } @@ -316,10 +283,6 @@ public ValidationInfo validate(@PathParam("routeId") String routeId) { @Produces(MediaType.TEXT_PLAIN) @AuthorizationRequired public String getRouteProlog(@PathParam("routeId") @NonNull String routeId) { - RouteManager rm = WebConsoleComponent.getRouteManager(); - if (rm == null) { - throw new InternalServerErrorException(); - } return rm.getRouteAsProlog(routeId); } } diff --git a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/SettingsApi.java b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/SettingsApi.java index 605c31042..353e842b0 100644 --- a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/SettingsApi.java +++ b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/SettingsApi.java @@ -7,9 +7,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -21,14 +21,20 @@ import de.fhg.aisec.ids.api.infomodel.ConnectorProfile; import de.fhg.aisec.ids.api.infomodel.InfoModel; -import de.fhg.aisec.ids.webconsole.WebConsoleComponent; import de.fraunhofer.iais.eis.Connector; import de.fraunhofer.iais.eis.util.TypedLiteral; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.Authorization; +import org.checkerframework.checker.nullness.qual.NonNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.ws.rs.*; +import javax.ws.rs.core.MediaType; +import java.util.stream.Collectors; import javax.ws.rs.*; import javax.ws.rs.core.MediaType; @@ -41,24 +47,26 @@ */ // ConnectorProfile will be processed by custom Jackson deserializer +@Component @Path("/settings") @Api( - value = "Self-Description and Connector Profiles", - authorizations = {@Authorization(value = "oauth2")} -) + value = "Self-Description and Connector Profiles", + authorizations = {@Authorization(value = "oauth2")}) public class SettingsApi { private static final Logger LOG = LoggerFactory.getLogger(SettingsApi.class); + private @NonNull InfoModel im; + + public SettingsApi(@Autowired @NonNull InfoModel im) { + this.im = im; + } + @POST @Path("/connectorProfile") @ApiOperation(value = "Configure the connector's self-description (\"Connector Profile\").") @Consumes(MediaType.APPLICATION_JSON) @AuthorizationRequired public String postConnectorProfile(ConnectorProfile profile) { - InfoModel im = WebConsoleComponent.getInfoModelManager(); - if (im == null) { - throw new ServiceUnavailableException("InfoModel is not available"); - } if (im.setConnector(profile)) { return "ConnectorProfile successfully stored."; } else { @@ -71,15 +79,10 @@ public String postConnectorProfile(ConnectorProfile profile) { @Path("/connectorProfile") @Produces(MediaType.APPLICATION_JSON) @ApiOperation( - value = "Returns this connector's self-description (\"Connector Profile\")", - response = ConnectorProfile.class - ) + value = "Returns this connector's self-description (\"Connector Profile\")", + response = ConnectorProfile.class) @AuthorizationRequired public ConnectorProfile getConnectorProfile() { - InfoModel im = WebConsoleComponent.getInfoModelManager(); - if (im == null) { - throw new ServiceUnavailableException("InfoModel is not available"); - } Connector c = im.getConnector(); if (c == null) { return new ConnectorProfile(); @@ -101,10 +104,6 @@ public ConnectorProfile getConnectorProfile() { @Produces("application/ld+json") // TODO Document ApiOperation public String getSelfInformation() { - InfoModel im = WebConsoleComponent.getInfoModelManager(); - if (im == null) { - throw new ServiceUnavailableException("InfoModel is not available"); - } try { return im.getConnectorAsJsonLd(); } catch (NullPointerException e) { @@ -120,10 +119,6 @@ public String getSelfInformation() { @Consumes("application/ld+json") @AuthorizationRequired public void setSelfInformation(String selfInformation) { - InfoModel im = WebConsoleComponent.getInfoModelManager(); - if (im == null) { - throw new ServiceUnavailableException("InfoModel is not available"); - } try { im.setConnectorByJsonLd(selfInformation); } catch (NullPointerException e) { @@ -138,10 +133,6 @@ public void setSelfInformation(String selfInformation) { @Consumes("application/ld+json") @AuthorizationRequired public void removeSelfInformation() { - InfoModel im = WebConsoleComponent.getInfoModelManager(); - if (im == null) { - throw new ServiceUnavailableException("InfoModel is not available"); - } try { im.setConnectorByJsonLd(null); } catch (NullPointerException e) { diff --git a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/UserApi.java b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/UserApi.java index 44b4c3da2..aa76a3343 100644 --- a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/UserApi.java +++ b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/UserApi.java @@ -7,9 +7,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -25,6 +25,7 @@ import io.swagger.annotations.Api; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; import javax.crypto.KeyGenerator; import javax.security.auth.callback.Callback; @@ -49,66 +50,66 @@ import static javax.ws.rs.core.MediaType.APPLICATION_JSON; import static javax.ws.rs.core.Response.Status.UNAUTHORIZED; +@Component @Path("/user") @Api(value = "User Authentication") @Produces(APPLICATION_JSON) @Consumes(APPLICATION_JSON) public class UserApi { - private static final Logger LOG = LoggerFactory.getLogger(UserApi.class); - static Key key; + private static final Logger LOG = LoggerFactory.getLogger(UserApi.class); + static Key key; - static { - try { - key = KeyGenerator.getInstance("HmacSHA256").generateKey(); - } catch (NoSuchAlgorithmException e) { - e.printStackTrace(); + static { + try { + key = KeyGenerator.getInstance("HmacSHA256").generateKey(); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } } - } - /** - * Given a correct username/password, this method returns a JWT token that is valid for one day. - * - * @param user Username/password. - * @return A JSON object of the form { "token" : } if successful, 401 - * UNAUTHORIZED if not. - */ - @POST - @Path("/login") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - public Response authenticateUser(User user) { - try { - // Authenticate the user using the credentials provided - if (!authenticate(user.username, user.password)) { - return Response.status(UNAUTHORIZED).build(); - } + /** + * Given a correct username/password, this method returns a JWT token that is valid for one day. + * + * @param user Username/password. + * @return A JSON object of the form { "token" : } if successful, 401 UNAUTHORIZED if not. + */ + @POST + @Path("/login") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response authenticateUser(User user) { + try { + // Authenticate the user using the credentials provided + if (!authenticate(user.username, user.password)) { + return Response.status(UNAUTHORIZED).build(); + } - // Issue a token for the user - String token = issueToken(user.username); + // Issue a token for the user + String token = issueToken(user.username); - // Return the token on the response - Map result = new HashMap<>(); - result.put("token", token); - return Response.ok().entity(result).build(); - } catch (Throwable e) { - e.printStackTrace(); - return Response.status(UNAUTHORIZED).build(); + // Return the token on the response + Map result = new HashMap<>(); + result.put("token", token); + return Response.ok().entity(result).build(); + } catch (Throwable e) { + e.printStackTrace(); + return Response.status(UNAUTHORIZED).build(); + } } - } private String issueToken(String username) { Calendar cal = Calendar.getInstance(); cal.setTimeInMillis(cal.getTimeInMillis() + 86_400_000); Date tomorrow = cal.getTime(); - return JWT.create() - .withClaim("user", username) - .withExpiresAt(tomorrow) - .withIssuer("ids-connector") - .sign(Algorithm.HMAC256(UserApi.key.getEncoded())); - } + return JWT.create() + .withClaim("user", username) + .withExpiresAt(tomorrow) + .withIssuer("ids-connector") + .sign(Algorithm.HMAC256(UserApi.key.getEncoded())); + } - private boolean authenticate(String user, String password) throws LoginException { + private boolean authenticate(String user, String password) throws LoginException { /* Login with JaaS. We use the default realm "karaf". When using default PropertiesLoginModule, users are configured in karaf-assembly/src/main/resources/etc/users.properties. Other modules such as OAuth, LDAP, JDBC can be configured as needed without changing this code here. diff --git a/ids-webconsole/src/main/resources/www/proxy.conf.json b/ids-webconsole/src/main/resources/www/proxy.conf.json index 5380e2680..190ba9c83 100644 --- a/ids-webconsole/src/main/resources/www/proxy.conf.json +++ b/ids-webconsole/src/main/resources/www/proxy.conf.json @@ -1,6 +1,6 @@ { "/cxf": { - "target": "http://localhost:8181", + "target": "http://localhost:8080", "secure": false } -} \ No newline at end of file +} diff --git a/ids-webconsole/src/test/java/de/fhg/aisec/ids/webconsole/api/RestApiTests.java b/ids-webconsole/src/test/java/de/fhg/aisec/ids/webconsole/api/RestApiTests.java index aa633a2f5..0a717c9b0 100644 --- a/ids-webconsole/src/test/java/de/fhg/aisec/ids/webconsole/api/RestApiTests.java +++ b/ids-webconsole/src/test/java/de/fhg/aisec/ids/webconsole/api/RestApiTests.java @@ -21,6 +21,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider; +import de.fhg.aisec.ids.api.settings.Settings; import de.fhg.aisec.ids.webconsole.api.data.Cert; import de.fhg.aisec.ids.webconsole.api.data.Identity; import de.fhg.aisec.ids.webconsole.api.data.User; @@ -40,6 +41,7 @@ import java.util.Map; import static org.junit.Assume.assumeFalse; +import static org.mockito.Mockito.mock; public class RestApiTests extends Assert { private static final String ENDPOINT_ADDRESS = "local://testserver"; @@ -66,7 +68,7 @@ private static void startServer() { // add custom providers if any sf.setProviders(providers); - sf.setResourceProvider(CertApi.class, new SingletonResourceProvider(new CertApi(), true)); + sf.setResourceProvider(CertApi.class, new SingletonResourceProvider(new CertApi(mock(Settings.class)), true)); sf.setResourceProvider(MetricAPI.class, new SingletonResourceProvider(new MetricAPI(), true)); sf.setResourceProvider(UserApi.class, new SingletonResourceProvider(new UserApi(), true)); sf.setAddress(ENDPOINT_ADDRESS); @@ -94,7 +96,7 @@ public static void destroy() { @Before public void before() { - CertApi certApi = new CertApi(); + CertApi certApi = new CertApi(mock(Settings.class)); Identity idSpec = new Identity(); idSpec.c = "c"; diff --git a/jnr-unixsocket-wrapper/LICENSE.txt b/jnr-unixsocket-wrapper/LICENSE.txt deleted file mode 100644 index 261eeb9e9..000000000 --- a/jnr-unixsocket-wrapper/LICENSE.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/jnr-unixsocket-wrapper/README.md b/jnr-unixsocket-wrapper/README.md deleted file mode 100644 index 3709355b4..000000000 --- a/jnr-unixsocket-wrapper/README.md +++ /dev/null @@ -1 +0,0 @@ -The _jnr-unixsocket-wrapper_ module wraps the JNR unix socket to make it available to the OSGi layer. This is needed for protobuf communication with trustme as well as communication with the TPM. diff --git a/jnr-unixsocket-wrapper/bnd.bnd b/jnr-unixsocket-wrapper/bnd.bnd deleted file mode 100644 index 52c1fb67a..000000000 --- a/jnr-unixsocket-wrapper/bnd.bnd +++ /dev/null @@ -1,15 +0,0 @@ -Bundle-Name: JNR UnixSocket Wrapper -Bundle-Description: JNR UnixSocket Wrapper Bundle -# Import com.kenai.jffi and jnr.ffi from jnr-ffi bundle because of native libraries wrapped in it. -# Everything else is directly included in this wrapper bundle. -Import-Package: \ - com.kenai.jffi*,\ - jnr.ffi*,\ - !jnr*,\ - !sun.misc*,\ - !sun.nio*,\ - * -# Merge split-package jnr.enxio.channels from jnr-enxio and jnr-unixsocket. -Export-Package: \ - jnr.enxio.channels*;-split-package:=merge-last,\ - jnr* diff --git a/libraryVersions.yaml b/libraryVersions.yaml index 398ad515a..af8784e4a 100644 --- a/libraryVersions.yaml +++ b/libraryVersions.yaml @@ -93,3 +93,5 @@ paxExam: "4.13.3" awaitility: "3.1.6" servicemixHamcrest: "1.3_1" javaxAnnotation: "1.3.2" + +springBoot: "2.3.4.RELEASE" \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index f4ad49b49..363383dcb 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,20 +1,20 @@ rootProject.name = "trusted-connector-core" -include(":camel-idscp2-osgi") include(":camel-influxdb") include(":camel-multipart-processor") -include(":cxf-jaxws-patch") -include(":examples") -include(":ids-acme") +//include(":ids-acme") include(":ids-api") include(":ids-container-manager") include(":ids-dataflow-control") -include(":ids-dynamic-tls") +//include(":ids-dynamic-tls") include(":ids-endpoint-config") include(":ids-infomodel-manager") include(":ids-route-manager") include(":ids-settings") include(":ids-webconsole") -include(":jnr-unixsocket-wrapper") -include(":karaf-assembly") -include(":karaf-features-ids") + +include(":ids-connector") + +// will be extracted to a separate repository later +include(":example-idscp2-client-server") + From 3a313b0212695bcbe886207dbeef9b02c70d51a8 Mon Sep 17 00:00:00 2001 From: Christian Banse Date: Tue, 30 Mar 2021 22:37:42 +0200 Subject: [PATCH 03/54] Building without Docker Signed-off-by: Christian Banse --- .github/workflows/build.yml | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4d942d5ff..fb139b6cf 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -5,19 +5,14 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@master - - name: Cache gradle modules - uses: actions/cache@v1 - env: - cache-name: cache-gradle-modules + - name: Setup Java JDK + uses: actions/setup-java@v1.4.3 with: - path: ~/.gradle - key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/gradle.build') }} - restore-keys: | - ${{ runner.os }}-build-${{ env.cache-name }}- - ${{ runner.os }}-build- - ${{ runner.os }}- + java-version: 14 + - name: Setup protoc + uses: arduino/setup-protoc@v1.1.2 + with: + version: 3.x - name: Build run: | - mkdir -p ~/.gradle - mkdir -p ~/.m2 - ./build.sh + ./gradlew --parallel yarnBuild check build From 23411fa979e149b5643f511a3fbd746d4d0a2053 Mon Sep 17 00:00:00 2001 From: Christian Banse Date: Tue, 30 Mar 2021 22:47:17 +0200 Subject: [PATCH 04/54] Caching node_modules Signed-off-by: Christian Banse --- .github/workflows/build.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fb139b6cf..940f9f449 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -13,6 +13,10 @@ jobs: uses: arduino/setup-protoc@v1.1.2 with: version: 3.x + - uses: actions/cache@v2 + with: + path: '**/node_modules' + key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }} - name: Build run: | - ./gradlew --parallel yarnBuild check build + ./gradlew --parallel build From 574de29bb9886c24ffc88a80713ec3670a9c409e Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Tue, 27 Apr 2021 12:40:00 +0200 Subject: [PATCH 05/54] Minor improvements --- ids-connector/build.gradle.kts | 4 +++- .../src/main/resources/application.yml | 2 +- .../fhg/aisec/ids/rm/RouteManagerService.kt | 22 ++++++------------- jnr-unixsocket-wrapper/build.gradle.kts | 9 -------- 4 files changed, 11 insertions(+), 26 deletions(-) delete mode 100644 jnr-unixsocket-wrapper/build.gradle.kts diff --git a/ids-connector/build.gradle.kts b/ids-connector/build.gradle.kts index 7e5bba381..68aca8b97 100644 --- a/ids-connector/build.gradle.kts +++ b/ids-connector/build.gradle.kts @@ -1,3 +1,5 @@ +import org.springframework.boot.gradle.tasks.bundling.BootJar + @Suppress("UNCHECKED_CAST") val libraryVersions = rootProject.extra.get("libraryVersions") as Map @@ -9,7 +11,7 @@ plugins { kotlin("plugin.spring") } -tasks.getByName("bootJar") { +tasks.getByName("bootJar") { launchScript() layered() } diff --git a/ids-connector/src/main/resources/application.yml b/ids-connector/src/main/resources/application.yml index c6cea2df2..32c946ce0 100644 --- a/ids-connector/src/main/resources/application.yml +++ b/ids-connector/src/main/resources/application.yml @@ -1,4 +1,4 @@ logging: level: ROOT: INFO - de.fhg.aisec: DEBUG \ No newline at end of file + de.fhg.aisec: TRACE \ No newline at end of file diff --git a/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/RouteManagerService.kt b/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/RouteManagerService.kt index c5ad086f5..c984ed1cc 100644 --- a/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/RouteManagerService.kt +++ b/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/RouteManagerService.kt @@ -116,19 +116,16 @@ class RouteManagerService : RouteManager { ctx.getBeanNamesForType(ComponentConfigurationPropertiesCommon::class.java) // yes, this is a bit hacky but will do fow now - return Arrays.stream(beanNamesForType) - .map { name -> + return beanNamesForType + .mapNotNull { name -> val first = name.split("-org")[0] - if (first.equals("camel.component")) { - return@map null + if (first == "camel.component") { + null + } else { + RouteComponent("camel-" + first.split("camel.component.")[1], "") } - - return@map RouteComponent("camel-" + first.split("camel.component.")[1], "") } - .filter { Objects.nonNull(it) } - .collect(Collectors.toList()) as - List } override fun getEndpoints(): Map> { @@ -137,12 +134,7 @@ class RouteManagerService : RouteManager { .collect( Collectors.toMap( { obj: CamelContext -> obj.name }, - { c: CamelContext -> - c.endpoints - .stream() - .map { obj: Endpoint -> obj.endpointUri } - .collect(Collectors.toList()) - } + { c: CamelContext -> c.endpoints.map { obj: Endpoint -> obj.endpointUri } } ) ) } diff --git a/jnr-unixsocket-wrapper/build.gradle.kts b/jnr-unixsocket-wrapper/build.gradle.kts deleted file mode 100644 index a135fc9e3..000000000 --- a/jnr-unixsocket-wrapper/build.gradle.kts +++ /dev/null @@ -1,9 +0,0 @@ -@Suppress("UNCHECKED_CAST") -val libraryVersions = rootProject.extra.get("libraryVersions") as Map - -dependencies { - implementation("com.github.jnr", "jnr-unixsocket", libraryVersions["jnrunix"]) - // Only jnr-ffi is provided by bundle, because it contains native libraries - // Versions above 2.1.5 fail with a wiring exception for package com.github.jnr.jffi.native - unixSocketBundle("com.github.jnr", "jnr-ffi", libraryVersions["jnrffi"]) -} \ No newline at end of file From 74d74f2593feddadc0bf9d037ed3e195c6866b84 Mon Sep 17 00:00:00 2001 From: Christian Banse Date: Tue, 27 Apr 2021 19:31:21 +0200 Subject: [PATCH 06/54] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index f0000ff66..1e0cba9c5 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ ![build](https://github.com/industrial-data-space/trusted-connector/workflows/build/badge.svg) +> :warning: Note: We are currently in the transition of OSGi to Spring Boot. You can track the current progress in [this](https://github.com/industrial-data-space/trusted-connector/issues/49) issue. If you are looking for a stable version, please use the latest OSGi-based release (4.0.0) + The _Trusted Connector_ is an Apache Karaf-based platform for the Industrial Internet of Things (IIoT). It supports Docker and trust|me as containerization environments and provides the following features: * Message routing and conversion between protocols with Apache Camel From f7e99ffe0a16b161946e1e95aed8ef5f0c47808f Mon Sep 17 00:00:00 2001 From: Christian Banse Date: Tue, 27 Apr 2021 19:39:59 +0200 Subject: [PATCH 07/54] Update README.md --- README.md | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/README.md b/README.md index 1e0cba9c5..30a528742 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ![build](https://github.com/industrial-data-space/trusted-connector/workflows/build/badge.svg) -> :warning: Note: We are currently in the transition of OSGi to Spring Boot. You can track the current progress in [this](https://github.com/industrial-data-space/trusted-connector/issues/49) issue. If you are looking for a stable version, please use the latest OSGi-based release (4.0.0) +> :warning: Note: We are currently in the transition of OSGi to Spring Boot. You can track the current progress in [this](https://github.com/industrial-data-space/trusted-connector/issues/49) issue. If you are looking for a stable version, please use the latest OSGi-based release (4.0.0) or the [master](https://github.com/industrial-data-space/trusted-connector/tree/master) branch. The _Trusted Connector_ is an Apache Karaf-based platform for the Industrial Internet of Things (IIoT). It supports Docker and trust|me as containerization environments and provides the following features: @@ -19,13 +19,10 @@ Please refer to the [contribution guide](https://github.com/industrial-data-spac # Project structure -├── __karaf-assembly__ _Deployable "assembly" with runtime and all modules_
-├── __camel-ids__ _IDS protocol (IDSCP) as an Apache Camel component_
├── __camel-influxdb__ Influx DB adapter for Apache Camel. (optional. It is not included in the assembly by default)
├── __camel-multipart-processor__ _REST/MultiPart protocol as an Apache Camel component_
├── __ids-acme__ _ACME 2 client for retrieving TLS certificates for the web console UI_
├── __ids-api__ _Internal APIs of all IDS connector modules._
-├── __ids-comm__ _Communication manager, keeping track of IDSCP connections_
├── __ids-container-manager__ _Management interface to the underlying container management layer (trustme or docker)_
├── __ids-dataflow-control__ _LUCON data flow policy framework_
├── __ids-dynamic-tls__ _Fragment bundle to allow refreshing TLS certificates in Jetty web server without restarting_
@@ -34,6 +31,4 @@ Please refer to the [contribution guide](https://github.com/industrial-data-spac ├── __ids-settings__ _Manages connector configuration_
├── __ids-token-manager__ _Acquires and verifies JWT tokens received from the DAPS server_
├── __ids-webconsole__ _Management UI for the connector. Is contained in default assembly but could be moved out of it, if a smaller code base is desired_
-├── __jnr-unixsocket-wrapper__ _Helper bundle for UNIX sockets for trustme cmld connection_
├── __karaf-features-ids__ _Feature definition for Apache Karaf runtime_
-└── __rat_repository__ _Online repository for remote attestation. Actually not part of the Core Platform_
From 05984b559aed5ef54890c4b0ed6be058aff74ee5 Mon Sep 17 00:00:00 2001 From: Christian Banse Date: Wed, 28 Apr 2021 11:16:17 +0200 Subject: [PATCH 08/54] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 30a528742..5535ff51a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ![build](https://github.com/industrial-data-space/trusted-connector/workflows/build/badge.svg) -> :warning: Note: We are currently in the transition of OSGi to Spring Boot. You can track the current progress in [this](https://github.com/industrial-data-space/trusted-connector/issues/49) issue. If you are looking for a stable version, please use the latest OSGi-based release (4.0.0) or the [master](https://github.com/industrial-data-space/trusted-connector/tree/master) branch. +> :warning: Note: We are currently in the transition of OSGi to Spring Boot. You can track the current progress in [this](https://github.com/industrial-data-space/trusted-connector/issues/49) issue. If you are looking for a stable version, please use the latest OSGi-based release ([4.0.0](https://github.com/industrial-data-space/trusted-connector/releases/tag/4.0.0)) or the [master](https://github.com/industrial-data-space/trusted-connector/tree/master) branch. The _Trusted Connector_ is an Apache Karaf-based platform for the Industrial Internet of Things (IIoT). It supports Docker and trust|me as containerization environments and provides the following features: From 41fbb6043aa5a71d27e45142576339f7ba52b1c0 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Thu, 29 Apr 2021 13:04:21 +0200 Subject: [PATCH 09/54] Removed useless subproject --- karaf-features-ids/.gitignore | 1 - karaf-features-ids/LICENSE.txt | 201 ---------------------------- karaf-features-ids/README.md | 1 - karaf-features-ids/build.gradle.kts | 122 ----------------- 4 files changed, 325 deletions(-) delete mode 100644 karaf-features-ids/.gitignore delete mode 100644 karaf-features-ids/LICENSE.txt delete mode 100644 karaf-features-ids/README.md delete mode 100644 karaf-features-ids/build.gradle.kts diff --git a/karaf-features-ids/.gitignore b/karaf-features-ids/.gitignore deleted file mode 100644 index b83d22266..000000000 --- a/karaf-features-ids/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/target/ diff --git a/karaf-features-ids/LICENSE.txt b/karaf-features-ids/LICENSE.txt deleted file mode 100644 index 261eeb9e9..000000000 --- a/karaf-features-ids/LICENSE.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/karaf-features-ids/README.md b/karaf-features-ids/README.md deleted file mode 100644 index bdf56bc3a..000000000 --- a/karaf-features-ids/README.md +++ /dev/null @@ -1 +0,0 @@ -The _karaf-features-ids_ module is a helper to deploy bundles as karaf featues. diff --git a/karaf-features-ids/build.gradle.kts b/karaf-features-ids/build.gradle.kts deleted file mode 100644 index 3aa4dec45..000000000 --- a/karaf-features-ids/build.gradle.kts +++ /dev/null @@ -1,122 +0,0 @@ -import com.github.lburgazzoli.gradle.plugin.karaf.features.KarafFeaturesExtension -import com.github.lburgazzoli.gradle.plugin.karaf.features.model.BundleDescriptor -import com.github.lburgazzoli.gradle.plugin.karaf.features.model.FeatureDescriptor - -@Suppress("UNCHECKED_CAST") -val libraryVersions = rootProject.extra.get("libraryVersions") as Map - -plugins { - id("com.github.lburgazzoli.karaf") version "0.5.1" -} - -description = "IDS Karaf Feature" - -val bundleDependencies = ArrayList>() -val bundleConfigurations = ArrayList() - -configurations.filter { it.name.endsWith("Bundle") }.forEach { bundleConfigurations.add(it.name) } - -rootProject.subprojects - .filter { it.name.matches(Regex("(^camel-.*|ids-.*|.*-(patch|wrapper)\$)")) } - .forEach { p -> - var included = false - // Include each sub-project declaring dependencies with a configuration ending on "Bundle", - // using exactly that configuration for the dependency itself and selection of additional recursive dependencies. - p.configurations.filter { it.name.endsWith("Bundle") || it.name.endsWith("Feature") }.forEach { c -> - // Resolve the configuration to obtain dependencies - c.resolve() - if (c.dependencies.size > 0) { - included = true - bundleDependencies += c.name to p.name - } - } - // If project has not been included, include it using "providedByBundle" - if (!included) { - bundleDependencies += "providedByBundle" to p.name - } - } - -dependencies { - // Include the dependencies calculated above - bundleDependencies.forEach { - add(it.first, project(path = ":${it.second}", configuration = it.first)) - } - zmqFeature("org.apache-extras.camel-extra", "camel-zeromq", libraryVersions["camelZeroMQ"]) - providedByBundle("org.jetbrains.kotlin", "kotlin-osgi-bundle", libraryVersions["kotlin"]) - providedByBundle("jakarta.activation:jakarta.activation-api:1.2.2") -} - -karaf { - features(closureOf { - xsdVersion = "1.3.0" - // it seems to be best practice to include the version in the feature repository as well - name = "ids-${project.version}" - version = project.version as String - - // the camel repository - repository("mvn:org.apache.camel.karaf/apache-camel/${libraryVersions["camel"]}/xml/features") - - // include cxf repository, since the camel one is slightly outdated -// repository "mvn:org.apache.cxf.karaf/apache-cxf/${libraryVersions.cxf}/xml/features" - - feature(closureOf { - name = "ids" - description = "IDS Feature" - - // only specifiy the dependencies that will be provided by bundles, the rest will be specified via features - configurations(*bundleConfigurations.toTypedArray()) - - // standard feature, but we need to explicitly state it here so that it gets installed in our bare Karaf - feature("jetty") - - // CXF for REST APIs - feature("cxf-jaxrs") - feature("cxf-jackson") - - // CXF commands for the shell - /* - Notice: This should actually be a conditional dependency, only if shell is available. - however the karaf assemble plugin does not seem to resolve these conditions during packaging. - */ - feature("cxf-commands") - - // For Web Application Bundles, such as our WebConsole - feature("war") - - // Features for Apache Camel routing - feature("camel-jackson") - feature("camel-milo") - feature("camel-cxf") - feature("camel-ahc") - feature("camel-http") - feature("camel-jetty") - feature("camel-paho") - //feature("camel-mqtt") - feature("camel-jsonpath") - feature("camel-csv") - - // start our bundles a lit bit later - bundle ("de.fhg.aisec.ids", closureOf { - attribute("start-level", "90") - }) - }) - - feature(closureOf { - name = "camel-influxdb-aisec" - description = "Correctly packed version of camel-influxdb feature" - version = libraryVersions["camel"] - - //noinspection GroovyAssignabilityCheck - configurations("influxFeature") - }) - - feature(closureOf { - name = "camel-zeromq-aisec" - description = "Camel ZeroMQ feature" - version = libraryVersions["camelZeroMQ"] - - //noinspection GroovyAssignabilityCheck - configurations("zmqFeature") - }) - }) -} From 4a4f03ba92d35131292486c082a8115e234995cb Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Fri, 30 Apr 2021 10:48:30 +0200 Subject: [PATCH 10/54] Updated kotlin, more version pinning --- build.gradle.kts | 37 ++++++++++++++++++++++++++++++------- libraryVersions.yaml | 5 +++-- 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index ee21fdafb..97697f258 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,4 +1,3 @@ -import org.gradle.api.tasks.testing.logging.TestExceptionFormat import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.yaml.snakeyaml.Yaml @@ -29,8 +28,8 @@ plugins { id("com.google.protobuf") version "0.8.12" apply false // Kotlin specific - kotlin("jvm") version "1.4.31" apply false - kotlin("plugin.spring") version "1.4.31" apply false + kotlin("jvm") version "1.4.32" apply false + kotlin("plugin.spring") version "1.4.32" apply false id("com.diffplug.spotless") version "5.11.0" id("com.github.jk1.dependency-license-report") version "1.16" @@ -112,13 +111,37 @@ subprojects { // Needed for kotlin modules, provided at runtime via kotlin-osgi-bundle in karaf-features-ids compileOnly("org.jetbrains.kotlin", "kotlin-stdlib-jdk8", libraryVersions["kotlin"]) - // We need to explicitly specify the 1.4 version for all kotlin dependencies, - // because otherwise something (maybe a plugin) downgrades the kotlin version to 1.3, + // Some versions are downgraded for unknown reasons, fix this here + val groupPins = mapOf( + "org.jetbrains.kotlin" to mapOf( + "*" to "kotlin" + ), + "com.squareup.okhttp3" to mapOf( + "*" to "okhttp" + ), + "com.google.guava" to mapOf( + "guava" to "guava" + ) + ) + // We need to explicitly specify the kotlin version for all kotlin dependencies, + // because otherwise something (maybe a plugin) downgrades the kotlin version, // which produces errors in the kotlin compiler. This is really nasty. configurations.all { resolutionStrategy.eachDependency { - if (requested.group == "org.jetbrains.kotlin") { - useVersion(libraryVersions["kotlin"] ?: throw RuntimeException("kotlin version not set")) + groupPins[requested.group]?.let { pins -> + pins["*"]?.let { + // Pin all names when asterisk is set + useVersion( + libraryVersions[it] + ?: throw RuntimeException("Key \"$it\" not set in libraryVersions.yaml") + ) + } ?: pins[requested.name]?.let { pin -> + // Pin only for specific names given in map + useVersion( + libraryVersions[pin] + ?: throw RuntimeException("Key \"$pin\" not set in libraryVersions.yaml") + ) + } } } } diff --git a/libraryVersions.yaml b/libraryVersions.yaml index af8784e4a..a2c3ff6cb 100644 --- a/libraryVersions.yaml +++ b/libraryVersions.yaml @@ -1,7 +1,8 @@ -idscp2: "0.4.0" +idscp2: "0.4.3" +okhttp: "4.9.1" # Kotlin library/compiler version -kotlin: "1.4.31" +kotlin: "1.4.32" kotlinxCoroutines: "1.4.3" # basically, the first requirement, all other libraries depend on this version karaf: "4.2.10" From f93095d61eae4deefb2c20bf01ece5c1773a5425 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Fri, 30 Apr 2021 10:49:22 +0200 Subject: [PATCH 11/54] Small gradle cleanup --- build.gradle.kts | 10 ---------- camel-influxdb/build.gradle.kts | 6 ++---- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 97697f258..acb4a564c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -74,9 +74,6 @@ subprojects { } } - // just to make bills of materials (bom) easier to see in the dependency tree - val bom by configurations.creating - // Configuration for dependencies that will be provided through features in the OSGi environment val providedByFeature by configurations.creating @@ -86,11 +83,6 @@ subprojects { val unixSocketBundle by configurations.creating val infomodelBundle by configurations.creating - // Configurations for bundles grouped to dedicated features apart from the main ids feature - val influxFeature by configurations.creating - - val zmqFeature by configurations.creating - // OSGi core dependencies which will just be there during runtime val osgiCore by configurations.creating @@ -104,9 +96,7 @@ subprojects { // Logging API providedByBundle("org.slf4j", "slf4j-api", libraryVersions["slf4j"]) - val implementation by configurations val compileOnly by configurations - val testImplementation by configurations // Needed for kotlin modules, provided at runtime via kotlin-osgi-bundle in karaf-features-ids compileOnly("org.jetbrains.kotlin", "kotlin-stdlib-jdk8", libraryVersions["kotlin"]) diff --git a/camel-influxdb/build.gradle.kts b/camel-influxdb/build.gradle.kts index f19712029..504543655 100644 --- a/camel-influxdb/build.gradle.kts +++ b/camel-influxdb/build.gradle.kts @@ -2,8 +2,6 @@ val libraryVersions = rootProject.extra.get("libraryVersions") as Map dependencies { - val influxFeature by configurations - - influxFeature("org.influxdb", "influxdb-java", libraryVersions["influxDB"]) - influxFeature("org.apache.camel", "camel-influxdb", libraryVersions["camel"]) + implementation("org.influxdb", "influxdb-java", libraryVersions["influxDB"]) + implementation("org.apache.camel", "camel-influxdb", libraryVersions["camel"]) } From 5857f0067de00442b011cff5b7ccdc1d15359b8c Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Fri, 30 Apr 2021 14:28:36 +0200 Subject: [PATCH 12/54] Cleanup and ktlint --- build.gradle.kts | 27 +- camel-multipart-processor/build.gradle.kts | 8 +- .../multipart/MultiPartInputProcessor.kt | 2 +- .../multipart/MultiPartOutputProcessor.kt | 6 +- .../camel/multipart/MultiPartStringParser.kt | 8 +- example-idscp2-client-server/build.gradle.kts | 2 +- .../de/fhg/aisec/ids/ExampleIdscpClient.kt | 36 +- .../de/fhg/aisec/ids/ExampleIdscpServer.kt | 48 +-- .../etc/consumer-core-protocol-test.p12 | Bin 2709 -> 0 bytes .../main/resources/etc/consumer-keystore.p12 | Bin 2693 -> 2693 bytes .../etc/provider-core-protocol-test.p12 | Bin 2709 -> 0 bytes .../main/resources/etc/provider-keystore.p12 | Bin 2693 -> 2693 bytes .../src/main/resources/etc/settings.mapdb | Bin 2097152 -> 2097152 bytes examples/build.gradle.kts | 10 +- ids-acme/build.gradle.kts | 2 +- .../fhg/aisec/ids/acme/AcmeChallengeServer.kt | 16 +- .../fhg/aisec/ids/acme/AcmeClientService.kt | 50 +-- .../ids/acme/provider/BoulderAcmeProvider.kt | 4 +- ids-api/build.gradle.kts | 2 +- .../api/idscp2/Idscp2UsageControlInterface.kt | 2 +- ids-connector/build.gradle.kts | 20 ++ .../fhg/aisec/ids/ConnectorConfiguration.kt | 17 +- .../de/fhg/aisec/ids/TrustedConnector.kt | 1 - .../resources/etc/karaf_maven_settings.xml | 6 - .../src/main/resources/etc/settings.mapdb | Bin 2097152 -> 2097152 bytes ids-container-manager/build.gradle.kts | 4 +- .../fhg/aisec/ids/cm/impl/StreamGobbler.java | 5 +- .../fhg/aisec/ids/cm/impl/docker/DockerCM.kt | 37 ++- .../fhg/aisec/ids/cm/impl/dummy/DummyCM.java | 13 +- .../unixsocket/TrustmeUnixSocketThread.java | 49 ++- .../aisec/ids/cm/impl/trustx/TrustXMock.java | 50 ++- .../ids/cm/impl/trustx/TrustXMockHandler.java | 13 +- .../aisec/ids/cm/impl/docker/DockerCmIT.kt | 1 - ids-dataflow-control/build.gradle.kts | 2 +- .../dataflowcontrol/PolicyDecisionPoint.kt | 22 +- .../lucon/CounterExampleImpl.kt | 2 +- .../ids/dataflowcontrol/lucon/LuconEngine.kt | 3 +- .../ids/dataflowcontrol/lucon/LuconLibrary.kt | 2 +- .../dataflowcontrol/lucon/TuPrologHelper.kt | 3 +- .../ids/dataflowcontrol/LuconEngineTest.kt | 259 ++++++++------- ids-infomodel-manager/build.gradle.kts | 8 +- .../InfoModelService.kt | 17 +- ids-route-manager/build.gradle.kts | 2 +- .../de/fhg/aisec/ids/rm/CamelInterceptor.kt | 6 +- .../aisec/ids/rm/PolicyEnforcementPoint.kt | 26 +- .../fhg/aisec/ids/rm/RouteManagerService.kt | 32 +- .../fhg/aisec/ids/rm/util/CamelRouteToDot.kt | 36 +- .../fhg/aisec/ids/rm/util/GraphProcessor.kt | 3 +- .../de/fhg/aisec/ids/rm/util/NodeData.kt | 36 +- .../de/fhg/aisec/ids/rm/util/PrologNode.kt | 34 +- .../de/fhg/aisec/ids/rm/util/PrologPrinter.kt | 39 ++- .../de/fhg/aisec/ids/rm/RouteMetricsTest.kt | 2 +- ids-settings/build.gradle.kts | 4 +- .../aisec/ids/settings/SettingsComponent.kt | 17 +- ids-webconsole/build.gradle.kts | 82 +++-- .../ids/webconsole/WebConsoleComponent.java | 1 - .../webconsole/api/AuthorizationRequired.java | 2 +- .../webconsole/api/CORSResponseFilter.java | 5 +- .../ids/webconsole/api/ConnectionAPI.java | 4 +- .../aisec/ids/webconsole/api/MetricAPI.java | 8 +- .../aisec/ids/webconsole/api/PolicyApi.java | 11 +- .../aisec/ids/webconsole/api/RouteApi.java | 3 - .../aisec/ids/webconsole/api/SettingsApi.java | 4 - .../webconsole/api/data/ValidationInfo.java | 1 + .../api/helper/ProcessExecutor.java | 5 +- .../webconsole/api/helper/StreamGobbler.java | 5 +- karaf-assembly/.gitignore | 3 - .../.mvn/wrapper/MavenWrapperDownloader.java | 117 ------- karaf-assembly/.mvn/wrapper/maven-wrapper.jar | Bin 50710 -> 0 bytes .../.mvn/wrapper/maven-wrapper.properties | 2 - karaf-assembly/Dockerfile | 32 -- karaf-assembly/LICENSE.txt | 201 ------------ karaf-assembly/README.md | 19 -- karaf-assembly/build.gradle.kts | 127 ------- karaf-assembly/mvnw | 310 ------------------ karaf-assembly/mvnw.cmd | 182 ---------- karaf-assembly/pom.template.xml | 119 ------- karaf-assembly/src/main/resources/bin/setenv | 54 --- .../resources/deploy/flow-policy-example.pl | 45 --- .../main/resources/etc/consumer-keystore.p12 | Bin 2693 -> 0 bytes .../src/main/resources/etc/custom.properties | 41 --- .../resources/etc/de.fhg.dfcontrol.rules.cfg | 5 - .../etc/idscp2/aisecconnector1-keystore.p12 | Bin 2853 -> 0 bytes .../etc/idscp2/client-truststore_new.p12 | Bin 2266 -> 0 bytes .../etc/import_ca_chain_into_keystore.sh | 10 - .../src/main/resources/etc/jetty.xml | 91 ----- .../resources/etc/karaf_maven_settings.xml | 6 - .../org.apache.felix.fileinstall-deploy.cfg | 25 -- .../etc/org.apache.karaf.management.cfg | 112 ------- .../resources/etc/org.ops4j.pax.logging.cfg | 106 ------ .../resources/etc/org.ops4j.pax.url.mvn.cfg | 42 --- .../main/resources/etc/org.ops4j.pax.web.cfg | 64 ---- .../main/resources/etc/provider-keystore.p12 | Bin 2693 -> 0 bytes .../src/main/resources/etc/system.properties | 155 --------- .../etc/tls-webconsole/keystore_latest.p12 | Bin 5665 -> 0 bytes .../src/main/resources/etc/truststore.p12 | Bin 2266 -> 0 bytes .../src/main/resources/etc/users.properties | 37 --- .../etc/branding.properties | 22 -- .../etc/org.apache.karaf.features.xml | 13 - .../de/fhg/aisec/ids/assembly/AssemblyIT.java | 112 ------- karaf-assembly/system/index.xml | 3 - karaf-assembly/system/index.xml.sha | 1 - libraryVersions.yaml | 5 +- settings.gradle.kts | 5 +- 104 files changed, 633 insertions(+), 2558 deletions(-) delete mode 100644 example-idscp2-client-server/src/main/resources/etc/consumer-core-protocol-test.p12 delete mode 100644 example-idscp2-client-server/src/main/resources/etc/provider-core-protocol-test.p12 rename {karaf-assembly => example-idscp2-client-server}/src/main/resources/etc/settings.mapdb (99%) delete mode 100644 ids-connector/src/main/resources/etc/karaf_maven_settings.xml delete mode 100644 karaf-assembly/.gitignore delete mode 100644 karaf-assembly/.mvn/wrapper/MavenWrapperDownloader.java delete mode 100755 karaf-assembly/.mvn/wrapper/maven-wrapper.jar delete mode 100755 karaf-assembly/.mvn/wrapper/maven-wrapper.properties delete mode 100644 karaf-assembly/Dockerfile delete mode 100644 karaf-assembly/LICENSE.txt delete mode 100644 karaf-assembly/README.md delete mode 100644 karaf-assembly/build.gradle.kts delete mode 100755 karaf-assembly/mvnw delete mode 100755 karaf-assembly/mvnw.cmd delete mode 100644 karaf-assembly/pom.template.xml delete mode 100755 karaf-assembly/src/main/resources/bin/setenv delete mode 100644 karaf-assembly/src/main/resources/deploy/flow-policy-example.pl delete mode 100644 karaf-assembly/src/main/resources/etc/consumer-keystore.p12 delete mode 100644 karaf-assembly/src/main/resources/etc/custom.properties delete mode 100644 karaf-assembly/src/main/resources/etc/de.fhg.dfcontrol.rules.cfg delete mode 100644 karaf-assembly/src/main/resources/etc/idscp2/aisecconnector1-keystore.p12 delete mode 100644 karaf-assembly/src/main/resources/etc/idscp2/client-truststore_new.p12 delete mode 100644 karaf-assembly/src/main/resources/etc/import_ca_chain_into_keystore.sh delete mode 100644 karaf-assembly/src/main/resources/etc/jetty.xml delete mode 100644 karaf-assembly/src/main/resources/etc/karaf_maven_settings.xml delete mode 100644 karaf-assembly/src/main/resources/etc/org.apache.felix.fileinstall-deploy.cfg delete mode 100644 karaf-assembly/src/main/resources/etc/org.apache.karaf.management.cfg delete mode 100644 karaf-assembly/src/main/resources/etc/org.ops4j.pax.logging.cfg delete mode 100644 karaf-assembly/src/main/resources/etc/org.ops4j.pax.url.mvn.cfg delete mode 100644 karaf-assembly/src/main/resources/etc/org.ops4j.pax.web.cfg delete mode 100644 karaf-assembly/src/main/resources/etc/provider-keystore.p12 delete mode 100644 karaf-assembly/src/main/resources/etc/system.properties delete mode 100644 karaf-assembly/src/main/resources/etc/tls-webconsole/keystore_latest.p12 delete mode 100644 karaf-assembly/src/main/resources/etc/truststore.p12 delete mode 100644 karaf-assembly/src/main/resources/etc/users.properties delete mode 100644 karaf-assembly/src/main/template-resources/etc/branding.properties delete mode 100644 karaf-assembly/src/main/template-resources/etc/org.apache.karaf.features.xml delete mode 100644 karaf-assembly/src/test/java/de/fhg/aisec/ids/assembly/AssemblyIT.java delete mode 100644 karaf-assembly/system/index.xml delete mode 100644 karaf-assembly/system/index.xml.sha diff --git a/build.gradle.kts b/build.gradle.kts index acb4a564c..2120cee17 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -14,7 +14,7 @@ repositories { plugins { java maven - + // Spring Boot id("org.springframework.boot") version "2.3.4.RELEASE" apply false id("io.spring.dependency-management") version "1.0.8.RELEASE" @@ -37,7 +37,7 @@ plugins { @Suppress("UNCHECKED_CAST") val libraryVersions: Map = - Yaml().loadAs(file("${rootDir}/libraryVersions.yaml").inputStream(), Map::class.java) as Map + Yaml().loadAs(file("$rootDir/libraryVersions.yaml").inputStream(), Map::class.java) as Map extra.set("libraryVersions", libraryVersions) licenseReport { @@ -62,7 +62,7 @@ subprojects { apply(plugin = "java-library") apply(plugin = "org.jetbrains.kotlin.jvm") apply(plugin = "io.spring.dependency-management") - + configure { imports { mavenBom("org.springframework.boot:spring-boot-dependencies:${libraryVersions["springBoot"]}") @@ -89,8 +89,10 @@ subprojects { // For artifacts that should be included as "compile" dependencies into published maven artifacts val publishCompile by configurations.creating - configurations["compile"].extendsFrom(providedByFeature, providedByBundle, unixSocketBundle, infomodelBundle, - osgiCore, publishCompile) + configurations["compile"].extendsFrom( + providedByFeature, providedByBundle, unixSocketBundle, infomodelBundle, + osgiCore, publishCompile + ) dependencies { // Logging API @@ -152,8 +154,8 @@ subprojects { tasks.jar { manifest { attributes( - "Bundle-Vendor" to "Fraunhofer AISEC", - "-noee" to true + "Bundle-Vendor" to "Fraunhofer AISEC", + "-noee" to true ) } } @@ -163,11 +165,11 @@ configure(subprojects.filter { it.name != "examples" }) { apply(plugin = "com.diffplug.spotless") spotless { - isEnforceCheck = false - kotlin { - ktfmt().kotlinlangStyle() - licenseHeader("""/*- + target("**/*.kt") + ktlint(libraryVersions["ktlint"]) + licenseHeader( + """/*- * ========================LICENSE_START================================= * ${project.name} * %% @@ -185,7 +187,8 @@ configure(subprojects.filter { it.name != "examples" }) { * See the License for the specific language governing permissions and * limitations under the License. * =========================LICENSE_END================================== - */""").yearSeparator(" - ") + */""" + ).yearSeparator(" - ") } } } diff --git a/camel-multipart-processor/build.gradle.kts b/camel-multipart-processor/build.gradle.kts index 5b2eebf2c..59cf9dc80 100644 --- a/camel-multipart-processor/build.gradle.kts +++ b/camel-multipart-processor/build.gradle.kts @@ -1,15 +1,15 @@ dependencies { @Suppress("UNCHECKED_CAST") val libraryVersions = - rootProject.extra.get("libraryVersions") as Map + rootProject.extra.get("libraryVersions") as Map providedByBundle(project(":ids-api")) { isTransitive = false } providedByFeature("org.apache.camel", "camel-core", libraryVersions["camel"]) - providedByFeature("org.apache.camel", "camel-http4", libraryVersions["camelHttp4"]) + providedByFeature("org.apache.camel", "camel-http4", libraryVersions["camelHttp4"]) providedByBundle("org.apache.httpcomponents", "httpcore-osgi", libraryVersions["httpcore"]) - providedByBundle("org.apache.httpcomponents", "httpclient-osgi", libraryVersions["httpclient"]) - + providedByBundle("org.apache.httpcomponents", "httpclient-osgi", libraryVersions["httpclient"]) + providedByBundle("commons-fileupload", "commons-fileupload", libraryVersions["commonsFileUpload"]) osgiCore("org.apache.felix", "org.apache.felix.framework", libraryVersions["felixFramework"]) diff --git a/camel-multipart-processor/src/main/kotlin/de/fhg/aisec/ids/camel/multipart/MultiPartInputProcessor.kt b/camel-multipart-processor/src/main/kotlin/de/fhg/aisec/ids/camel/multipart/MultiPartInputProcessor.kt index 3df70d2df..2fbe6664f 100644 --- a/camel-multipart-processor/src/main/kotlin/de/fhg/aisec/ids/camel/multipart/MultiPartInputProcessor.kt +++ b/camel-multipart-processor/src/main/kotlin/de/fhg/aisec/ids/camel/multipart/MultiPartInputProcessor.kt @@ -19,9 +19,9 @@ */ package de.fhg.aisec.ids.camel.multipart -import java.io.InputStream import org.apache.camel.Exchange import org.apache.camel.Processor +import java.io.InputStream class MultiPartInputProcessor : Processor { @Throws(Exception::class) diff --git a/camel-multipart-processor/src/main/kotlin/de/fhg/aisec/ids/camel/multipart/MultiPartOutputProcessor.kt b/camel-multipart-processor/src/main/kotlin/de/fhg/aisec/ids/camel/multipart/MultiPartOutputProcessor.kt index 494c34a49..0120a4718 100644 --- a/camel-multipart-processor/src/main/kotlin/de/fhg/aisec/ids/camel/multipart/MultiPartOutputProcessor.kt +++ b/camel-multipart-processor/src/main/kotlin/de/fhg/aisec/ids/camel/multipart/MultiPartOutputProcessor.kt @@ -20,9 +20,6 @@ package de.fhg.aisec.ids.camel.multipart import de.fhg.aisec.ids.api.infomodel.InfoModel -import java.io.InputStream -import java.nio.charset.StandardCharsets -import java.util.* import org.apache.camel.Exchange import org.apache.camel.Processor import org.apache.http.entity.ContentType @@ -30,6 +27,9 @@ import org.apache.http.entity.mime.HttpMultipartMode import org.apache.http.entity.mime.MultipartEntityBuilder import org.apache.http.entity.mime.content.InputStreamBody import org.apache.http.entity.mime.content.StringBody +import java.io.InputStream +import java.nio.charset.StandardCharsets +import java.util.UUID /** * The MultiPartOutputProcessor will read the Exchange's header "ids" (if present) and the diff --git a/camel-multipart-processor/src/main/kotlin/de/fhg/aisec/ids/camel/multipart/MultiPartStringParser.kt b/camel-multipart-processor/src/main/kotlin/de/fhg/aisec/ids/camel/multipart/MultiPartStringParser.kt index ad545312c..1c161522c 100644 --- a/camel-multipart-processor/src/main/kotlin/de/fhg/aisec/ids/camel/multipart/MultiPartStringParser.kt +++ b/camel-multipart-processor/src/main/kotlin/de/fhg/aisec/ids/camel/multipart/MultiPartStringParser.kt @@ -19,15 +19,15 @@ */ package de.fhg.aisec.ids.camel.multipart +import org.apache.commons.fileupload.FileUpload +import org.apache.commons.fileupload.UploadContext +import org.apache.commons.fileupload.disk.DiskFileItemFactory +import org.slf4j.LoggerFactory import java.io.BufferedReader import java.io.IOException import java.io.InputStream import java.io.InputStreamReader import java.nio.charset.StandardCharsets -import org.apache.commons.fileupload.FileUpload -import org.apache.commons.fileupload.UploadContext -import org.apache.commons.fileupload.disk.DiskFileItemFactory -import org.slf4j.LoggerFactory class MultiPartStringParser internal constructor(private val multipartInput: InputStream) : UploadContext { diff --git a/example-idscp2-client-server/build.gradle.kts b/example-idscp2-client-server/build.gradle.kts index 845cfda41..d33b2b7d7 100644 --- a/example-idscp2-client-server/build.gradle.kts +++ b/example-idscp2-client-server/build.gradle.kts @@ -12,4 +12,4 @@ dependencies { implementation(project(":ids-connector")) implementation("org.springframework.boot:spring-boot-starter") -} \ No newline at end of file +} diff --git a/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpClient.kt b/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpClient.kt index 5c19b83ad..f2a879484 100644 --- a/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpClient.kt +++ b/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpClient.kt @@ -19,7 +19,6 @@ */ package de.fhg.aisec.ids -import java.io.File import org.apache.camel.RoutesBuilder import org.apache.camel.builder.RouteBuilder import org.apache.camel.support.jsse.KeyManagersParameters @@ -28,6 +27,7 @@ import org.apache.camel.support.jsse.SSLContextParameters import org.apache.camel.support.jsse.TrustManagersParameters import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration +import java.nio.file.FileSystems @Configuration open class ExampleIdscpClient { @@ -39,24 +39,12 @@ open class ExampleIdscpClient { ctx.keyManagers = KeyManagersParameters() ctx.keyManagers.keyStore = KeyStoreParameters() ctx.keyManagers.keyStore.resource = - File( - Thread.currentThread() - .contextClassLoader - .getResource("etc/provider-core-protocol-test.p12") - .path - ) - .path + FileSystems.getDefault().getPath("etc", "provider-keystore.p12").toFile().path ctx.keyManagers.keyStore.password = "password" ctx.trustManagers = TrustManagersParameters() ctx.trustManagers.keyStore = KeyStoreParameters() ctx.trustManagers.keyStore.resource = - File( - Thread.currentThread() - .contextClassLoader - .getResource("etc/truststore.p12") - .path - ) - .path + FileSystems.getDefault().getPath("etc", "truststore.p12").toFile().path ctx.trustManagers.keyStore.password = "password" return ctx @@ -67,22 +55,14 @@ open class ExampleIdscpClient { return object : RouteBuilder() { override fun configure() { from("timer://tenSecondsTimer?fixedRate=true&period=10000") - .setBody() - .simple("PING") - .setHeader("idscp2-header") - .simple("ping") + .setBody().simple("PING") + .setHeader("idscp2-header").simple("ping") .log("Client sends: \${body} (Header: \${headers[idscp2-header]})") - .to( - "idscp2client://localhost:29292?awaitResponse=true&sslContextParameters=#clientSslContext" - ) + .to("idscp2client://consumer-core:29292?awaitResponse=true&sslContextParameters=#clientSslContext") .log("Client received: \${body} (Header: \${headers[idscp2-header]})") - .removeHeader( - "idscp2-header" - ) // Prevents the client consumer from sending the message back to the server - .setBody() - .simple("\${null}") + .removeHeader("idscp2-header") // Prevents client consumer from sending the message back to the server + .setBody().simple("\${null}") } } } - } diff --git a/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpServer.kt b/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpServer.kt index 4183e3c54..c4358c4a2 100644 --- a/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpServer.kt +++ b/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpServer.kt @@ -1,3 +1,22 @@ +/*- + * ========================LICENSE_START================================= + * example-idscp2-client-server + * %% + * Copyright (C) 2021 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ package de.fhg.aisec.ids import org.apache.camel.RoutesBuilder @@ -8,10 +27,11 @@ import org.apache.camel.support.jsse.SSLContextParameters import org.apache.camel.support.jsse.TrustManagersParameters import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration -import java.io.File +import java.nio.file.FileSystems @Configuration open class ExampleIdscpServer { + @Bean("serverSslContext") open fun createSSLContext(): SSLContextParameters { val ctx = SSLContextParameters() @@ -19,41 +39,27 @@ open class ExampleIdscpServer { ctx.keyManagers = KeyManagersParameters() ctx.keyManagers.keyStore = KeyStoreParameters() ctx.keyManagers.keyStore.resource = - File( - Thread.currentThread() - .contextClassLoader - .getResource("etc/consumer-core-protocol-test.p12") - .path - ) - .path + FileSystems.getDefault().getPath("etc", "consumer-keystore.p12").toFile().path ctx.keyManagers.keyStore.password = "password" ctx.trustManagers = TrustManagersParameters() ctx.trustManagers.keyStore = KeyStoreParameters() ctx.trustManagers.keyStore.resource = - File( - Thread.currentThread() - .contextClassLoader - .getResource("etc/truststore.p12") - .path - ) - .path + FileSystems.getDefault().getPath("etc", "truststore.p12").toFile().path ctx.trustManagers.keyStore.password = "password" return ctx } @Bean - open fun server(): RoutesBuilder? { + open fun server(): RoutesBuilder { return object : RouteBuilder() { override fun configure() { from("idscp2server://0.0.0.0:29292?sslContextParameters=#serverSslContext") .log("Server received: \${body} (Header: \${headers[idscp2-header]})") - .setBody() - .simple("PONG") - .setHeader("idscp2-header") - .simple("pong") + .setBody().simple("PONG") + .setHeader("idscp2-header").simple("pong") .log("Server response: \${body} (Header: \${headers[idscp2-header]})") } } } -} \ No newline at end of file +} diff --git a/example-idscp2-client-server/src/main/resources/etc/consumer-core-protocol-test.p12 b/example-idscp2-client-server/src/main/resources/etc/consumer-core-protocol-test.p12 deleted file mode 100644 index b9022b7f7b58878a01de63efdf91d0df67d3e00d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2709 zcmV;G3TpK*f(nrW0Ru3C3ReaRDuzgg_YDCD0ic2kNCbikL@M3t zMH4m#0s;sCfPw_D1jn0KTM5L?cD$TEiH*GiT%7LX$$K5YWT3$BM{QQ!UXf65UZmKO znKc*^mEH!eqQ!n{@YC#^!6EdTAHKr9rmEJoeyR~Up(B>SK6I+sibm*N=H+&>`g87O zSO7D}Ie^D0nvxy7fgn=CF9&cA2>02ZoPP2Lv&L9Q<;;Vx$kyoDNf2;Iqwch$fhALw z&W%rZJ5lB@D&%-h=Fw!%oU&HmD~M<XlYK`Qo z1r*r;)$}qyxy3P(MF!?J1XZSmAjM2zJN)}2_cQ1PNO8)0qy>t(Zj%y<=F}%ukI8NCE;3X?cHnLS
-3?R$*)FBmO3H&PfaLGrXlZSY>& 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 XJR8iQc6$T}hr^oFtLI=v0s;sC>~F<6 diff --git a/example-idscp2-client-server/src/main/resources/etc/provider-core-protocol-test.p12 b/example-idscp2-client-server/src/main/resources/etc/provider-core-protocol-test.p12 deleted file mode 100644 index 020b5f1cf2e0c3e9b3caf400585d671f0e1d8231..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2709 zcmV;G3TpK*f(nrW0Ru3C3ReaRDuzgg_YDCD0ic2kNCbikL@#&XqvO}`@x{FpbPaYqN`AwT71 z8D%sq#jhA0rY+I#0mu}4Ajr8ZMpU!gvdSSZ!Y`NH@$T~=`sLD>p9jobG;`v9!?Wl zoPP!I30jxWYR+EOTirf$5172y;mGhCq!anUDRw4RddIx6v~v6yS`WjI3;5-a;fjf> zi6R}2Oj2H8oOq>2PBGMRawSt#OBEh@3-#bAQclm}pSrXiHbAPE`Z|<#AP0yX_O~rL zy_ArV4FX=0?ZKA)mc3otNf&OhaZCtj8WH2na5uZScyz$L*tDVp%z#sZ`k=B~_n$~h zp5G5X1wB!|4s11T`ysf{2gBC7<@)jdn@eF}$$#4?*BUzGUc_f7u^KBfn|J}G%lKFiY_g#TSPqtN&h`y#chP`45H zo6F;FPADgu?M8rRY`*2W2qw~dOn)((@50bod00YW_u9RtMOxLu%vxh~FZFlfkGj{GS-D$*{$9kq zD1Wsmx72QB+S<`l4Ia+oCA#nmI!DPNXBS~P>tZ-QdPHr}2{F|e)d4bnk!H#K9WU2r zM;L5C;5~01nU|Xu5;T6P+QOFKQi$X+Z2m#{Sy&xjIIOY}*Mpr!2M7QYcw_`0)m%|( zw{SA0EhldOn)rX9vn&We43h!I3-%E6eX5F!Ms&eH1470{KFd8aDxX-vPk3QZJyVg0 z^o2NdKC4{xhVA-LD;iQcGm`LvO{#1Jc)?&<6I}uSEmxXf#;sSPI@NWibeBqZ^YvH& z^pe`F?y)Ja^Z5k(Z@#(10E?!QS4tiG4<3}YvnfomEvs<72RC24XqzgW!-2Id4^0{x z$L?|kqYej&i%(ky9_dq9Z0n^oZ;5d(DzwvbyLuB!u)}HeD*kmP6>rUY=F?)4p&FEi z^N7Y1Krcd~%TR|=mpX2b*2STn{N=KD4PGjQy_#pB$Fs52HbVeIm@POHQmUA%w!H7Q zoA~q|+AB;C|F2}^r?TUsFoFd^1_>&LNQUS_k#WVg0I64gV|SwFPk4> zzhU$hQD6C@g6FogFvYM48T}n|T>REaBrnh5HO?i^8k9CO?lvw17MmUs)X3P6d0up= zn@uR5`xY7^DNiA$tcuJd~frPOng?y}J_(9T06#Lfv&KsA5wE zLGvGANKXCrNr9so8gl8&o+JFER4f2`OKd5la@P0nV528LIi zj!3fqjl895GFD--4Fqr}KuD>1t$1;r4Td#M@ZEV%g=>V*iEq$ndqh+De_2a2-!CEr$Is{!4~nkqZHTi#WSe(?24dQ6tYehKj%25F+vB+-DR%~y7^O`lcJ z#~~eCkm2t|{yy^(bN74yuRuM6QqA4Uu`pP1Y_Bf``R$$h!TGzOJi?aT|MBYD>?$%^ zBPeYJ1`7nW$7bj+Z6^XZP;GXrk_`0c?}5-gdrmWA zU5hiO8!HrOm)5}`>uoqx=)cU$~&vSTw+ehsjW*I+^m7Yg`|2#)*6Awfi$fu4pHv`|A7>KHQgm3zIXTW8i46 z&EqXgt=H-J-^%db4N;1?~aWvEt}Q`j1|M;c4}LSYo@Me z4i>5X1Hu&jri9uf9v77U8c$|Q7wZkAhLO=I&jdw=PKI!k1Fg0dbarhLso940zKDOf z@q;!r8v|Uw#Pr5fa2O&o&0CGtN$7*KqL!NcK5MWn@z+Z)XGu P6LsbnYPsWf0s;sC@3->f diff --git a/example-idscp2-client-server/src/main/resources/etc/provider-keystore.p12 b/example-idscp2-client-server/src/main/resources/etc/provider-keystore.p12 index 7c45bd3087048bbef49cfcbf4d4cd40a338a82c2..830797f6993b334c9886c6aae7031b06a96bcb4d 100644 GIT binary patch delta 2561 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 X<3QlwJ;($I-FzHzECO!O0s;sCHZb56 delta 2561 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 X7u_U#D&qtQ-j16bohhyH0s;sC#B|r& diff --git a/karaf-assembly/src/main/resources/etc/settings.mapdb b/example-idscp2-client-server/src/main/resources/etc/settings.mapdb similarity index 99% rename from karaf-assembly/src/main/resources/etc/settings.mapdb rename to example-idscp2-client-server/src/main/resources/etc/settings.mapdb index dae8b18ff5a441150281270e9f64152dfcab9745..8f917658d00d1fe438e29c26f12cec9cde499d40 100644 GIT binary patch delta 302 zcmXwyyAArXZLQlxTq?K9BZvpki&m#lcn2~kE0HKcaEI157WQqc;K{l|L=*r2P{A$5|9O=K1n mq)S4IkRqfADME^nBBTf@LW+*GDOG&T* diff --git a/examples/build.gradle.kts b/examples/build.gradle.kts index cc768c319..99a9efb2f 100644 --- a/examples/build.gradle.kts +++ b/examples/build.gradle.kts @@ -6,7 +6,7 @@ val copyExample = tasks.create("copyExample") { doFirst { delete(project.buildDir) } - from (project.projectDir) { + from(project.projectDir) { include("example-*/**", "tpmsim/tpmsim_data.tar", "tpmsim/rootCA.crt", "cert-stores/*") exclude("example-idscp/example-client", "example-idscp/example-server") } @@ -29,8 +29,10 @@ processTemplates.onlyIf { findProperty("exampleTag") != null } // Create ZIP archive from examples, see task copyExample val zipExample = task("zipExample") { doLast { - zipTo(File("${projectDir}/trusted-connector-examples_${findProperty("exampleTag")}.zip"), - project.buildDir) + zipTo( + File("$projectDir/trusted-connector-examples_${findProperty("exampleTag")}.zip"), + project.buildDir + ) } } zipExample.onlyIf { findProperty("exampleTag") != null } @@ -52,4 +54,4 @@ gradle.taskGraph.whenReady { } } } -} \ No newline at end of file +} diff --git a/ids-acme/build.gradle.kts b/ids-acme/build.gradle.kts index cfc2a0b97..38b0e5064 100644 --- a/ids-acme/build.gradle.kts +++ b/ids-acme/build.gradle.kts @@ -1,6 +1,6 @@ dependencies { @Suppress("UNCHECKED_CAST") val libraryVersions = - rootProject.extra.get("libraryVersions") as Map + rootProject.extra.get("libraryVersions") as Map providedByBundle(project(":ids-api")) { isTransitive = false } diff --git a/ids-acme/src/main/kotlin/de/fhg/aisec/ids/acme/AcmeChallengeServer.kt b/ids-acme/src/main/kotlin/de/fhg/aisec/ids/acme/AcmeChallengeServer.kt index d2323bce0..59c47cfd9 100644 --- a/ids-acme/src/main/kotlin/de/fhg/aisec/ids/acme/AcmeChallengeServer.kt +++ b/ids-acme/src/main/kotlin/de/fhg/aisec/ids/acme/AcmeChallengeServer.kt @@ -21,11 +21,11 @@ package de.fhg.aisec.ids.acme import de.fhg.aisec.ids.api.acme.AcmeClient import fi.iki.elonen.NanoHTTPD +import org.slf4j.LoggerFactory import java.io.ByteArrayInputStream import java.io.IOException import java.nio.charset.StandardCharsets import java.util.regex.Pattern -import org.slf4j.LoggerFactory object AcmeChallengeServer { const val TEXT_PLAIN = "text/plain" @@ -37,12 +37,12 @@ object AcmeChallengeServer { fun startServer(acmeClient: AcmeClient, challengePort: Int) { server = object : NanoHTTPD(challengePort) { - override fun serve(session: NanoHTTPD.IHTTPSession): NanoHTTPD.Response { + override fun serve(session: IHTTPSession): Response { val tokenMatcher = ACME_REGEX.matcher(session.uri) if (!tokenMatcher.matches()) { LOG.error("Received invalid ACME challenge {} ", session.uri) - return NanoHTTPD.newFixedLengthResponse( - NanoHTTPD.Response.Status.BAD_REQUEST, + return newFixedLengthResponse( + Response.Status.BAD_REQUEST, TEXT_PLAIN, null ) @@ -52,16 +52,16 @@ object AcmeChallengeServer { val response = acmeClient.getChallengeAuthorization(token) return if (response == null) { LOG.warn("ACME challenge is unknown") - NanoHTTPD.newFixedLengthResponse( - NanoHTTPD.Response.Status.NOT_FOUND, + newFixedLengthResponse( + Response.Status.NOT_FOUND, TEXT_PLAIN, null ) } else { LOG.info("ACME challenge response: {}", response) val responseBytes = response.toByteArray(StandardCharsets.UTF_8) - NanoHTTPD.newFixedLengthResponse( - NanoHTTPD.Response.Status.OK, + newFixedLengthResponse( + Response.Status.OK, TEXT_PLAIN, ByteArrayInputStream(responseBytes), responseBytes.size.toLong() diff --git a/ids-acme/src/main/kotlin/de/fhg/aisec/ids/acme/AcmeClientService.kt b/ids-acme/src/main/kotlin/de/fhg/aisec/ids/acme/AcmeClientService.kt index 114bbdbf6..bcd173b27 100644 --- a/ids-acme/src/main/kotlin/de/fhg/aisec/ids/acme/AcmeClientService.kt +++ b/ids-acme/src/main/kotlin/de/fhg/aisec/ids/acme/AcmeClientService.kt @@ -23,6 +23,22 @@ import de.fhg.aisec.ids.api.acme.AcmeClient import de.fhg.aisec.ids.api.acme.AcmeTermsOfService import de.fhg.aisec.ids.api.acme.SslContextFactoryReloadable import de.fhg.aisec.ids.api.settings.Settings +import org.apache.karaf.scheduler.Scheduler +import org.osgi.service.component.annotations.Activate +import org.osgi.service.component.annotations.Component +import org.osgi.service.component.annotations.Reference +import org.osgi.service.component.annotations.ReferenceCardinality +import org.shredzone.acme4j.Account +import org.shredzone.acme4j.AccountBuilder +import org.shredzone.acme4j.Order +import org.shredzone.acme4j.Session +import org.shredzone.acme4j.Status +import org.shredzone.acme4j.challenge.Http01Challenge +import org.shredzone.acme4j.exception.AcmeException +import org.shredzone.acme4j.exception.AcmeNetworkException +import org.shredzone.acme4j.util.CSRBuilder +import org.shredzone.acme4j.util.KeyPairUtils +import org.slf4j.LoggerFactory import java.io.IOException import java.io.InputStreamReader import java.net.URI @@ -36,19 +52,9 @@ import java.security.KeyStore import java.security.cert.X509Certificate import java.time.LocalDateTime import java.time.format.DateTimeFormatter -import java.util.* -import org.apache.karaf.scheduler.Scheduler -import org.osgi.service.component.annotations.Activate -import org.osgi.service.component.annotations.Component -import org.osgi.service.component.annotations.Reference -import org.osgi.service.component.annotations.ReferenceCardinality -import org.shredzone.acme4j.* -import org.shredzone.acme4j.challenge.Http01Challenge -import org.shredzone.acme4j.exception.AcmeException -import org.shredzone.acme4j.exception.AcmeNetworkException -import org.shredzone.acme4j.util.CSRBuilder -import org.shredzone.acme4j.util.KeyPairUtils -import org.slf4j.LoggerFactory +import java.util.Arrays +import java.util.Collections +import java.util.Date @Component( immediate = true, @@ -245,19 +251,19 @@ class AcmeClientService : AcmeClient, Runnable { LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd_HH:mm:ss.SSS")) try { Files.newBufferedReader( - targetDirectory.resolve("domain.key"), - StandardCharsets.UTF_8 - ) + targetDirectory.resolve("domain.key"), + StandardCharsets.UTF_8 + ) .use { keyReader -> Files.newBufferedWriter( - targetDirectory.resolve("csr_ $timestamp.csr"), - StandardCharsets.UTF_8 - ) + targetDirectory.resolve("csr_ $timestamp.csr"), + StandardCharsets.UTF_8 + ) .use { csrWriter -> Files.newBufferedWriter( - targetDirectory.resolve("cert-chain_$timestamp.crt"), - StandardCharsets.UTF_8 - ) + targetDirectory.resolve("cert-chain_$timestamp.crt"), + StandardCharsets.UTF_8 + ) .use { chainWriter -> val domainKeyPair = KeyPairUtils.readKeyPair(keyReader) diff --git a/ids-acme/src/main/kotlin/de/fhg/aisec/ids/acme/provider/BoulderAcmeProvider.kt b/ids-acme/src/main/kotlin/de/fhg/aisec/ids/acme/provider/BoulderAcmeProvider.kt index 50acfea23..48a6f32e2 100644 --- a/ids-acme/src/main/kotlin/de/fhg/aisec/ids/acme/provider/BoulderAcmeProvider.kt +++ b/ids-acme/src/main/kotlin/de/fhg/aisec/ids/acme/provider/BoulderAcmeProvider.kt @@ -19,12 +19,12 @@ */ package de.fhg.aisec.ids.acme.provider +import org.shredzone.acme4j.provider.AbstractAcmeProvider +import org.shredzone.acme4j.provider.AcmeProvider import java.net.MalformedURLException import java.net.URI import java.net.URL import java.util.regex.Pattern -import org.shredzone.acme4j.provider.AbstractAcmeProvider -import org.shredzone.acme4j.provider.AcmeProvider /** * An [AcmeProvider] for *Boulder*. diff --git a/ids-api/build.gradle.kts b/ids-api/build.gradle.kts index c9150b579..dd2c645b8 100644 --- a/ids-api/build.gradle.kts +++ b/ids-api/build.gradle.kts @@ -26,7 +26,7 @@ tasks.clean { configure { module { // mark as generated sources for IDEA - generatedSourceDirs.add(File("${protobufGeneratedDir}/main/java")) + generatedSourceDirs.add(File("$protobufGeneratedDir/main/java")) } } diff --git a/ids-api/src/main/kotlin/de/fhg/aisec/ids/api/idscp2/Idscp2UsageControlInterface.kt b/ids-api/src/main/kotlin/de/fhg/aisec/ids/api/idscp2/Idscp2UsageControlInterface.kt index 37d7e6e62..c2387152a 100644 --- a/ids-api/src/main/kotlin/de/fhg/aisec/ids/api/idscp2/Idscp2UsageControlInterface.kt +++ b/ids-api/src/main/kotlin/de/fhg/aisec/ids/api/idscp2/Idscp2UsageControlInterface.kt @@ -20,8 +20,8 @@ package de.fhg.aisec.ids.api.idscp2 import de.fraunhofer.iais.eis.ContractAgreement -import java.net.URI import org.apache.camel.Exchange +import java.net.URI /** * This interface has to be parameterized with the type of the connection objects handled, e.g. diff --git a/ids-connector/build.gradle.kts b/ids-connector/build.gradle.kts index 68aca8b97..f24b84f54 100644 --- a/ids-connector/build.gradle.kts +++ b/ids-connector/build.gradle.kts @@ -6,11 +6,31 @@ val libraryVersions = rootProject.extra.get("libraryVersions") as Map { + module { + // mark as generated sources for IDEA + generatedSourceDirs.add(File("$buildDir/generated/source/buildConfig/main/main")) + } +} + tasks.getByName("bootJar") { launchScript() layered() diff --git a/ids-connector/src/main/kotlin/de/fhg/aisec/ids/ConnectorConfiguration.kt b/ids-connector/src/main/kotlin/de/fhg/aisec/ids/ConnectorConfiguration.kt index 5782ca25d..2bfef6164 100644 --- a/ids-connector/src/main/kotlin/de/fhg/aisec/ids/ConnectorConfiguration.kt +++ b/ids-connector/src/main/kotlin/de/fhg/aisec/ids/ConnectorConfiguration.kt @@ -21,23 +21,38 @@ package de.fhg.aisec.ids import de.fhg.aisec.ids.api.cm.ContainerManager import de.fhg.aisec.ids.api.infomodel.InfoModel +import de.fhg.aisec.ids.api.settings.Settings +import de.fhg.aisec.ids.camel.idscp2.Utils import de.fhg.aisec.ids.rm.RouteManagerService -import java.util.* import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.CommandLineRunner import org.springframework.context.ApplicationContext import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration +import java.util.Arrays @Configuration class ConnectorConfiguration { @Autowired(required = false) private var cml: ContainerManager? = null + @Autowired private lateinit var settings: Settings + @Autowired private lateinit var im: InfoModel @Autowired private lateinit var rm: RouteManagerService + @Bean + fun configureIdscp2(): CommandLineRunner { + return CommandLineRunner { + Utils.connectorUrlProducer = { settings.connectorProfile.connectorUrl } + Utils.maintainerUrlProducer = { settings.connectorProfile.maintainerUrl } + Utils.dapsUrlProducer = { settings.connectorConfig.dapsUrl } + TrustedConnector.LOG.info("Information model {} loaded", BuildConfig.INFOMODEL_VERSION) + Utils.infomodelVersion = BuildConfig.INFOMODEL_VERSION + } + } + @Bean fun listBeans(ctx: ApplicationContext): CommandLineRunner? { return CommandLineRunner { diff --git a/ids-connector/src/main/kotlin/de/fhg/aisec/ids/TrustedConnector.kt b/ids-connector/src/main/kotlin/de/fhg/aisec/ids/TrustedConnector.kt index 3e6e22821..501c5966f 100644 --- a/ids-connector/src/main/kotlin/de/fhg/aisec/ids/TrustedConnector.kt +++ b/ids-connector/src/main/kotlin/de/fhg/aisec/ids/TrustedConnector.kt @@ -19,7 +19,6 @@ */ package de.fhg.aisec.ids -import java.util.* import org.slf4j.LoggerFactory import org.springframework.boot.autoconfigure.SpringBootApplication import org.springframework.boot.runApplication diff --git a/ids-connector/src/main/resources/etc/karaf_maven_settings.xml b/ids-connector/src/main/resources/etc/karaf_maven_settings.xml deleted file mode 100644 index 7f8349b4d..000000000 --- a/ids-connector/src/main/resources/etc/karaf_maven_settings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - \ No newline at end of file diff --git a/ids-connector/src/main/resources/etc/settings.mapdb b/ids-connector/src/main/resources/etc/settings.mapdb index dae8b18ff5a441150281270e9f64152dfcab9745..8f917658d00d1fe438e29c26f12cec9cde499d40 100644 GIT binary patch delta 302 zcmXwyyAArXZLQlxTq?K9BZvpki&m#lcn2~kE0HKcaEI157WQqc;K{l|L=*r2P{A$5|9O=K1n mq)S4IkRqfADME^nBBTf@LW+*GDOG&T* diff --git a/ids-container-manager/build.gradle.kts b/ids-container-manager/build.gradle.kts index 4d0890b69..b4de670e0 100644 --- a/ids-container-manager/build.gradle.kts +++ b/ids-container-manager/build.gradle.kts @@ -26,7 +26,7 @@ tasks.clean { configure { module { // mark as generated sources for IDEA - generatedSourceDirs.add(File("${protobufGeneratedDir}/main/java")) + generatedSourceDirs.add(File("$protobufGeneratedDir/main/java")) } } @@ -42,7 +42,7 @@ dependencies { exclude("com.github.jnr", "jnr-unixsocket") } - //implementation(project(":jnr-unixsocket-wrapper")) + // implementation(project(":jnr-unixsocket-wrapper")) implementation("com.github.jnr", "jnr-unixsocket", libraryVersions["jnrunix"]) implementation("com.github.jnr", "jnr-ffi", libraryVersions["jnrffi"]) diff --git a/ids-container-manager/src/main/java/de/fhg/aisec/ids/cm/impl/StreamGobbler.java b/ids-container-manager/src/main/java/de/fhg/aisec/ids/cm/impl/StreamGobbler.java index 4e975a334..a57c195a4 100644 --- a/ids-container-manager/src/main/java/de/fhg/aisec/ids/cm/impl/StreamGobbler.java +++ b/ids-container-manager/src/main/java/de/fhg/aisec/ids/cm/impl/StreamGobbler.java @@ -19,11 +19,12 @@ */ package de.fhg.aisec.ids.cm.impl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; public class StreamGobbler extends Thread { private static final Logger LOG = LoggerFactory.getLogger(StreamGobbler.class); diff --git a/ids-container-manager/src/main/java/de/fhg/aisec/ids/cm/impl/docker/DockerCM.kt b/ids-container-manager/src/main/java/de/fhg/aisec/ids/cm/impl/docker/DockerCM.kt index 5cf1f0412..4d803e0c7 100644 --- a/ids-container-manager/src/main/java/de/fhg/aisec/ids/cm/impl/docker/DockerCM.kt +++ b/ids-container-manager/src/main/java/de/fhg/aisec/ids/cm/impl/docker/DockerCM.kt @@ -23,18 +23,33 @@ import com.amihaiemil.docker.Container import com.amihaiemil.docker.Docker import com.amihaiemil.docker.Images import com.amihaiemil.docker.LocalDocker -import de.fhg.aisec.ids.api.cm.* +import de.fhg.aisec.ids.api.cm.ApplicationContainer +import de.fhg.aisec.ids.api.cm.ContainerManager +import de.fhg.aisec.ids.api.cm.ContainerStatus +import de.fhg.aisec.ids.api.cm.Decision +import de.fhg.aisec.ids.api.cm.Direction +import de.fhg.aisec.ids.api.cm.NoContainerExistsException +import de.fhg.aisec.ids.api.cm.Protocol +import org.slf4j.LoggerFactory import java.io.File import java.io.IOException import java.net.InetAddress -import java.time.* +import java.time.Instant +import java.time.OffsetDateTime +import java.time.Period +import java.time.ZoneId +import java.time.ZonedDateTime import java.time.temporal.ChronoUnit import java.time.temporal.TemporalUnit -import java.util.* +import java.util.LinkedList +import java.util.Optional import java.util.stream.Collectors -import javax.json.* +import javax.json.Json +import javax.json.JsonArray +import javax.json.JsonObject +import javax.json.JsonString +import javax.json.JsonValue import kotlin.math.abs -import org.slf4j.LoggerFactory /** * ContainerManager implementation for Docker containers. @@ -87,7 +102,7 @@ class DockerCM : ContainerManager { * Human readable memory sizes Credits: aioobe, https://stackoverflow.com/questions * /3758606/how-to-convert-byte-size-into-human-readable-format-in-java */ - private fun humanReadableByteCount(bytes: Long): String? { + private fun humanReadableByteCount(bytes: Long): String { val b = if (bytes == Long.MIN_VALUE) Long.MAX_VALUE else abs(bytes) return when { b < 1024L -> { @@ -175,7 +190,7 @@ class DockerCM : ContainerManager { app.imageId = imageInfo?.getString("Id") app.imageDigests = imageInfo?.getJsonArray("RepoDigests")?.map { (it as JsonString).string } - ?: emptyList() + ?: emptyList() app.ipAddresses = networks .values @@ -195,7 +210,7 @@ class DockerCM : ContainerManager { .toList() app.size = "${humanReadableByteCount((c["SizeRw"] ?: 0).toString().toLong())} RW (data), " + - "${humanReadableByteCount((c["SizeRootFs"] ?: 0).toString().toLong())} RO (layers)" + "${humanReadableByteCount((c["SizeRootFs"] ?: 0).toString().toLong())} RO (layers)" app.created = info.getString("Created") app.status = ContainerStatus.valueOf(state.getString("Status").toUpperCase()) app.ports = @@ -331,9 +346,11 @@ class DockerCM : ContainerManager { val exposedPorts = Json.createObjectBuilder() val portBindings = Json.createObjectBuilder() val portRegex = - ("(?:((?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\\.){3}" + + ( + "(?:((?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\\.){3}" + "(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])):)?" + - "([0-9]+):([0-9]+)(?:/(tcp|udp))?") + "([0-9]+):([0-9]+)(?:/(tcp|udp))?" + ) .toRegex() for (port in app.ports) { val match = portRegex.matchEntire(port) diff --git a/ids-container-manager/src/main/java/de/fhg/aisec/ids/cm/impl/dummy/DummyCM.java b/ids-container-manager/src/main/java/de/fhg/aisec/ids/cm/impl/dummy/DummyCM.java index a7b182783..8f800376d 100644 --- a/ids-container-manager/src/main/java/de/fhg/aisec/ids/cm/impl/dummy/DummyCM.java +++ b/ids-container-manager/src/main/java/de/fhg/aisec/ids/cm/impl/dummy/DummyCM.java @@ -19,16 +19,9 @@ */ package de.fhg.aisec.ids.cm.impl.dummy; -import de.fhg.aisec.ids.api.cm.ApplicationContainer; -import de.fhg.aisec.ids.api.cm.ContainerManager; -import de.fhg.aisec.ids.api.cm.Decision; -import de.fhg.aisec.ids.api.cm.Direction; -import de.fhg.aisec.ids.api.cm.Protocol; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; +import de.fhg.aisec.ids.api.cm.*; + +import java.util.*; /** * Dummy implementation of a null container manager which is used if no real CMLd is available. diff --git a/ids-container-manager/src/main/java/de/fhg/aisec/ids/comm/unixsocket/TrustmeUnixSocketThread.java b/ids-container-manager/src/main/java/de/fhg/aisec/ids/comm/unixsocket/TrustmeUnixSocketThread.java index b9c51a5b0..125b35570 100644 --- a/ids-container-manager/src/main/java/de/fhg/aisec/ids/comm/unixsocket/TrustmeUnixSocketThread.java +++ b/ids-container-manager/src/main/java/de/fhg/aisec/ids/comm/unixsocket/TrustmeUnixSocketThread.java @@ -19,6 +19,12 @@ */ package de.fhg.aisec.ids.comm.unixsocket; +import jnr.enxio.channels.NativeSelectorProvider; +import jnr.unixsocket.UnixSocketAddress; +import jnr.unixsocket.UnixSocketChannel; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.io.File; import java.io.IOException; import java.math.BigInteger; @@ -27,22 +33,15 @@ import java.nio.channels.Selector; import java.util.*; import java.util.concurrent.TimeUnit; -import jnr.enxio.channels.NativeSelectorProvider; -import jnr.unixsocket.UnixSocketAddress; -import jnr.unixsocket.UnixSocketChannel; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; public class TrustmeUnixSocketThread implements Runnable { private static final Logger LOG = LoggerFactory.getLogger(TrustmeUnixSocketThread.class); - private UnixSocketAddress address; - private UnixSocketChannel channel; private String socket; // The selector we'll be monitoring - private Selector selector; + private final Selector selector; - private ByteBuffer lengthBuffer = ByteBuffer.allocate(4); + private final ByteBuffer lengthBuffer = ByteBuffer.allocate(4); // A list of PendingChange instances private final List pendingChanges = new LinkedList<>(); @@ -51,9 +50,8 @@ public class TrustmeUnixSocketThread implements Runnable { private final Map> pendingData = new HashMap<>(); // Maps a UnixSocketChannel to a UnixSocketResponseHandler - private Map rspHandlers = - Collections.synchronizedMap( - new HashMap()); + private final Map rspHandlers = + Collections.synchronizedMap(new HashMap<>()); // constructor setting another socket address public TrustmeUnixSocketThread(String socket) throws IOException { @@ -88,11 +86,7 @@ public void send(byte[] data, TrustmeUnixSocketResponseHandler handler, boolean this.rspHandlers.put(socket, handler); // And queue the data we want written synchronized (this.pendingData) { - List queue = (List) this.pendingData.get(socket); - if (queue == null) { - queue = new ArrayList(); - this.pendingData.put(socket, queue); - } + List queue = this.pendingData.computeIfAbsent(socket, k -> new ArrayList<>()); queue.add(ByteBuffer.wrap(result)); } @@ -117,7 +111,7 @@ public void run() { change.channel.register(this.selector, change.ops); break; default: - LOG.warn("Unknown ChangeRequest type", change.type); + LOG.warn("Unknown ChangeRequest type {}", change.type); } } this.pendingChanges.clear(); @@ -129,7 +123,7 @@ public void run() { // Iterate over the set of keys for which events are available Iterator selectedKeys = this.selector.selectedKeys().iterator(); while (selectedKeys.hasNext()) { - SelectionKey key = (SelectionKey) selectedKeys.next(); + SelectionKey key = selectedKeys.next(); selectedKeys.remove(); if (!key.isValid()) { continue; @@ -231,8 +225,7 @@ private void handleResponse(UnixSocketChannel socketChannel, byte[] data) throws System.arraycopy(data, 0, rspData, 0, data.length); // Look up the handler for this channel - TrustmeUnixSocketResponseHandler handler = - (TrustmeUnixSocketResponseHandler) this.rspHandlers.get(socketChannel); + TrustmeUnixSocketResponseHandler handler = this.rspHandlers.get(socketChannel); // And pass the response to it if (handler.handleResponse(rspData)) { @@ -247,7 +240,7 @@ private void write(SelectionKey key) throws IOException { final UnixSocketChannel channel = this.getChannel(key); synchronized (this.pendingData) { - List queue = (List) this.pendingData.get(channel); + List queue = this.pendingData.get(channel); // Write until there's not more data while (!queue.isEmpty()) { @@ -267,7 +260,7 @@ private void write(SelectionKey key) throws IOException { } } - private void finishConnection(SelectionKey key) throws IOException { + private void finishConnection(SelectionKey key) { final UnixSocketChannel channel = this.getChannel(key); // Finish the connection. If the connection operation failed this will raise an @@ -304,16 +297,16 @@ private UnixSocketChannel initiateConnection() throws IOException, InterruptedEx socketFile.getAbsolutePath(), retries)); } } - this.address = new UnixSocketAddress(socketFile.getAbsoluteFile()); - this.channel = UnixSocketChannel.open(this.address); - this.channel.configureBlocking(false); + UnixSocketAddress address = new UnixSocketAddress(socketFile.getAbsoluteFile()); + UnixSocketChannel channel = UnixSocketChannel.open(address); + channel.configureBlocking(false); // synchronize pending changes synchronized (this.pendingChanges) { this.pendingChanges.add( new ChangeRequest( - channel, ChangeRequest.REGISTER, SelectionKey.OP_CONNECT | SelectionKey.OP_WRITE)); + channel, ChangeRequest.REGISTER, SelectionKey.OP_CONNECT | SelectionKey.OP_WRITE)); } - return this.channel; + return channel; } // initialize the selector diff --git a/ids-container-manager/src/test/java/de/fhg/aisec/ids/cm/impl/trustx/TrustXMock.java b/ids-container-manager/src/test/java/de/fhg/aisec/ids/cm/impl/trustx/TrustXMock.java index 45d4f1e5f..2aca71af1 100644 --- a/ids-container-manager/src/test/java/de/fhg/aisec/ids/cm/impl/trustx/TrustXMock.java +++ b/ids-container-manager/src/test/java/de/fhg/aisec/ids/cm/impl/trustx/TrustXMock.java @@ -20,12 +20,6 @@ package de.fhg.aisec.ids.cm.impl.trustx; import de.fhg.aisec.ids.comm.unixsocket.ChangeRequest; -import java.io.File; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.channels.SelectionKey; -import java.nio.channels.Selector; -import java.util.*; import jnr.enxio.channels.NativeSelectorProvider; import jnr.unixsocket.UnixServerSocketChannel; import jnr.unixsocket.UnixSocketAddress; @@ -33,25 +27,31 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.File; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.channels.SelectionKey; +import java.nio.channels.Selector; +import java.util.*; + public class TrustXMock implements Runnable { private static final Logger LOG = LoggerFactory.getLogger(TrustXMock.class); - private UnixSocketAddress address; private UnixServerSocketChannel channel; private String socket; // The selector we'll be monitoring - private Selector selector; + private final Selector selector; // The buffer into which we'll read data when it's available - private ByteBuffer readBuffer = ByteBuffer.allocate(1024 * 1024); + private final ByteBuffer readBuffer = ByteBuffer.allocate(1024 * 1024); // A list of PendingChange instances - private List pendingChanges = new LinkedList<>(); + private final List pendingChanges = new LinkedList<>(); // Maps a UnixSocketChannel to a list of ByteBuffer instances - private Map> pendingData = new HashMap<>(); + private final Map> pendingData = new HashMap<>(); - private TrustXMockHandler handler; + private final TrustXMockHandler handler; // constructor setting another socket address public TrustXMock(String socket, TrustXMockHandler handler) throws IOException { @@ -67,11 +67,7 @@ public void send(UnixSocketChannel socket, byte[] data) { new ChangeRequest(socket, ChangeRequest.CHANGEOPS, SelectionKey.OP_WRITE)); // And queue the data we want written synchronized (this.pendingData) { - List queue = (List) this.pendingData.get(socket); - if (queue == null) { - queue = new ArrayList(); - this.pendingData.put(socket, queue); - } + List queue = this.pendingData.computeIfAbsent(socket, k -> new ArrayList<>()); queue.add(ByteBuffer.wrap(data)); } // Finally, wake up our selecting thread so it can make the required changes @@ -86,14 +82,10 @@ public void run() { try { // Process any pending changes synchronized (this.pendingChanges) { - Iterator changes = this.pendingChanges.iterator(); - while (changes.hasNext()) { - ChangeRequest change = (ChangeRequest) changes.next(); - switch (change.type) { - case ChangeRequest.CHANGEOPS: - SelectionKey key = change.channel.keyFor(this.selector); - key.interestOps(change.ops); - break; + for (ChangeRequest change : this.pendingChanges) { + if (change.type == ChangeRequest.CHANGEOPS) { + SelectionKey key = change.channel.keyFor(this.selector); + key.interestOps(change.ops); } } this.pendingChanges.clear(); @@ -105,7 +97,7 @@ public void run() { // Iterate over the set of keys for which events are available Iterator selectedKeys = this.selector.selectedKeys().iterator(); while (selectedKeys.hasNext()) { - SelectionKey key = (SelectionKey) selectedKeys.next(); + SelectionKey key = selectedKeys.next(); selectedKeys.remove(); if (!key.isValid()) { continue; @@ -125,6 +117,7 @@ public void run() { } } + @SuppressWarnings("unused") private void accept(SelectionKey key) throws IOException { // Accept the connection and make it non-blocking UnixSocketChannel client = channel.accept(); @@ -167,7 +160,7 @@ private void write(SelectionKey key) throws IOException { final UnixSocketChannel channel = this.getChannel(key); synchronized (this.pendingData) { - List queue = (List) this.pendingData.get(channel); + List queue = this.pendingData.get(channel); // Write until there's not more data while (!queue.isEmpty()) { @@ -192,10 +185,11 @@ private Selector initSelector() throws IOException { Selector socketSelector = NativeSelectorProvider.getInstance().openSelector(); File socketFile = new File(getSocket()); + //noinspection ResultOfMethodCallIgnored socketFile.delete(); socketFile.deleteOnExit(); - this.address = new UnixSocketAddress(socketFile.getAbsoluteFile()); + UnixSocketAddress address = new UnixSocketAddress(socketFile.getAbsoluteFile()); this.channel = UnixServerSocketChannel.open(); this.channel.configureBlocking(false); this.channel.socket().bind(address); diff --git a/ids-container-manager/src/test/java/de/fhg/aisec/ids/cm/impl/trustx/TrustXMockHandler.java b/ids-container-manager/src/test/java/de/fhg/aisec/ids/cm/impl/trustx/TrustXMockHandler.java index 9d79364bd..8dec14317 100644 --- a/ids-container-manager/src/test/java/de/fhg/aisec/ids/cm/impl/trustx/TrustXMockHandler.java +++ b/ids-container-manager/src/test/java/de/fhg/aisec/ids/cm/impl/trustx/TrustXMockHandler.java @@ -19,30 +19,31 @@ */ package de.fhg.aisec.ids.cm.impl.trustx; -import java.util.LinkedList; -import java.util.List; import jnr.unixsocket.UnixSocketChannel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.LinkedList; +import java.util.List; + public class TrustXMockHandler implements Runnable { - private Logger LOG = LoggerFactory.getLogger(TrustXMockHandler.class); - private List queue = new LinkedList<>(); + private final List queue = new LinkedList<>(); @Override public void run() { ServerDataEvent dataEvent; + //noinspection InfiniteLoopStatement while (true) { // Wait for data to become available synchronized (queue) { while (queue.isEmpty()) { try { queue.wait(); - } catch (InterruptedException e) { + } catch (InterruptedException ignored) { } } - dataEvent = (ServerDataEvent) queue.remove(0); + dataEvent = queue.remove(0); } // Print diff --git a/ids-container-manager/src/test/kotlin/de/fhg/aisec/ids/cm/impl/docker/DockerCmIT.kt b/ids-container-manager/src/test/kotlin/de/fhg/aisec/ids/cm/impl/docker/DockerCmIT.kt index aecaa6f5d..4999d21cd 100644 --- a/ids-container-manager/src/test/kotlin/de/fhg/aisec/ids/cm/impl/docker/DockerCmIT.kt +++ b/ids-container-manager/src/test/kotlin/de/fhg/aisec/ids/cm/impl/docker/DockerCmIT.kt @@ -22,7 +22,6 @@ package de.fhg.aisec.ids.cm.impl.docker import de.fhg.aisec.ids.api.cm.ApplicationContainer import de.fhg.aisec.ids.api.cm.ContainerStatus import de.fhg.aisec.ids.cm.impl.docker.DockerCM.Companion.isSupported -import java.util.* import org.junit.After import org.junit.Assert import org.junit.Assume diff --git a/ids-dataflow-control/build.gradle.kts b/ids-dataflow-control/build.gradle.kts index 57a9d01e6..a2d1d66df 100644 --- a/ids-dataflow-control/build.gradle.kts +++ b/ids-dataflow-control/build.gradle.kts @@ -2,7 +2,7 @@ description = "Camel IDS Component" dependencies { @Suppress("UNCHECKED_CAST") val libraryVersions = - rootProject.extra.get("libraryVersions") as Map + rootProject.extra.get("libraryVersions") as Map providedByBundle(project(":ids-api")) { isTransitive = false } diff --git a/ids-dataflow-control/src/main/kotlin/de/fhg/aisec/ids/dataflowcontrol/PolicyDecisionPoint.kt b/ids-dataflow-control/src/main/kotlin/de/fhg/aisec/ids/dataflowcontrol/PolicyDecisionPoint.kt index 6e46b6d8f..88c083455 100644 --- a/ids-dataflow-control/src/main/kotlin/de/fhg/aisec/ids/dataflowcontrol/PolicyDecisionPoint.kt +++ b/ids-dataflow-control/src/main/kotlin/de/fhg/aisec/ids/dataflowcontrol/PolicyDecisionPoint.kt @@ -26,22 +26,32 @@ import alice.tuprolog.exceptions.NoMoreSolutionException import alice.tuprolog.exceptions.NoSolutionException import alice.tuprolog.exceptions.PrologException import com.google.common.cache.CacheBuilder -import de.fhg.aisec.ids.api.policy.* +import de.fhg.aisec.ids.api.policy.DecisionRequest +import de.fhg.aisec.ids.api.policy.Obligation +import de.fhg.aisec.ids.api.policy.PAP +import de.fhg.aisec.ids.api.policy.PDP +import de.fhg.aisec.ids.api.policy.PolicyDecision import de.fhg.aisec.ids.api.policy.PolicyDecision.Decision +import de.fhg.aisec.ids.api.policy.ServiceNode +import de.fhg.aisec.ids.api.policy.TransformationDecision import de.fhg.aisec.ids.api.router.RouteManager import de.fhg.aisec.ids.api.router.RouteVerificationProof import de.fhg.aisec.ids.dataflowcontrol.lucon.LuconEngine import de.fhg.aisec.ids.dataflowcontrol.lucon.TuPrologHelper.escape import de.fhg.aisec.ids.dataflowcontrol.lucon.TuPrologHelper.listStream +import org.osgi.service.component.ComponentContext +import org.osgi.service.component.annotations.Activate +import org.osgi.service.component.annotations.Component +import org.osgi.service.component.annotations.Reference +import org.osgi.service.component.annotations.ReferenceCardinality +import org.osgi.service.component.annotations.ReferencePolicy +import org.slf4j.LoggerFactory +import org.springframework.beans.factory.annotation.Autowired import java.io.File -import java.util.* +import java.util.LinkedList import java.util.concurrent.ExecutionException import java.util.concurrent.TimeUnit import javax.annotation.PostConstruct -import org.osgi.service.component.ComponentContext -import org.osgi.service.component.annotations.* -import org.slf4j.LoggerFactory -import org.springframework.beans.factory.annotation.Autowired /** * This is a singleton, i.e. there will only be one instance of PolicyDecisionPoint within the whole diff --git a/ids-dataflow-control/src/main/kotlin/de/fhg/aisec/ids/dataflowcontrol/lucon/CounterExampleImpl.kt b/ids-dataflow-control/src/main/kotlin/de/fhg/aisec/ids/dataflowcontrol/lucon/CounterExampleImpl.kt index 9e9ad6edc..7cc5689f4 100644 --- a/ids-dataflow-control/src/main/kotlin/de/fhg/aisec/ids/dataflowcontrol/lucon/CounterExampleImpl.kt +++ b/ids-dataflow-control/src/main/kotlin/de/fhg/aisec/ids/dataflowcontrol/lucon/CounterExampleImpl.kt @@ -22,7 +22,7 @@ package de.fhg.aisec.ids.dataflowcontrol.lucon import alice.tuprolog.Struct import alice.tuprolog.Term import de.fhg.aisec.ids.api.router.CounterExample -import java.util.* +import java.util.LinkedList class CounterExampleImpl(term: Term) : CounterExample() { diff --git a/ids-dataflow-control/src/main/kotlin/de/fhg/aisec/ids/dataflowcontrol/lucon/LuconEngine.kt b/ids-dataflow-control/src/main/kotlin/de/fhg/aisec/ids/dataflowcontrol/lucon/LuconEngine.kt index d46cbdaf6..b0bc20abf 100644 --- a/ids-dataflow-control/src/main/kotlin/de/fhg/aisec/ids/dataflowcontrol/lucon/LuconEngine.kt +++ b/ids-dataflow-control/src/main/kotlin/de/fhg/aisec/ids/dataflowcontrol/lucon/LuconEngine.kt @@ -30,11 +30,10 @@ import alice.tuprolog.exceptions.NoSolutionException import alice.tuprolog.interfaces.event.LibraryListener import de.fhg.aisec.ids.api.router.CounterExample import de.fhg.aisec.ids.api.router.RouteVerificationProof +import org.slf4j.LoggerFactory import java.io.OutputStream import java.nio.charset.StandardCharsets -import java.util.* import java.util.regex.Pattern -import org.slf4j.LoggerFactory /** * LUCON (Logic based Usage Control) policy decision engine. diff --git a/ids-dataflow-control/src/main/kotlin/de/fhg/aisec/ids/dataflowcontrol/lucon/LuconLibrary.kt b/ids-dataflow-control/src/main/kotlin/de/fhg/aisec/ids/dataflowcontrol/lucon/LuconLibrary.kt index 98508d494..974d3c11e 100644 --- a/ids-dataflow-control/src/main/kotlin/de/fhg/aisec/ids/dataflowcontrol/lucon/LuconLibrary.kt +++ b/ids-dataflow-control/src/main/kotlin/de/fhg/aisec/ids/dataflowcontrol/lucon/LuconLibrary.kt @@ -25,9 +25,9 @@ import alice.tuprolog.Term import alice.tuprolog.Var import com.google.common.cache.CacheBuilder import com.google.common.cache.CacheLoader +import org.slf4j.LoggerFactory import java.util.concurrent.ExecutionException import java.util.concurrent.TimeUnit -import org.slf4j.LoggerFactory /** * Plugins and default theories for tuProlog engine. diff --git a/ids-dataflow-control/src/main/kotlin/de/fhg/aisec/ids/dataflowcontrol/lucon/TuPrologHelper.kt b/ids-dataflow-control/src/main/kotlin/de/fhg/aisec/ids/dataflowcontrol/lucon/TuPrologHelper.kt index d6d8f5d2c..a39bc8aac 100644 --- a/ids-dataflow-control/src/main/kotlin/de/fhg/aisec/ids/dataflowcontrol/lucon/TuPrologHelper.kt +++ b/ids-dataflow-control/src/main/kotlin/de/fhg/aisec/ids/dataflowcontrol/lucon/TuPrologHelper.kt @@ -21,7 +21,8 @@ package de.fhg.aisec.ids.dataflowcontrol.lucon import alice.tuprolog.Struct import alice.tuprolog.Term -import java.util.* +import java.util.Spliterator +import java.util.Spliterators import java.util.stream.Stream import java.util.stream.StreamSupport diff --git a/ids-dataflow-control/src/test/kotlin/de/fhg/aisec/ids/dataflowcontrol/LuconEngineTest.kt b/ids-dataflow-control/src/test/kotlin/de/fhg/aisec/ids/dataflowcontrol/LuconEngineTest.kt index b3427fb92..24215550d 100644 --- a/ids-dataflow-control/src/test/kotlin/de/fhg/aisec/ids/dataflowcontrol/LuconEngineTest.kt +++ b/ids-dataflow-control/src/test/kotlin/de/fhg/aisec/ids/dataflowcontrol/LuconEngineTest.kt @@ -27,13 +27,13 @@ import de.fhg.aisec.ids.api.policy.PolicyDecision import de.fhg.aisec.ids.api.policy.ServiceNode import de.fhg.aisec.ids.api.router.RouteManager import de.fhg.aisec.ids.dataflowcontrol.lucon.LuconEngine -import java.nio.charset.StandardCharsets -import java.util.* import org.junit.Assert import org.junit.Ignore import org.junit.Test import org.mockito.ArgumentMatchers import org.mockito.Mockito +import java.nio.charset.StandardCharsets +import java.util.Scanner /** * Unit tests for the LUCON policy engine. @@ -250,7 +250,7 @@ class LuconEngineTest { println(proof?.toString()) Assert.assertNotNull(proof) Assert.assertFalse(proof!!.isValid) - // assertTrue(proof.toString().contains("Service testQueueService may receive messages + // assertTrue(proof.toString().contains("Service testQueueService may receive messages // labeled // [private], " + "which is forbidden by rule \"anotherRule\".")); println("##### PROBLEM #####") @@ -529,139 +529,146 @@ class LuconEngineTest { companion object { // Solving Towers of Hanoi in only two lines. Prolog FTW! private const val HANOI_THEORY = - ("move(1,X,Y,_) :- " + - "write('Move top disk from '), write(X), write(' to '), write(Y), nl. \n" + - "move(N,X,Y,Z) :- N>1, M is N-1, move(M,X,Z,Y), move(1,X,Y,_), move(M,Z,Y,X). ") + ( + "move(1,X,Y,_) :- " + + "write('Move top disk from '), write(X), write(' to '), write(Y), nl. \n" + + "move(N,X,Y,Z) :- N>1, M is N-1, move(M,X,Z,Y), move(1,X,Y,_), move(M,Z,Y,X). " + ) // A random but syntactically correct policy. private const val EXAMPLE_POLICY = - ("\n" + - "%%%%%%%% Rules %%%%%%%%%%%%\n" + - "rule(denyAll).\n" + - "rule_priority(denyAll, 0).\n" + - "has_decision(denyAll, drop).\n" + - "receives_label(denyAll).\n" + - "has_target(denyAll, serviceAll).\n" + - "\n" + - "rule(allowRule).\n" + - "rule_priority(allowRule, 1).\n" + - "has_decision(allowRule, allow).\n" + - "receives_label(allowRule).\n" + - "has_target(allowRule, hiveMqttBrokerService).\n" + - "has_target(allowRule, anonymizerService).\n" + - "has_target(allowRule, loggerService).\n" + - "has_target(allowRule, hadoopClustersService).\n" + - "has_target(allowRule, testQueueService).\n" + - "\n" + - "rule(deleteAfterOneMonth).\n" + - "rule_priority(deleteAfterOneMonth, 1).\n" + - "has_decision(deleteAfterOneMonth, allow).\n" + - "receives_label(deleteAfterOneMonth) :- label(private).\n" + - "has_target(deleteAfterOneMonth, service78096644).\n" + - "has_obligation(deleteAfterOneMonth, obl1709554620).\n" + - "% generated service\n" + - "service(service78096644).\n" + - "has_endpoint(service78096644, \"hdfs.*\").\n" + - "% generated obligation\n" + - "requires_prerequisite(obl1709554620, delete_after_days(30)).\n" + - "has_alternativedecision(obl1709554620, drop).\n" + - "\n" + - "rule(anotherRule).\n" + - "rule_priority(anotherRule, 1).\n" + - "has_target(anotherRule, testQueueService).\n" + - "receives_label(anotherRule) :- label(private).\n" + - "has_decision(anotherRule, drop).\n" + - "\n" + - "%%%%%%%%%%%% Services %%%%%%%%%%%%\n" + - "service(serviceAll).\n" + - "has_endpoint(serviceAll,'.*').\n" + - "\n" + - "service(hiveMqttBrokerService).\n" + - "creates_label(hiveMqttBrokerService, labelone).\n" + - "creates_label(hiveMqttBrokerService, private).\n" + - "removes_label(hiveMqttBrokerService, labeltwo).\n" + - "has_endpoint(hiveMqttBrokerService, \"^paho:.*?tcp://broker.hivemq.com:1883.*\").\n" + - "has_property(hiveMqttBrokerService, type, public).\n" + - "\n" + - "service(anonymizerService).\n" + - "has_endpoint(anonymizerService, \".*anonymizer.*\").\n" + - "has_property(anonymizerService, myProp, anonymize('surname', 'name')).\n" + - "\n" + - "service(loggerService).\n" + - "has_endpoint(loggerService, \"^log.*\").\n" + + ( "\n" + - "service(hadoopClustersService).\n" + - "has_endpoint(hadoopClustersService, \"^hdfs://.*\").\n" + - "has_capability(hadoopClustersService, deletion).\n" + - "has_property(hadoopClustersService, anonymizes, anonymize('surname', 'name')).\n" + - "\n" + - "service(testQueueService).\n" + - "has_endpoint(testQueueService, \"^amqp:.*?:test\").") + "%%%%%%%% Rules %%%%%%%%%%%%\n" + + "rule(denyAll).\n" + + "rule_priority(denyAll, 0).\n" + + "has_decision(denyAll, drop).\n" + + "receives_label(denyAll).\n" + + "has_target(denyAll, serviceAll).\n" + + "\n" + + "rule(allowRule).\n" + + "rule_priority(allowRule, 1).\n" + + "has_decision(allowRule, allow).\n" + + "receives_label(allowRule).\n" + + "has_target(allowRule, hiveMqttBrokerService).\n" + + "has_target(allowRule, anonymizerService).\n" + + "has_target(allowRule, loggerService).\n" + + "has_target(allowRule, hadoopClustersService).\n" + + "has_target(allowRule, testQueueService).\n" + + "\n" + + "rule(deleteAfterOneMonth).\n" + + "rule_priority(deleteAfterOneMonth, 1).\n" + + "has_decision(deleteAfterOneMonth, allow).\n" + + "receives_label(deleteAfterOneMonth) :- label(private).\n" + + "has_target(deleteAfterOneMonth, service78096644).\n" + + "has_obligation(deleteAfterOneMonth, obl1709554620).\n" + + "% generated service\n" + + "service(service78096644).\n" + + "has_endpoint(service78096644, \"hdfs.*\").\n" + + "% generated obligation\n" + + "requires_prerequisite(obl1709554620, delete_after_days(30)).\n" + + "has_alternativedecision(obl1709554620, drop).\n" + + "\n" + + "rule(anotherRule).\n" + + "rule_priority(anotherRule, 1).\n" + + "has_target(anotherRule, testQueueService).\n" + + "receives_label(anotherRule) :- label(private).\n" + + "has_decision(anotherRule, drop).\n" + + "\n" + + "%%%%%%%%%%%% Services %%%%%%%%%%%%\n" + + "service(serviceAll).\n" + + "has_endpoint(serviceAll,'.*').\n" + + "\n" + + "service(hiveMqttBrokerService).\n" + + "creates_label(hiveMqttBrokerService, labelone).\n" + + "creates_label(hiveMqttBrokerService, private).\n" + + "removes_label(hiveMqttBrokerService, labeltwo).\n" + + "has_endpoint(hiveMqttBrokerService, \"^paho:.*?tcp://broker.hivemq.com:1883.*\").\n" + + "has_property(hiveMqttBrokerService, type, public).\n" + + "\n" + + "service(anonymizerService).\n" + + "has_endpoint(anonymizerService, \".*anonymizer.*\").\n" + + "has_property(anonymizerService, myProp, anonymize('surname', 'name')).\n" + + "\n" + + "service(loggerService).\n" + + "has_endpoint(loggerService, \"^log.*\").\n" + + "\n" + + "service(hadoopClustersService).\n" + + "has_endpoint(hadoopClustersService, \"^hdfs://.*\").\n" + + "has_capability(hadoopClustersService, deletion).\n" + + "has_property(hadoopClustersService, anonymizes, anonymize('surname', 'name')).\n" + + "\n" + + "service(testQueueService).\n" + + "has_endpoint(testQueueService, \"^amqp:.*?:test\")." + ) // Policy with extended labels, i.e. "purpose(green)" private const val EXTENDED_LABELS_POLICY = - ("" + - "%%%%%%%% Rules %%%%%%%%%%%%\n" + - "rule(denyAll).\n" + - "rule_priority(denyAll, 0).\n" + - "has_decision(denyAll, drop).\n" + - "receives_label(denyAll).\n" + - "has_target(denyAll, serviceAll).\n" + - "\n" + - "rule(demo).\n" + - "rule_priority(demo, 1).\n" + - "has_target(demo, service473016340).\n" + - "service(service473016340).\n" + - "has_endpoint(service473016340,\"(ahc|ahc-ws|cxf|cxfbean|cxfrs)://.*\").\n" + - "receives_label(demo) :- label(purpose(green)).\n" // Note that Prolog does not - // support - // nested predicates. - + - "has_decision(demo, allow).\n" + - "\n" + - "%%%%% Services %%%%%%%%%%%%\n" + - "service(serviceAll).\n" + - "has_endpoint(serviceAll,'.*').\n" + - "creates_label(serviceAll, purpose(green)).\n" + - "\n" + - "service(sanitizedata).\n" + - "has_endpoint(sanitizedata, \"^bean://SanitizerBean.*\").\n" + - "creates_label(sanitizedata, public).\n" + - "removes_label(sanitizedata, private).\n") + ( + "" + + "%%%%%%%% Rules %%%%%%%%%%%%\n" + + "rule(denyAll).\n" + + "rule_priority(denyAll, 0).\n" + + "has_decision(denyAll, drop).\n" + + "receives_label(denyAll).\n" + + "has_target(denyAll, serviceAll).\n" + + "\n" + + "rule(demo).\n" + + "rule_priority(demo, 1).\n" + + "has_target(demo, service473016340).\n" + + "service(service473016340).\n" + + "has_endpoint(service473016340,\"(ahc|ahc-ws|cxf|cxfbean|cxfrs)://.*\").\n" + + "receives_label(demo) :- label(purpose(green)).\n" + // Note that Prolog does not + // support + // nested predicates. + "has_decision(demo, allow).\n" + + "\n" + + "%%%%% Services %%%%%%%%%%%%\n" + + "service(serviceAll).\n" + + "has_endpoint(serviceAll,'.*').\n" + + "creates_label(serviceAll, purpose(green)).\n" + + "\n" + + "service(sanitizedata).\n" + + "has_endpoint(sanitizedata, \"^bean://SanitizerBean.*\").\n" + + "creates_label(sanitizedata, public).\n" + + "removes_label(sanitizedata, private).\n" + ) // Route from LUCON paper with path searching logic private const val VERIFIABLE_ROUTE = - ("%\n" + - "% (C) Julian Schütte, Fraunhofer AISEC, 2017\n" + - "%\n" + - "% Demonstration of model checking a message route against a usage control policy\n" + - "%\n" + - "% Message Route definition\n" + + ( "%\n" + - "% hiveMqttBroker \n" + - "% / \\ \n" + - "% logger anonymizer \n" + - "% \\ / \n" + - "% hadoopClusters \n" + - "% | \n" + - "% testQueue \n" + - "entrynode(hiveMqttBroker).\n" + - "stmt(hiveMqttBroker).\n" + - "has_action(hiveMqttBroker, \"paho:something:tcp://broker.hivemq.com:1883/anywhere\").\n" + - "stmt(logger).\n" + - "has_action(logger, \"log\").\n" + - "stmt(anonymizer).\n" + - "has_action(anonymizer, \"hello_anonymizer_world\").\n" + - "stmt(hadoopClusters).\n" + - "has_action(hadoopClusters, \"hdfs://myCluser\").\n" + - "stmt(testQueue).\n" + - "has_action(testQueue, \"amqp:testQueue:test\").\n" + - "\n" + - "succ(hiveMqttBroker, logger).\n" + - "succ(hiveMqttBroker, anonymizer).\n" + - "succ(logger, hadoopClusters).\n" + - "succ(anonymizer, hadoopClusters).\n" + - "succ(hadoopClusters, testQueue).\n" + - "\n") + "% (C) Julian Schütte, Fraunhofer AISEC, 2017\n" + + "%\n" + + "% Demonstration of model checking a message route against a usage control policy\n" + + "%\n" + + "% Message Route definition\n" + + "%\n" + + "% hiveMqttBroker \n" + + "% / \\ \n" + + "% logger anonymizer \n" + + "% \\ / \n" + + "% hadoopClusters \n" + + "% | \n" + + "% testQueue \n" + + "entrynode(hiveMqttBroker).\n" + + "stmt(hiveMqttBroker).\n" + + "has_action(hiveMqttBroker, \"paho:something:tcp://broker.hivemq.com:1883/anywhere\").\n" + + "stmt(logger).\n" + + "has_action(logger, \"log\").\n" + + "stmt(anonymizer).\n" + + "has_action(anonymizer, \"hello_anonymizer_world\").\n" + + "stmt(hadoopClusters).\n" + + "has_action(hadoopClusters, \"hdfs://myCluser\").\n" + + "stmt(testQueue).\n" + + "has_action(testQueue, \"amqp:testQueue:test\").\n" + + "\n" + + "succ(hiveMqttBroker, logger).\n" + + "succ(hiveMqttBroker, anonymizer).\n" + + "succ(logger, hadoopClusters).\n" + + "succ(anonymizer, hadoopClusters).\n" + + "succ(hadoopClusters, testQueue).\n" + + "\n" + ) } } diff --git a/ids-infomodel-manager/build.gradle.kts b/ids-infomodel-manager/build.gradle.kts index 6010a2791..9e826571c 100644 --- a/ids-infomodel-manager/build.gradle.kts +++ b/ids-infomodel-manager/build.gradle.kts @@ -12,15 +12,17 @@ apply(plugin = "idea") buildConfig { sourceSets.getByName("main") { packageName("de.fhg.aisec.ids.informationmodelmanager") - buildConfigField("String", "INFOMODEL_VERSION", - "\"${libraryVersions["infomodel"] ?: error("Infomodel version not available")}\"") + buildConfigField( + "String", "INFOMODEL_VERSION", + "\"${libraryVersions["infomodel"] ?: error("Infomodel version not available")}\"" + ) } } configure { module { // mark as generated sources for IDEA - generatedSourceDirs.add(File("${buildDir}/generated/source/buildConfig/main/main")) + generatedSourceDirs.add(File("$buildDir/generated/source/buildConfig/main/main")) } } diff --git a/ids-infomodel-manager/src/main/kotlin/de/fhg/aisec/ids/informationmodelmanager/InfoModelService.kt b/ids-infomodel-manager/src/main/kotlin/de/fhg/aisec/ids/informationmodelmanager/InfoModelService.kt index 2e613e531..368988f1d 100644 --- a/ids-infomodel-manager/src/main/kotlin/de/fhg/aisec/ids/informationmodelmanager/InfoModelService.kt +++ b/ids-infomodel-manager/src/main/kotlin/de/fhg/aisec/ids/informationmodelmanager/InfoModelService.kt @@ -23,17 +23,24 @@ import de.fhg.aisec.ids.api.conm.ConnectionManager import de.fhg.aisec.ids.api.infomodel.ConnectorProfile import de.fhg.aisec.ids.api.infomodel.InfoModel import de.fhg.aisec.ids.api.settings.Settings -import de.fraunhofer.iais.eis.* +import de.fraunhofer.iais.eis.Connector +import de.fraunhofer.iais.eis.ConnectorEndpointBuilder +import de.fraunhofer.iais.eis.Resource +import de.fraunhofer.iais.eis.ResourceBuilder +import de.fraunhofer.iais.eis.ResourceCatalog +import de.fraunhofer.iais.eis.ResourceCatalogBuilder +import de.fraunhofer.iais.eis.SecurityProfile +import de.fraunhofer.iais.eis.TrustedConnector +import de.fraunhofer.iais.eis.TrustedConnectorBuilder import de.fraunhofer.iais.eis.ids.jsonld.Serializer import de.fraunhofer.iais.eis.util.ConstraintViolationException import de.fraunhofer.iais.eis.util.TypedLiteral -import java.net.URI -import java.net.URISyntaxException -import java.util.* import org.osgi.service.component.annotations.Reference import org.osgi.service.component.annotations.ReferenceCardinality import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired +import java.net.URI +import java.net.URISyntaxException /** IDS Info Model Manager. */ // @Component(name = "ids-infomodel-manager", immediate = true) @@ -172,7 +179,7 @@ class InfoModelService : InfoModel { get() = settings.connectorJsonLd ?: connector?.let { serializer.serialize(it) } - ?: throw NullPointerException("Connector is not available") + ?: throw NullPointerException("Connector is not available") override fun setConnectorByJsonLd(jsonLd: String?) { settings.let { settings -> diff --git a/ids-route-manager/build.gradle.kts b/ids-route-manager/build.gradle.kts index 3e7aff88f..764cc338b 100644 --- a/ids-route-manager/build.gradle.kts +++ b/ids-route-manager/build.gradle.kts @@ -1,6 +1,6 @@ dependencies { @Suppress("UNCHECKED_CAST") val libraryVersions = - rootProject.extra.get("libraryVersions") as Map + rootProject.extra.get("libraryVersions") as Map providedByBundle(project(":ids-api")) { isTransitive = false } diff --git a/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/CamelInterceptor.kt b/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/CamelInterceptor.kt index ec2488a88..08566a272 100644 --- a/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/CamelInterceptor.kt +++ b/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/CamelInterceptor.kt @@ -26,7 +26,11 @@ import org.apache.camel.CamelContext import org.apache.camel.NamedNode import org.apache.camel.Processor import org.apache.camel.spi.InterceptStrategy -import org.osgi.service.component.annotations.* +import org.osgi.service.component.annotations.Activate +import org.osgi.service.component.annotations.Component +import org.osgi.service.component.annotations.Reference +import org.osgi.service.component.annotations.ReferenceCardinality +import org.osgi.service.component.annotations.ReferencePolicy @Component(immediate = true, name = "ids-camel-interceptor") class CamelInterceptor : InterceptStrategy { diff --git a/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/PolicyEnforcementPoint.kt b/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/PolicyEnforcementPoint.kt index fe89f14da..c8f5d496c 100644 --- a/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/PolicyEnforcementPoint.kt +++ b/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/PolicyEnforcementPoint.kt @@ -27,16 +27,18 @@ import de.fhg.aisec.ids.api.policy.TransformationDecision import de.fraunhofer.iais.eis.BinaryOperator import de.fraunhofer.iais.eis.Constraint import de.fraunhofer.iais.eis.LeftOperand -import java.net.InetAddress -import java.net.URI -import java.util.* -import org.apache.camel.* +import org.apache.camel.AsyncCallback +import org.apache.camel.Exchange +import org.apache.camel.NamedNode +import org.apache.camel.Processor import org.apache.camel.model.EndpointRequiredDefinition import org.apache.camel.model.FromDefinition import org.apache.camel.model.RouteDefinition import org.apache.camel.model.ToDefinition import org.apache.camel.support.processor.DelegateAsyncProcessor import org.slf4j.LoggerFactory +import java.net.InetAddress +import java.net.URI class PolicyEnforcementPoint internal constructor(private val destinationNode: NamedNode, target: Processor) : @@ -95,7 +97,7 @@ internal constructor(private val destinationNode: NamedNode, target: Processor) } // Only take action for nodes of type (= input) and (= output) if ((sourceNode is EndpointRequiredDefinition && isIdscp2Endpoint(sourceNode)) || - destinationNode is ToDefinition + destinationNode is ToDefinition ) { val ucContract = try { @@ -151,9 +153,11 @@ internal constructor(private val destinationNode: NamedNode, target: Processor) // Check whether we deal with an entry node ("from:...") or a response of a // To node ("to...")... if (sourceNode is FromDefinition || - (sourceNode is ToDefinition && + ( + sourceNode is ToDefinition && !ucInterface.isProtected(exchange) && - isIdscp2Endpoint(sourceNode)) + isIdscp2Endpoint(sourceNode) + ) ) { // If we found an entry node, then protect exchange's body ucInterface.protectBody(exchange, ucContract.id) @@ -165,7 +169,7 @@ internal constructor(private val destinationNode: NamedNode, target: Processor) // ... or output ("to:...") node as destination of this transition. // Additionally check whether exchange's body was protected. } else if (destinationNode is ToDefinition && - ucInterface.isProtected(exchange) + ucInterface.isProtected(exchange) ) { // Compare hash value and port of camelRoute's containerUri with local // Docker containers @@ -196,8 +200,8 @@ internal constructor(private val destinationNode: NamedNode, target: Processor) // Check whether all endpoint's ip-addresses belong to allowed // containers if (InetAddress.getAllByName(endpointUri.host).all { - allowedIPs.contains(it) - } + allowedIPs.contains(it) + } ) { ucInterface.unprotectBody(exchange) if (LOG.isDebugEnabled) { @@ -208,7 +212,7 @@ internal constructor(private val destinationNode: NamedNode, target: Processor) } else { LOG.warn( "UC: Some or all IP addresses of the host ${endpointUri.host} " + - "do not belong to the permitted containers (${allowedContainers})" + "do not belong to the permitted containers ($allowedContainers)" ) } } diff --git a/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/RouteManagerService.kt b/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/RouteManagerService.kt index c984ed1cc..d4b3af80d 100644 --- a/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/RouteManagerService.kt +++ b/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/RouteManagerService.kt @@ -19,16 +19,13 @@ */ package de.fhg.aisec.ids.rm -import de.fhg.aisec.ids.api.router.* +import de.fhg.aisec.ids.api.router.RouteComponent +import de.fhg.aisec.ids.api.router.RouteException +import de.fhg.aisec.ids.api.router.RouteManager +import de.fhg.aisec.ids.api.router.RouteMetrics +import de.fhg.aisec.ids.api.router.RouteObject import de.fhg.aisec.ids.rm.util.CamelRouteToDot import de.fhg.aisec.ids.rm.util.PrologPrinter -import java.io.* -import java.nio.charset.StandardCharsets -import java.util.* -import java.util.stream.Collectors -import javax.management.* -import javax.xml.bind.JAXBContext -import javax.xml.bind.JAXBException import org.apache.camel.CamelContext import org.apache.camel.Endpoint import org.apache.camel.ServiceStatus @@ -43,6 +40,23 @@ import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired import org.springframework.context.ApplicationContext import org.springframework.stereotype.Component +import java.io.BufferedWriter +import java.io.ByteArrayInputStream +import java.io.ByteArrayOutputStream +import java.io.IOException +import java.io.OutputStreamWriter +import java.io.StringReader +import java.io.StringWriter +import java.nio.charset.StandardCharsets +import java.util.stream.Collectors +import javax.management.AttributeNotFoundException +import javax.management.InstanceNotFoundException +import javax.management.MBeanException +import javax.management.MalformedObjectNameException +import javax.management.ObjectName +import javax.management.ReflectionException +import javax.xml.bind.JAXBContext +import javax.xml.bind.JAXBException /** * Manages Camel routes. @@ -382,7 +396,7 @@ class RouteManagerService : RouteManager { val serviceStatus = cCtx.routeController.getRouteStatus(routeId) routeStarted = serviceStatus == ServiceStatus.Started || - serviceStatus == ServiceStatus.Starting + serviceStatus == ServiceStatus.Starting break } } diff --git a/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/util/CamelRouteToDot.kt b/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/util/CamelRouteToDot.kt index d70a642e8..a214a1ccf 100644 --- a/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/util/CamelRouteToDot.kt +++ b/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/util/CamelRouteToDot.kt @@ -19,12 +19,18 @@ */ package de.fhg.aisec.ids.rm.util +import org.apache.camel.model.ChoiceDefinition +import org.apache.camel.model.FromDefinition +import org.apache.camel.model.MulticastDefinition +import org.apache.camel.model.PipelineDefinition +import org.apache.camel.model.ProcessorDefinition +import org.apache.camel.model.RouteDefinition +import org.apache.camel.model.ToDefinition +import org.apache.camel.util.ObjectHelper import java.io.IOException import java.io.PrintWriter import java.io.Writer -import java.util.* -import org.apache.camel.model.* -import org.apache.camel.util.ObjectHelper +import java.util.IdentityHashMap /** * Camel route definition to GraphViz converter. @@ -46,8 +52,10 @@ class CamelRouteToDot { @Throws(IOException::class) private fun printRoutes(writer: Writer, group: String?, routes: List) { if (group != null) { - writer.write("""subgraph cluster_${clusterCounter++} { -""") + writer.write( + """subgraph cluster_${clusterCounter++} { +""" + ) writer.write("label = \"$group\";\n") writer.write("color = grey;\n") writer.write("style = \"dashed\";\n") @@ -145,19 +153,25 @@ class CamelRouteToDot { if (!data!!.nodeWritten) { data.nodeWritten = true writer.write("\n") - writer.write(""" + writer.write( + """ ${data.id} - """.trimIndent()) + """.trimIndent() + ) writer.write(" [\n") - writer.write(""" + writer.write( + """ label = "${data.label}" - """.trimIndent()) - writer.write(""" + """.trimIndent() + ) + writer.write( + """ tooltip = "${data.tooltip}" - """.trimIndent()) + """.trimIndent() + ) val image = data.image if (image != null) { writer.write("shapefile = \"$image\"\n") diff --git a/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/util/GraphProcessor.kt b/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/util/GraphProcessor.kt index a46df4e8d..4f120874f 100644 --- a/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/util/GraphProcessor.kt +++ b/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/util/GraphProcessor.kt @@ -22,12 +22,11 @@ package de.fhg.aisec.ids.rm.util import de.fhg.aisec.ids.api.router.graph.Edge import de.fhg.aisec.ids.api.router.graph.GraphData import de.fhg.aisec.ids.api.router.graph.Node -import java.util.* -import java.util.concurrent.atomic.AtomicInteger import org.apache.camel.model.ChoiceDefinition import org.apache.camel.model.OptionalIdentifiedDefinition import org.apache.camel.model.ProcessorDefinition import org.apache.camel.model.RouteDefinition +import java.util.concurrent.atomic.AtomicInteger object GraphProcessor { /** diff --git a/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/util/NodeData.kt b/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/util/NodeData.kt index 508dcb2cb..fc2e9fb69 100644 --- a/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/util/NodeData.kt +++ b/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/util/NodeData.kt @@ -19,9 +19,22 @@ */ package de.fhg.aisec.ids.rm.util -import java.util.* -import org.apache.camel.model.* +import org.apache.camel.model.AggregateDefinition +import org.apache.camel.model.BeanDefinition +import org.apache.camel.model.ChoiceDefinition +import org.apache.camel.model.FilterDefinition +import org.apache.camel.model.FromDefinition +import org.apache.camel.model.OtherwiseDefinition +import org.apache.camel.model.ProcessorDefinition +import org.apache.camel.model.RecipientListDefinition +import org.apache.camel.model.ResequenceDefinition +import org.apache.camel.model.RoutingSlipDefinition +import org.apache.camel.model.SplitDefinition +import org.apache.camel.model.ToDefinition +import org.apache.camel.model.TransformDefinition +import org.apache.camel.model.WhenDefinition import org.apache.camel.util.ObjectHelper +import java.util.Locale /** Represents a node in Graphviz representation of a route. */ class NodeData(var id: String, node: Any?, imagePrefix: String) { @@ -36,11 +49,12 @@ class NodeData(var id: String, node: Any?, imagePrefix: String) { var outputs: List>? = null private fun removeQueryString(text: String?): String? { - val idx = text!!.indexOf('?') - return if (idx <= 0) { - text - } else { - text.substring(0, idx) + return text?.indexOf('?')?.let { idx -> + if (idx <= 0) { + text + } else { + text.substring(0, idx) + } } } @@ -178,9 +192,11 @@ class NodeData(var id: String, node: Any?, imagePrefix: String) { } if (ObjectHelper.isEmpty(url) && ObjectHelper.isNotEmpty(nodeType)) { url = - ("http://camel.apache.org/" + - nodeType!!.toLowerCase(Locale.ENGLISH).replace(' ', '-') + - ".html") + ( + "http://camel.apache.org/" + + nodeType!!.toLowerCase(Locale.ENGLISH).replace(' ', '-') + + ".html" + ) } if (node is ProcessorDefinition<*> && outputs == null) { outputs = node.outputs diff --git a/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/util/PrologNode.kt b/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/util/PrologNode.kt index efbd6c4e8..f1c8d8368 100644 --- a/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/util/PrologNode.kt +++ b/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/util/PrologNode.kt @@ -19,29 +19,41 @@ */ package de.fhg.aisec.ids.rm.util -import java.util.* -import org.apache.camel.model.* +import org.apache.camel.model.AggregateDefinition +import org.apache.camel.model.BeanDefinition +import org.apache.camel.model.ChoiceDefinition +import org.apache.camel.model.FilterDefinition +import org.apache.camel.model.FromDefinition +import org.apache.camel.model.OtherwiseDefinition +import org.apache.camel.model.ProcessorDefinition +import org.apache.camel.model.RecipientListDefinition +import org.apache.camel.model.ResequenceDefinition +import org.apache.camel.model.RoutingSlipDefinition +import org.apache.camel.model.SplitDefinition +import org.apache.camel.model.ToDefinition +import org.apache.camel.model.TransformDefinition +import org.apache.camel.model.WhenDefinition import org.apache.camel.util.ObjectHelper /** Represents a node in the EIP diagram tree */ class PrologNode(node: Any) { - // public String id; + // public String id; private var nodeType: String? = null private var value: String? = null - // public String predicate = "has_url"; + // public String predicate = "has_url"; private var outputs: List>? = null init { - // this.id = id; + // this.id = id; if (node is ProcessorDefinition<*>) { - // this.predicate = "has_operation"; + // this.predicate = "has_operation"; value = node.label } when (node) { is FromDefinition -> { nodeType = "from" - // this.predicate = "has_url"; + // this.predicate = "has_url"; value = node.endpointUri } is ToDefinition -> { @@ -68,7 +80,7 @@ class PrologNode(node: Any) { nodeType = "choice" } is RecipientListDefinition<*> -> { - // this.predicate = "recipient_list"; + // this.predicate = "recipient_list"; value = node.label nodeType = "recipients" } @@ -83,16 +95,16 @@ class PrologNode(node: Any) { nodeType = "aggregator" } is ResequenceDefinition -> { - // this.predicate = "resequence"; + // this.predicate = "resequence"; value = node.label } is BeanDefinition -> { - // this.predicate = "bean"; + // this.predicate = "bean"; value = node.label } is TransformDefinition -> { value = node.label - // this.predicate = "transform"; + // this.predicate = "transform"; } } diff --git a/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/util/PrologPrinter.kt b/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/util/PrologPrinter.kt index 997128c65..84ab9c6ac 100644 --- a/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/util/PrologPrinter.kt +++ b/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/util/PrologPrinter.kt @@ -19,14 +19,13 @@ */ package de.fhg.aisec.ids.rm.util -import java.io.IOException -import java.io.Writer -import java.util.* -import java.util.concurrent.atomic.AtomicInteger import org.apache.camel.model.ChoiceDefinition import org.apache.camel.model.OptionalIdentifiedDefinition import org.apache.camel.model.ProcessorDefinition import org.apache.camel.model.RouteDefinition +import java.io.IOException +import java.io.Writer +import java.util.concurrent.atomic.AtomicInteger class PrologPrinter { /** @@ -62,20 +61,24 @@ class PrologPrinter { preds: List> ): List> { for (p in preds) { - writer.write(""" + writer.write( + """ succ(${p.id}, ${current.id}). - """.trimIndent()) + """.trimIndent() + ) } - writer.write(""" + writer.write( + """ stmt(${current.id}). - """.trimIndent()) + """.trimIndent() + ) writer.write( """ has_action(${current.id}, "${current.label}"). - """.trimIndent() + """.trimIndent() ) // predecessor of next recursion is the current node @@ -120,18 +123,24 @@ class PrologPrinter { i.customId = true i.id = "input" + counter.incrementAndGet() } - writer.write(""" + writer.write( + """ stmt(${i.id}). - """.trimIndent()) - writer.write(""" + """.trimIndent() + ) + writer.write( + """ entrynode(${i.id}). - """.trimIndent()) - writer.write(""" + """.trimIndent() + ) + writer.write( + """ has_action(${i.id}, "${i.label}"). - """.trimIndent()) + """.trimIndent() + ) var prev: OptionalIdentifiedDefinition<*>? = i for (next in route.outputs) { printNode(writer, next, prev?.let { listOf(it) } ?: emptyList()) diff --git a/ids-route-manager/src/test/kotlin/de/fhg/aisec/ids/rm/RouteMetricsTest.kt b/ids-route-manager/src/test/kotlin/de/fhg/aisec/ids/rm/RouteMetricsTest.kt index e894aa54f..c32190db9 100644 --- a/ids-route-manager/src/test/kotlin/de/fhg/aisec/ids/rm/RouteMetricsTest.kt +++ b/ids-route-manager/src/test/kotlin/de/fhg/aisec/ids/rm/RouteMetricsTest.kt @@ -19,11 +19,11 @@ */ package de.fhg.aisec.ids.rm -import java.util.* import org.apache.camel.builder.RouteBuilder import org.apache.camel.model.ModelCamelContext import org.apache.camel.test.junit4.CamelTestSupport import org.junit.Test +import java.util.Arrays class RouteMetricsTest : CamelTestSupport() { @Test diff --git a/ids-settings/build.gradle.kts b/ids-settings/build.gradle.kts index b0d016030..e4b8724f2 100644 --- a/ids-settings/build.gradle.kts +++ b/ids-settings/build.gradle.kts @@ -6,7 +6,7 @@ dependencies { // Required by MapDB below providedByBundle("com.google.guava", "guava", libraryVersions["guava"]) - implementation ("org.mapdb", "mapdb", libraryVersions["mapdb"]) { + implementation("org.mapdb", "mapdb", libraryVersions["mapdb"]) { // Exclude guava dependency, which is provided by bundle exclude("com.google.guava", "guava") exclude("org.jetbrains.kotlin", "*") @@ -15,4 +15,4 @@ dependencies { osgiCore("org.osgi", "osgi.cmpn", libraryVersions["osgiCompendium"]) implementation("org.springframework.boot:spring-boot-starter") -} \ No newline at end of file +} diff --git a/ids-settings/src/main/kotlin/de/fhg/aisec/ids/settings/SettingsComponent.kt b/ids-settings/src/main/kotlin/de/fhg/aisec/ids/settings/SettingsComponent.kt index 0e317bb80..f09961040 100644 --- a/ids-settings/src/main/kotlin/de/fhg/aisec/ids/settings/SettingsComponent.kt +++ b/ids-settings/src/main/kotlin/de/fhg/aisec/ids/settings/SettingsComponent.kt @@ -24,31 +24,30 @@ import de.fhg.aisec.ids.api.infomodel.ConnectorProfile import de.fhg.aisec.ids.api.settings.ConnectionSettings import de.fhg.aisec.ids.api.settings.ConnectorConfig import de.fhg.aisec.ids.api.settings.Settings -import java.nio.file.FileSystems -import java.util.* -import java.util.concurrent.ConcurrentMap -import javax.annotation.PreDestroy -import kotlin.collections.HashMap import org.mapdb.DB import org.mapdb.DBMaker import org.mapdb.Serializer import org.slf4j.LoggerFactory +import java.nio.file.FileSystems +import java.util.Collections +import java.util.concurrent.ConcurrentMap +import javax.annotation.PreDestroy @org.springframework.stereotype.Component class SettingsComponent : Settings { - constructor() { + init { activate() } - fun activate() { - LOG.debug("Open Settings Database...") + private fun activate() { + LOG.debug("Open Settings Database {}...", DB_PATH.toFile().absolutePath) DB_PATH.toFile().parentFile.mkdirs() // Use default reliable (non-mmap) mode and WAL for transaction safety mapDB = DBMaker.fileDB(DB_PATH.toFile()).transactionEnable().make() - var dbVersion = settingsStore.getOrPut(DB_VERSION_KEY, { 1 }) as Int + var dbVersion = settingsStore.getOrPut(DB_VERSION_KEY) { 1 } as Int // Check for unknown DB version if (dbVersion > CURRENT_DB_VERSION) { LOG.error( diff --git a/ids-webconsole/build.gradle.kts b/ids-webconsole/build.gradle.kts index e45cfbf65..6e83a1b35 100644 --- a/ids-webconsole/build.gradle.kts +++ b/ids-webconsole/build.gradle.kts @@ -1,4 +1,8 @@ -import com.benjaminsproule.swagger.gradleplugin.model.* +import com.benjaminsproule.swagger.gradleplugin.model.ApiSourceExtension +import com.benjaminsproule.swagger.gradleplugin.model.InfoExtension +import com.benjaminsproule.swagger.gradleplugin.model.LicenseExtension +import com.benjaminsproule.swagger.gradleplugin.model.ScopeExtension +import com.benjaminsproule.swagger.gradleplugin.model.SecurityDefinitionExtension import com.github.gradle.node.yarn.task.YarnTask @Suppress("UNCHECKED_CAST") @@ -21,44 +25,54 @@ sourceSets { } swagger { - apiSource(closureOf { - springmvc = false - locations = listOf("de.fhg.aisec.ids.webconsole.api") - schemes = listOf("http") - host = "localhost:8181" - basePath = "/" - info(closureOf { - title = "Trusted Connector API" - version = project.version as String - license(closureOf { - url = "http://www.apache.org/licenses/LICENSE-2.0.html" - name = "Apache 2.0" - }) - description ="""This is the administrative REST API of the Trusted Connector. + apiSource( + closureOf { + springmvc = false + locations = listOf("de.fhg.aisec.ids.webconsole.api") + schemes = listOf("http") + host = "localhost:8181" + basePath = "/" + info( + closureOf { + title = "Trusted Connector API" + version = project.version as String + license( + closureOf { + url = "http://www.apache.org/licenses/LICENSE-2.0.html" + name = "Apache 2.0" + } + ) + description = """This is the administrative REST API of the Trusted Connector. The API provides an administrative interface to manage the Trusted Connector at runtime and is used by the default administration dashboard ("web console"). """ - }) - swaggerDirectory = "${project.projectDir}/generated/swagger-ui" - outputFormats = listOf("json","yaml") - securityDefinition(closureOf { - // `name` can be used refer to this security schemes from elsewhere - name = "oauth2" - type = "oauth2" - // The flow used by the OAuth2 security scheme - flow = "password" - tokenUrl = "https://localhost:8181/user/login" - scope(closureOf { - name = "write:api" - description = "Read and write access to the API" - }) - }) + } + ) + swaggerDirectory = "${project.projectDir}/generated/swagger-ui" + outputFormats = listOf("json", "yaml") + securityDefinition( + closureOf { + // `name` can be used refer to this security schemes from elsewhere + name = "oauth2" + type = "oauth2" + // The flow used by the OAuth2 security scheme + flow = "password" + tokenUrl = "https://localhost:8181/user/login" + scope( + closureOf { + name = "write:api" + description = "Read and write access to the API" + } + ) + } + ) /* the plugin could theoretically also generate the html files, however it currently only allows for the generation of html OR swagger.json, not both. Therefore we still need to use spectacle using yarn */ - // templatePath = "${project.projectDir}/src/test/resources/strapdown.html.hbs" - // outputPath = "${project.projectDir}/generated/document.html" - }) + // templatePath = "${project.projectDir}/src/test/resources/strapdown.html.hbs" + // outputPath = "${project.projectDir}/generated/document.html" + } + ) } dependencies { @@ -102,7 +116,7 @@ dependencies { } node { - //download.set(true) + // download.set(true) // currently broken on M1 } diff --git a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/WebConsoleComponent.java b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/WebConsoleComponent.java index b7786e1bc..7a3b0c033 100644 --- a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/WebConsoleComponent.java +++ b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/WebConsoleComponent.java @@ -23,7 +23,6 @@ import de.fhg.aisec.ids.api.cm.ContainerManager; import de.fhg.aisec.ids.api.conm.ConnectionManager; import de.fhg.aisec.ids.api.endpointconfig.EndpointConfigManager; -import de.fhg.aisec.ids.api.infomodel.InfoModel; import de.fhg.aisec.ids.api.policy.PAP; import de.fhg.aisec.ids.api.router.RouteManager; import de.fhg.aisec.ids.api.settings.Settings; diff --git a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/AuthorizationRequired.java b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/AuthorizationRequired.java index ef4ac91b8..fa8583adf 100644 --- a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/AuthorizationRequired.java +++ b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/AuthorizationRequired.java @@ -19,11 +19,11 @@ */ package de.fhg.aisec.ids.webconsole.api; +import javax.ws.rs.NameBinding; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import javax.ws.rs.NameBinding; @NameBinding @Target({ElementType.TYPE, ElementType.METHOD}) diff --git a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/CORSResponseFilter.java b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/CORSResponseFilter.java index c638e7a35..b1424784f 100644 --- a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/CORSResponseFilter.java +++ b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/CORSResponseFilter.java @@ -19,13 +19,14 @@ */ package de.fhg.aisec.ids.webconsole.api; -import java.io.IOException; +import org.osgi.service.component.annotations.Component; + import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerResponseContext; import javax.ws.rs.container.ContainerResponseFilter; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.ext.Provider; -import org.osgi.service.component.annotations.Component; +import java.io.IOException; /** * This filter adds Cross-Origin Resource Sharing (CORS) headers to each response. diff --git a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/ConnectionAPI.java b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/ConnectionAPI.java index fbf654062..edbc34fd0 100644 --- a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/ConnectionAPI.java +++ b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/ConnectionAPI.java @@ -29,12 +29,12 @@ import io.swagger.annotations.Authorization; import org.springframework.stereotype.Component; -import java.util.ArrayList; -import java.util.List; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; +import java.util.ArrayList; +import java.util.List; /** * REST API interface for managing connections from and to the connector. diff --git a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/MetricAPI.java b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/MetricAPI.java index 2c07916e0..41f3be297 100644 --- a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/MetricAPI.java +++ b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/MetricAPI.java @@ -22,14 +22,14 @@ import io.swagger.annotations.*; import org.springframework.stereotype.Component; -import java.lang.management.*; -import java.text.DecimalFormat; -import java.util.HashMap; -import java.util.Map; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; +import java.lang.management.*; +import java.text.DecimalFormat; +import java.util.HashMap; +import java.util.Map; /** * REST API interface for platform metrics. diff --git a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/PolicyApi.java b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/PolicyApi.java index cea42d339..95dd77df6 100644 --- a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/PolicyApi.java +++ b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/PolicyApi.java @@ -22,16 +22,15 @@ import de.fhg.aisec.ids.api.policy.PAP; import de.fhg.aisec.ids.webconsole.WebConsoleComponent; import io.swagger.annotations.*; -import java.util.ArrayList; -import java.util.List; -import javax.ws.rs.*; -import javax.ws.rs.core.MediaType; - -import org.apache.cxf.jaxrs.ext.multipart.Multipart; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; +import javax.ws.rs.*; +import javax.ws.rs.core.MediaType; +import java.util.ArrayList; +import java.util.List; + /** * REST API interface for managing usage control policies in the connector. * diff --git a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/RouteApi.java b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/RouteApi.java index 6d438e7a5..d53407662 100644 --- a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/RouteApi.java +++ b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/RouteApi.java @@ -20,10 +20,8 @@ package de.fhg.aisec.ids.webconsole.api; import de.fhg.aisec.ids.api.Result; -import de.fhg.aisec.ids.api.cm.ContainerManager; import de.fhg.aisec.ids.api.policy.PAP; import de.fhg.aisec.ids.api.router.*; -import de.fhg.aisec.ids.api.settings.Settings; import de.fhg.aisec.ids.webconsole.WebConsoleComponent; import de.fhg.aisec.ids.webconsole.api.data.ValidationInfo; import io.swagger.annotations.Api; @@ -38,7 +36,6 @@ import javax.ws.rs.*; import javax.ws.rs.core.MediaType; -import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; diff --git a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/SettingsApi.java b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/SettingsApi.java index 353e842b0..bf9f995c0 100644 --- a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/SettingsApi.java +++ b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/SettingsApi.java @@ -36,10 +36,6 @@ import javax.ws.rs.core.MediaType; import java.util.stream.Collectors; -import javax.ws.rs.*; -import javax.ws.rs.core.MediaType; -import java.util.stream.Collectors; - /** * REST API interface for Connector settings in the connector. * diff --git a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/data/ValidationInfo.java b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/data/ValidationInfo.java index 03f52e0b2..57377707e 100644 --- a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/data/ValidationInfo.java +++ b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/data/ValidationInfo.java @@ -20,6 +20,7 @@ package de.fhg.aisec.ids.webconsole.api.data; import de.fhg.aisec.ids.api.router.CounterExample; + import java.util.List; public class ValidationInfo { diff --git a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/helper/ProcessExecutor.java b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/helper/ProcessExecutor.java index 1b06fb32a..11a6e2176 100644 --- a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/helper/ProcessExecutor.java +++ b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/helper/ProcessExecutor.java @@ -19,11 +19,12 @@ */ package de.fhg.aisec.ids.webconsole.api.helper; -import java.io.IOException; -import java.io.OutputStream; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.IOException; +import java.io.OutputStream; + public class ProcessExecutor { private static final Logger LOG = LoggerFactory.getLogger(ProcessExecutor.class); diff --git a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/helper/StreamGobbler.java b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/helper/StreamGobbler.java index da2fabfde..51e06bf89 100644 --- a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/helper/StreamGobbler.java +++ b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/helper/StreamGobbler.java @@ -19,11 +19,12 @@ */ package de.fhg.aisec.ids.webconsole.api.helper; -import java.io.*; -import java.nio.charset.StandardCharsets; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.*; +import java.nio.charset.StandardCharsets; + class StreamGobbler extends Thread { private static final Logger LOG = LoggerFactory.getLogger(StreamGobbler.class); InputStream is; diff --git a/karaf-assembly/.gitignore b/karaf-assembly/.gitignore deleted file mode 100644 index c3442a564..000000000 --- a/karaf-assembly/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/target/ -# Generated from pom.template.xml -pom.xml \ No newline at end of file diff --git a/karaf-assembly/.mvn/wrapper/MavenWrapperDownloader.java b/karaf-assembly/.mvn/wrapper/MavenWrapperDownloader.java deleted file mode 100644 index c32394f14..000000000 --- a/karaf-assembly/.mvn/wrapper/MavenWrapperDownloader.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2007-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import java.net.*; -import java.io.*; -import java.nio.channels.*; -import java.util.Properties; - -public class MavenWrapperDownloader { - - private static final String WRAPPER_VERSION = "0.5.5"; - /** - * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. - */ - private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/" - + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar"; - - /** - * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to - * use instead of the default one. - */ - private static final String MAVEN_WRAPPER_PROPERTIES_PATH = - ".mvn/wrapper/maven-wrapper.properties"; - - /** - * Path where the maven-wrapper.jar will be saved to. - */ - private static final String MAVEN_WRAPPER_JAR_PATH = - ".mvn/wrapper/maven-wrapper.jar"; - - /** - * Name of the property which should be used to override the default download url for the wrapper. - */ - private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; - - public static void main(String args[]) { - System.out.println("- Downloader started"); - File baseDirectory = new File(args[0]); - System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); - - // If the maven-wrapper.properties exists, read it and check if it contains a custom - // wrapperUrl parameter. - File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); - String url = DEFAULT_DOWNLOAD_URL; - if(mavenWrapperPropertyFile.exists()) { - FileInputStream mavenWrapperPropertyFileInputStream = null; - try { - mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); - Properties mavenWrapperProperties = new Properties(); - mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); - url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); - } catch (IOException e) { - System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); - } finally { - try { - if(mavenWrapperPropertyFileInputStream != null) { - mavenWrapperPropertyFileInputStream.close(); - } - } catch (IOException e) { - // Ignore ... - } - } - } - System.out.println("- Downloading from: " + url); - - File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); - if(!outputFile.getParentFile().exists()) { - if(!outputFile.getParentFile().mkdirs()) { - System.out.println( - "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'"); - } - } - System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); - try { - downloadFileFromURL(url, outputFile); - System.out.println("Done"); - System.exit(0); - } catch (Throwable e) { - System.out.println("- Error downloading"); - e.printStackTrace(); - System.exit(1); - } - } - - private static void downloadFileFromURL(String urlString, File destination) throws Exception { - if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) { - String username = System.getenv("MVNW_USERNAME"); - char[] password = System.getenv("MVNW_PASSWORD").toCharArray(); - Authenticator.setDefault(new Authenticator() { - @Override - protected PasswordAuthentication getPasswordAuthentication() { - return new PasswordAuthentication(username, password); - } - }); - } - URL website = new URL(urlString); - ReadableByteChannel rbc; - rbc = Channels.newChannel(website.openStream()); - FileOutputStream fos = new FileOutputStream(destination); - fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); - fos.close(); - rbc.close(); - } - -} diff --git a/karaf-assembly/.mvn/wrapper/maven-wrapper.jar b/karaf-assembly/.mvn/wrapper/maven-wrapper.jar deleted file mode 100755 index 0d5e649888a4843c1520054d9672f80c62ebbb48..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 50710 zcmbTd1F&Yzk}llaw%yydZQHhOtG8|2wr$%sdfWEC{mnUpfBrjP%(-twMXZRmGOM!c zd9yOJo|2OU0!ID;4i5g~#}E8J?LU7Ie;%cUmH4T}WkhI!e#l9J{q@Zcz<+)r_dg0E z|5rh2ei?BQVMQexX_2HDe#ihic;RQiO?))5*`S|S7OJR$0!15$@o}&gh{KEX8>-aS zebwz)UwGRGE9?4DhKZ)R2wjvy<%rYe_z!fyA~>e=tmvNPLiuHP53`)W`FLgV1o9b@ z?3)Q4hagTgvBzZDa`v_DRkmwm>bk&&5@m;ZKwovq%oDWOE5u zleR0Z)LP%g z*ydlFD2)HVxVbHjlfI?CgZaOti1hCi{oA;xT^;o8?2H}$CAG}|d$o49)--kwwtsqX zGBi1>nE^FB$)DBl&kl0=BkJj!u8pT3X-SM$t*%!O7Tx#?VUN(J@J7 z%mqmlxhp6bH9rj)^iYq`pf?`O*$x~aBDK%&CjpjW0Dmepb(vLDTzk@0d>tccth>%{ zqcr7aeZu!Zr23hdL)!RGizX}aWJj6ClX4Gb=bet4tBUy?-|r{nUh$7yJ*eiA?Z;B2`eF1LaPBSu_fx@B5isJF5&|yU7hLsa5}05d3gQRmO4{!66oMh zigvqS{W+|Y0wOi($g$qiEf^jL)}>W~AR*|m?Ia0Mm&;BjorRn-!}CxKVO!7^_eSU; za}~KI`cHaF*!+>B5a-KI>36u#or|tTiuzm;hLCR>bMq9@2Z1fr4d$A`%|rCLKl^5z z`Z~yYPy)~i?x3_LE7|;0GLF#mVOpQ8X>1gNNLX!4rWD(!q!EVsGZPum^~IQ?OAy9U z#lqI;WcC{U(KHra8q6HKa`%NZ^;gqs))9Mb3hgxa%QY1dO_YQok3%a5hFXmwyQwt5 zokv+V7DJgXNlo1Jv9u21JB$WF~oaC)aF8zY-VK6{ynvH6F zk|{{&#%crN>5Vm&6byp)q(XYXIF)9Q`;lMGWJIP3e)3zmi0gVmI|;n*$`v-Jtj5!h>;@Y&fY9%VqR zdvyz`W~hk%)WdNHVGkD6tdf`iv8B&HpjCgRcx=@$^CrBuzraY$k`dZ&LmR8t+(FSQ zL7=y~l+GL+%Xzvj66Xb`Ey}35$xDv5O2@5ywUr2_>Jz*srt`dPuFp2>5mTdt>H7NR zvg!zAScv9uGBZa^gCeh77YJ4_0xc@0!jSG}P@Pn!)t0|+UFI7!?W90^55Ha1de+3Y zNz}7<*xPlOFN5;J!=rS=Zwb(PT)j`|B_(F8EmsvkQZ1wGuG&Xu)OZmTR0Y99D$5#tf%OElqb{J^!W*E8vy2$QkhN-E(3>~vNdny^ z&_#^RRL>0Mog`;hZ~2=uUwy|8W@gdO$pq$;8M?Z?{ z(!g)#LR-;l-oCvHxx--!6D~z2_%z~DPIcWwnzgGa&;ouDP~Bx#u>)3HUKjSUTv2kS z*jfLRyc-Yu(ClrUvuAvfnmu_BkvFbTk8>#tYv@*?nq_h~A!A!yM;do9 zC^E#;pW}3;$ApFCRQo(dyU5c>3TcRmq%|Z|8p^lxDmk7JN6llr_&U?Rg|@NljYOR2 zb=vg=oS1GN>(^NCAaiE9rbhk__1Nwu!OuPddM7KQJj)Bezh85DvUl}a?!*ZJEMKfp zbU*8SY`{iQ=%fl0#Af$k6~2*0v^?llf1Emdn5Q5YG+%7`*5uyO_^txn^`x2l^J_As2-4_Tm|5b}0q$5okF$ zHaO03%@~_Z=jpV!WTbL$}e;NgXz=Uw!ogI}+S@aBP**2Wo^yN#ZG z4G$m^yaM9g?M5E1ft8jOLuzc3Psca*;7`;gnI0YzS0%f4{|VGEzKceaptfluwyY#7 z^=q#@gi@?cOm99Qz!EylA4G~7kbF7hlRIzcrb~{_2(x@@z`7d96Bi_**(vyr_~9Of z!n>Gqk|ZWyu!xhi9f53&PM3`3tNF}pHaq}(;KEn#pmm6DZBu8*{kyrTxk<;mx~(;; z1NMrp@Zd0ZqI!oTJo3b|HROE}UNcQash!p5eLjTcz)>kP=Bp@z)5rLGnaF5{~@z;MFCP9s_dDdADddy z{|Zd9ou-;laEHid_b7A^ zBw1J-^uo$K|@udwk;w* za_|mNqh!k}0fkzR#`|v?iVB@HJt^?0Fo^YGim=lqWD&K7$=J2L(HMp@*5YwV1U)1Aj@><#btD=m0Ga1X))fcKJ=s(v}E7fc1fa_$nGP%d9Opjh3) zRid3zuc5^mNmnnsg4G>m;Sfh@hH$ZT$p%QswzSRa2bh;(7lOaWT>Jv@Ki>_Ep?jx7 z&hwEG^YF=vEgvUwjT_VgWlSZeS{CTjedc)A>N0*uAU(9G@5|><%)^NxRcyx@4!m3s z%1?oiq^@>V!+tKZka-ax2e-`Deeb9_AaTF~z;arjq>Im$ zMc`JAOruhFrFTj6I-Al5$^z4tyu_l2Qk04>>;9#)B#fF})h0_OHP)%xv~m#T+6VG< zP6O@;?5g^t6wm{HX+54ZPoe%(;HU^*OPSEojLYRFRE~=mPXE!0pb|Zs=psR=-v`L# zB2`|mvJBoNTvW`LJ}a;cHP~jC@klxY0|ec3Y!w-`mQ6>CzF}GQCHmrB>k3`fk=3Ck z+WwgG3U_aN&(|RY$ss6CYZ(%4!~tuVWSHu?q=6{-Izay&o_Mvxm=!*?C-NQZFC8=n{?qfRf$3o_VSHs%zfSMdMQ5_f3xt6~+{RX=$H8at z9Si~lTmp}|lmm;++^zA%Iv+XJAHcTf1_jRxfEgz$XozU8$D?08YntWwMY-9iyk@u#wR?JxR2bky5j9 z3Sl-dQQU?#rO0xa)Sp<|MJnx@%w#GcXXM7*Vs=VPdSFt5$aJux89D%D?lA0_j&L42 zcyGz!opsIob%M&~(~&UkX0ndOq^MqjxXw8MIN}U@vAKq_fp@*Vp$uVFiNfahq2MzA zU`4uR8m$S~m+h{-pKVzp%Gs(Wz+%>h;R9Sg-MrB38r?e_Tx6PD%>)bi(#$!a@*_#j zCKr_wm;wtEtOCDwzW25?t{~PANe*e(EXogwcq&Ysl-nT2MBB3E96NP8`Ej_iQFT@X zG22M5ibzYHNJ~tR(et8lDFp|we$&U1tZ33H-o#?o$(o&(>aCNWlMw#Y{b}!fw$6_p z{k}778KP{PZ`c87HBXWDJK)sKXU5xF2))N*t_1C^~Q5(q1W#@r0y#QUke zY9@kew61E>;G2Ds$-gvm=pMuXW~T4Tv@ZhzZkH)DZ_mlk!&rL#E+5JaIx|cf&@b{g ziV)ouh%FU9i6D+C!e&>1x91bwV26SChDV1};|%rXHfqfEpP9?svl6*wM_)kY1DlTX zVN?D2ru8SysDeW~0<@G�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 JS$+5G{{hr`vzY(@ diff --git a/karaf-assembly/.mvn/wrapper/maven-wrapper.properties b/karaf-assembly/.mvn/wrapper/maven-wrapper.properties deleted file mode 100755 index fa87ad7dd..000000000 --- a/karaf-assembly/.mvn/wrapper/maven-wrapper.properties +++ /dev/null @@ -1,2 +0,0 @@ -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.1/apache-maven-3.6.1-bin.zip -wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar diff --git a/karaf-assembly/Dockerfile b/karaf-assembly/Dockerfile deleted file mode 100644 index 201248061..000000000 --- a/karaf-assembly/Dockerfile +++ /dev/null @@ -1,32 +0,0 @@ -ARG BASE_IMAGE=adoptopenjdk:11-jdk-hotspot-focal -FROM $BASE_IMAGE - -LABEL AUTHOR="Michael Lux (michael.lux@aisec.fraunhofer.de)" - -# Install socat for UNIX socket debugging and ps command for karaf scripts -RUN apt-get update -qq && apt-get install -qq socat procps - -# Optional: Install oh-my-zsh for a better shell (~ 20 MiB overhead) -RUN apt-get update -qq && apt-get install -qq wget git zsh fonts-powerline \ - && wget https://github.com/robbyrussell/oh-my-zsh/raw/master/tools/install.sh -O - | zsh || true \ - # Set nice theme - && sed -ie 's/^ZSH_THEME=".*"$/ZSH_THEME="agnoster"/' ~/.zshrc \ - # Disable automatic update - && sed -ie 's/^# DISABLE_AUTO_UPDATE$/DISABLE_AUTO_UPDATE/' ~/.zshrc \ - # Remove git, Cleanup - && apt-get remove --purge -qq git && apt-get autoremove --purge -qq \ - # Inject karaf console start command into zsh history - && echo ": 0:0;bin/client" > ~/.zsh_history - -# Adding the actual core platform files to /root -ADD build/assembly /root/ - -# Making karaf start script executable -RUN chmod 0755 /root/bin/karaf - -WORKDIR "/root" - -# Ports to expose -EXPOSE 8181 8443 29998 5005 1099 1098 9292 29292 - -ENTRYPOINT ["/root/bin/karaf"] diff --git a/karaf-assembly/LICENSE.txt b/karaf-assembly/LICENSE.txt deleted file mode 100644 index 261eeb9e9..000000000 --- a/karaf-assembly/LICENSE.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/karaf-assembly/README.md b/karaf-assembly/README.md deleted file mode 100644 index 0a20fb25c..000000000 --- a/karaf-assembly/README.md +++ /dev/null @@ -1,19 +0,0 @@ -The _karaf-assembly_ is the main module, containing the karaf instance. This creates the binary that launches the OSGi engine. All other modules run on top of this. - - -Create a custom Apache Karaf configuration including Camel. - -Built it: - -``` -mvn clean install -``` - - -Run it: - -``` -target/assembly/bin/karaf clean debug -``` - -(`clean` clears the workspace at startup, `debug` allows remote debugging. None of these is required) diff --git a/karaf-assembly/build.gradle.kts b/karaf-assembly/build.gradle.kts deleted file mode 100644 index 2b3e8601a..000000000 --- a/karaf-assembly/build.gradle.kts +++ /dev/null @@ -1,127 +0,0 @@ -@file:Suppress("PropertyName") - -import com.github.jlouns.gradle.cpe.tasks.CrossPlatformExec -import java.util.* - -@Suppress("UNCHECKED_CAST") -val libraryVersions = rootProject.extra.get("libraryVersions") as Map - -dependencies { - testImplementation(project(":ids-api")) { isTransitive = false } - - osgiCore("org.apache.felix", "org.apache.felix.framework", libraryVersions["felixFramework"]) - osgiCore("org.osgi", "osgi.cmpn", libraryVersions["osgiCompendium"]) - - testImplementation("org.ops4j.pax.exam", "pax-exam", libraryVersions["paxExam"]) - testImplementation("org.ops4j.pax.exam", "pax-exam-junit4", libraryVersions["paxExam"]) - testImplementation("org.ops4j.pax.exam", "pax-exam-container-karaf", libraryVersions["paxExam"]) - testImplementation("org.apache.karaf.itests", "common", libraryVersions["karaf"]) - - testImplementation("org.apache.karaf", "apache-karaf", libraryVersions["karaf"], ext = "pom") - testImplementation("org.awaitility", "awaitility", libraryVersions["awaitility"]) - testImplementation("org.apache.servicemix.bundles", "org.apache.servicemix.bundles.hamcrest", - libraryVersions["servicemixHamcrest"]) - testImplementation("javax.annotation", "javax.annotation-api", libraryVersions["javaxAnnotation"]) -} - -val BRANDING_WIDTH = 84 - -fun getBrandingAligned(branding: String, space: String = "\\u0020"): String { - val sb = StringBuilder() - val spaces = (BRANDING_WIDTH - branding.length) / 2 - for (i in 0 until spaces) { - sb.append(space) - } - sb.append(branding) - return sb.toString() -} - -val parsePom = tasks.register("parsePom") { - from(project.projectDir) { - include("pom.template.xml") - } - expand( - mapOf( - "projectVersion" to project.version as String, - "karafVersion" to libraryVersions["karaf"], - "paxVersion" to libraryVersions["pax"], - "brandingFirst" to getBrandingAligned( - "Trusted Connector Console (${project.version}), Apache Karaf (${libraryVersions["karaf"]})" - ), - "brandingSecond" to getBrandingAligned( - "Fraunhofer AISEC ${Calendar.getInstance().get(Calendar.YEAR)}" - ) - ) - ) - rename("pom.template.xml", "pom.xml") - into(project.projectDir) - - inputs.property("projectVersion", project.version) - inputs.property("karafVersion", libraryVersions["karaf"]) -} - -/* -Now this is tricky. We need to build a custom distribution of karaf with a few features: -- included ids feature -- a bunch of configuration files in etc - -Since gradle still has no karaf-assembly plugin we need to do this using maven (meh!) -*/ -val assembleKaraf by tasks.registering(CrossPlatformExec::class) { - commandLine(listOf("./mvnw", "--no-transfer-progress", "clean", "package")) - doLast { - mkdir("${project.buildDir}/classes/kotlin/test") - } - dependsOn(parsePom) - // Wait for all relevant sub projects before executing assembly process - rootProject.subprojects.forEach { - if (it.name.startsWith("ids") || it.name.startsWith("camel-") - || it.name.endsWith("-patch") || it.name.endsWith("-wrapper") - || it.name == "karaf-features-ids" - ) { - dependsOn(it.tasks.install) - } - } -} -// Sometimes required to fix an error caused by a non-existing folder (maybe caused by mvn clean) -mkdir("${project.buildDir}/classes/kotlin/test") - -tasks.jar { - dependsOn(assembleKaraf) -} - -// The PaxExam config of KarafTestSupport requires the maven dependency meta information generated here -val makeMavenDependencies by tasks.registering { - val outputFileDir = project.file("build/classes/java/test/META-INF/maven/") - val outputFile = file(outputFileDir).resolve("dependencies.properties") - outputs.file(outputFile) - - doFirst { - val properties = Properties() - - // information of the project itself - properties.setProperty("groupId", "${project.group}") - properties.setProperty("artifactId", project.name) - properties.setProperty("version", "${project.version}") - properties.setProperty("${project.group}/${project.name}/version", "${project.version}") - - // information of all test runtime dependencies - project.configurations.testCompileClasspath.get().resolvedConfiguration.resolvedArtifacts.forEach { - val keyBase = it.moduleVersion.id.group + "/" + it.moduleVersion.id.name - properties.setProperty("${keyBase}/scope", "compile") - properties.setProperty("${keyBase}/type", it.extension) - properties.setProperty("${keyBase}/version", it.moduleVersion.id.version) - } - - outputFileDir.mkdirs() - outputFile.outputStream().use { - properties.store(it, "Generated from Gradle for PaxExam integration tests") - } - } -} - -tasks.integrationTest { - dependsOn(makeMavenDependencies) - dependsOn(assembleKaraf) - outputs.upToDateWhen { false } -} diff --git a/karaf-assembly/mvnw b/karaf-assembly/mvnw deleted file mode 100755 index d2f0ea380..000000000 --- a/karaf-assembly/mvnw +++ /dev/null @@ -1,310 +0,0 @@ -#!/bin/sh -# ---------------------------------------------------------------------------- -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# ---------------------------------------------------------------------------- - -# ---------------------------------------------------------------------------- -# Maven2 Start Up Batch script -# -# Required ENV vars: -# ------------------ -# JAVA_HOME - location of a JDK home dir -# -# Optional ENV vars -# ----------------- -# M2_HOME - location of maven2's installed home dir -# MAVEN_OPTS - parameters passed to the Java VM when running Maven -# e.g. to debug Maven itself, use -# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -# MAVEN_SKIP_RC - flag to disable loading of mavenrc files -# ---------------------------------------------------------------------------- - -if [ -z "$MAVEN_SKIP_RC" ] ; then - - if [ -f /etc/mavenrc ] ; then - . /etc/mavenrc - fi - - if [ -f "$HOME/.mavenrc" ] ; then - . "$HOME/.mavenrc" - fi - -fi - -# OS specific support. $var _must_ be set to either true or false. -cygwin=false; -darwin=false; -mingw=false -case "`uname`" in - CYGWIN*) cygwin=true ;; - MINGW*) mingw=true;; - Darwin*) darwin=true - # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home - # See https://developer.apple.com/library/mac/qa/qa1170/_index.html - if [ -z "$JAVA_HOME" ]; then - if [ -x "/usr/libexec/java_home" ]; then - export JAVA_HOME="`/usr/libexec/java_home`" - else - export JAVA_HOME="/Library/Java/Home" - fi - fi - ;; -esac - -if [ -z "$JAVA_HOME" ] ; then - if [ -r /etc/gentoo-release ] ; then - JAVA_HOME=`java-config --jre-home` - fi -fi - -if [ -z "$M2_HOME" ] ; then - ## resolve links - $0 may be a link to maven's home - PRG="$0" - - # need this for relative symlinks - while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG="`dirname "$PRG"`/$link" - fi - done - - saveddir=`pwd` - - M2_HOME=`dirname "$PRG"`/.. - - # make it fully qualified - M2_HOME=`cd "$M2_HOME" && pwd` - - cd "$saveddir" - # echo Using m2 at $M2_HOME -fi - -# For Cygwin, ensure paths are in UNIX format before anything is touched -if $cygwin ; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --unix "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --unix "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --unix "$CLASSPATH"` -fi - -# For Mingw, ensure paths are in UNIX format before anything is touched -if $mingw ; then - [ -n "$M2_HOME" ] && - M2_HOME="`(cd "$M2_HOME"; pwd)`" - [ -n "$JAVA_HOME" ] && - JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" -fi - -if [ -z "$JAVA_HOME" ]; then - javaExecutable="`which javac`" - if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then - # readlink(1) is not available as standard on Solaris 10. - readLink=`which readlink` - if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then - if $darwin ; then - javaHome="`dirname \"$javaExecutable\"`" - javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" - else - javaExecutable="`readlink -f \"$javaExecutable\"`" - fi - javaHome="`dirname \"$javaExecutable\"`" - javaHome=`expr "$javaHome" : '\(.*\)/bin'` - JAVA_HOME="$javaHome" - export JAVA_HOME - fi - fi -fi - -if [ -z "$JAVACMD" ] ; then - if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - else - JAVACMD="`which java`" - fi -fi - -if [ ! -x "$JAVACMD" ] ; then - echo "Error: JAVA_HOME is not defined correctly." >&2 - echo " We cannot execute $JAVACMD" >&2 - exit 1 -fi - -if [ -z "$JAVA_HOME" ] ; then - echo "Warning: JAVA_HOME environment variable is not set." -fi - -CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher - -# traverses directory structure from process work directory to filesystem root -# first directory with .mvn subdirectory is considered project base directory -find_maven_basedir() { - - if [ -z "$1" ] - then - echo "Path not specified to find_maven_basedir" - return 1 - fi - - basedir="$1" - wdir="$1" - while [ "$wdir" != '/' ] ; do - if [ -d "$wdir"/.mvn ] ; then - basedir=$wdir - break - fi - # workaround for JBEAP-8937 (on Solaris 10/Sparc) - if [ -d "${wdir}" ]; then - wdir=`cd "$wdir/.."; pwd` - fi - # end of workaround - done - echo "${basedir}" -} - -# concatenates all lines of a file -concat_lines() { - if [ -f "$1" ]; then - echo "$(tr -s '\n' ' ' < "$1")" - fi -} - -BASE_DIR=`find_maven_basedir "$(pwd)"` -if [ -z "$BASE_DIR" ]; then - exit 1; -fi - -########################################################################################## -# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central -# This allows using the maven wrapper in projects that prohibit checking in binary data. -########################################################################################## -if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found .mvn/wrapper/maven-wrapper.jar" - fi -else - if [ "$MVNW_VERBOSE" = true ]; then - echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." - fi - if [ -n "$MVNW_REPOURL" ]; then - jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" - else - jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" - fi - while IFS="=" read key value; do - case "$key" in (wrapperUrl) jarUrl="$value"; break ;; - esac - done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" - if [ "$MVNW_VERBOSE" = true ]; then - echo "Downloading from: $jarUrl" - fi - wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" - if $cygwin; then - wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` - fi - - if command -v wget > /dev/null; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found wget ... using wget" - fi - if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then - wget "$jarUrl" -O "$wrapperJarPath" - else - wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" - fi - elif command -v curl > /dev/null; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found curl ... using curl" - fi - if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then - curl -o "$wrapperJarPath" "$jarUrl" -f - else - curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f - fi - - else - if [ "$MVNW_VERBOSE" = true ]; then - echo "Falling back to using Java to download" - fi - javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" - # For Cygwin, switch paths to Windows format before running javac - if $cygwin; then - javaClass=`cygpath --path --windows "$javaClass"` - fi - if [ -e "$javaClass" ]; then - if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then - if [ "$MVNW_VERBOSE" = true ]; then - echo " - Compiling MavenWrapperDownloader.java ..." - fi - # Compiling the Java class - ("$JAVA_HOME/bin/javac" "$javaClass") - fi - if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then - # Running the downloader - if [ "$MVNW_VERBOSE" = true ]; then - echo " - Running MavenWrapperDownloader.java ..." - fi - ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") - fi - fi - fi -fi -########################################################################################## -# End of extension -########################################################################################## - -export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} -if [ "$MVNW_VERBOSE" = true ]; then - echo $MAVEN_PROJECTBASEDIR -fi -MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" - -# For Cygwin, switch paths to Windows format before running java -if $cygwin; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --path --windows "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --windows "$CLASSPATH"` - [ -n "$MAVEN_PROJECTBASEDIR" ] && - MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` -fi - -# Provide a "standardized" way to retrieve the CLI args that will -# work with both Windows and non-Windows executions. -MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" -export MAVEN_CMD_LINE_ARGS - -WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -exec "$JAVACMD" \ - $MAVEN_OPTS \ - -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ - "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ - ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/karaf-assembly/mvnw.cmd b/karaf-assembly/mvnw.cmd deleted file mode 100755 index b26ab24f0..000000000 --- a/karaf-assembly/mvnw.cmd +++ /dev/null @@ -1,182 +0,0 @@ -@REM ---------------------------------------------------------------------------- -@REM Licensed to the Apache Software Foundation (ASF) under one -@REM or more contributor license agreements. See the NOTICE file -@REM distributed with this work for additional information -@REM regarding copyright ownership. The ASF licenses this file -@REM to you under the Apache License, Version 2.0 (the -@REM "License"); you may not use this file except in compliance -@REM with the License. You may obtain a copy of the License at -@REM -@REM http://www.apache.org/licenses/LICENSE-2.0 -@REM -@REM Unless required by applicable law or agreed to in writing, -@REM software distributed under the License is distributed on an -@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -@REM KIND, either express or implied. See the License for the -@REM specific language governing permissions and limitations -@REM under the License. -@REM ---------------------------------------------------------------------------- - -@REM ---------------------------------------------------------------------------- -@REM Maven2 Start Up Batch script -@REM -@REM Required ENV vars: -@REM JAVA_HOME - location of a JDK home dir -@REM -@REM Optional ENV vars -@REM M2_HOME - location of maven2's installed home dir -@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands -@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending -@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven -@REM e.g. to debug Maven itself, use -@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files -@REM ---------------------------------------------------------------------------- - -@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' -@echo off -@REM set title of command window -title %0 -@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' -@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% - -@REM set %HOME% to equivalent of $HOME -if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") - -@REM Execute a user defined script before this one -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre -@REM check for pre script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" -if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" -:skipRcPre - -@setlocal - -set ERROR_CODE=0 - -@REM To isolate internal variables from possible post scripts, we use another setlocal -@setlocal - -@REM ==== START VALIDATION ==== -if not "%JAVA_HOME%" == "" goto OkJHome - -echo. -echo Error: JAVA_HOME not found in your environment. >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -:OkJHome -if exist "%JAVA_HOME%\bin\java.exe" goto init - -echo. -echo Error: JAVA_HOME is set to an invalid directory. >&2 -echo JAVA_HOME = "%JAVA_HOME%" >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -@REM ==== END VALIDATION ==== - -:init - -@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". -@REM Fallback to current working directory if not found. - -set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% -IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir - -set EXEC_DIR=%CD% -set WDIR=%EXEC_DIR% -:findBaseDir -IF EXIST "%WDIR%"\.mvn goto baseDirFound -cd .. -IF "%WDIR%"=="%CD%" goto baseDirNotFound -set WDIR=%CD% -goto findBaseDir - -:baseDirFound -set MAVEN_PROJECTBASEDIR=%WDIR% -cd "%EXEC_DIR%" -goto endDetectBaseDir - -:baseDirNotFound -set MAVEN_PROJECTBASEDIR=%EXEC_DIR% -cd "%EXEC_DIR%" - -:endDetectBaseDir - -IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig - -@setlocal EnableExtensions EnableDelayedExpansion -for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a -@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% - -:endReadAdditionalConfig - -SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" -set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" -set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" - -FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( - IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B -) - -@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central -@REM This allows using the maven wrapper in projects that prohibit checking in binary data. -if exist %WRAPPER_JAR% ( - if "%MVNW_VERBOSE%" == "true" ( - echo Found %WRAPPER_JAR% - ) -) else ( - if not "%MVNW_REPOURL%" == "" ( - SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" - ) - if "%MVNW_VERBOSE%" == "true" ( - echo Couldn't find %WRAPPER_JAR%, downloading it ... - echo Downloading from: %DOWNLOAD_URL% - ) - - powershell -Command "&{"^ - "$webclient = new-object System.Net.WebClient;"^ - "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ - "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ - "}"^ - "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ - "}" - if "%MVNW_VERBOSE%" == "true" ( - echo Finished downloading %WRAPPER_JAR% - ) -) -@REM End of extension - -@REM Provide a "standardized" way to retrieve the CLI args that will -@REM work with both Windows and non-Windows executions. -set MAVEN_CMD_LINE_ARGS=%* - -%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* -if ERRORLEVEL 1 goto error -goto end - -:error -set ERROR_CODE=1 - -:end -@endlocal & set ERROR_CODE=%ERROR_CODE% - -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost -@REM check for post script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" -if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" -:skipRcPost - -@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' -if "%MAVEN_BATCH_PAUSE%" == "on" pause - -if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% - -exit /B %ERROR_CODE% diff --git a/karaf-assembly/pom.template.xml b/karaf-assembly/pom.template.xml deleted file mode 100644 index 26ec1526c..000000000 --- a/karaf-assembly/pom.template.xml +++ /dev/null @@ -1,119 +0,0 @@ - - - 4.0.0 - - de.fhg.aisec.ids - karaf-assembly - ${projectVersion} - karaf-assembly - IDS :: Karaf Assembly - - - UTF-8 - ${brandingFirst} - ${brandingSecond} - ${karafVersion} - ${paxVersion} - - - - - org.apache.karaf.features - framework - ${karafVersion} - kar - - - org.apache.karaf.features - standard - features - ${karafVersion} - xml - runtime - - - - org.apache.karaf.features - spring-legacy - ${karafVersion} - features - xml - runtime - - - - de.fhg.aisec.ids - karaf-features-ids - ${projectVersion} - features - xml - runtime - - - - - build - - - src/main/resources - false - - **/* - - - - src/main/template-resources - true - - **/* - - - - - - - org.apache.maven.plugins - maven-resources-plugin - 3.1.0 - - - process-resources - - resources - - - - - - org.apache.karaf.tooling - karaf-maven-plugin - true - ${karafVersion} - - - wrap - management - ssh - aries-blueprint - shell - shell-compat - feature - bundle - config - deployer - feature - kar - log - package - service - system - - - ids - camel-zeromq - - - - - - diff --git a/karaf-assembly/src/main/resources/bin/setenv b/karaf-assembly/src/main/resources/bin/setenv deleted file mode 100755 index 45e9dccd8..000000000 --- a/karaf-assembly/src/main/resources/bin/setenv +++ /dev/null @@ -1,54 +0,0 @@ -#!/bin/sh -# -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# -# handle specific scripts; the SCRIPT_NAME is exactly the name of the Karaf -# script: client, instance, shell, start, status, stop, karaf -# -# if [ "$KARAF_SCRIPT" == "SCRIPT_NAME" ]; then -# Actions go here... -# fi - -# -# general settings which should be applied for all scripts go here; please keep -# in mind that it is possible that scripts might be executed more than once, e.g. -# in example of the start script where the start script is executed first and the -# karaf script afterwards. -# - -# -# The following section shows the possible configuration options for the default -# karaf scripts -# -# export JAVA_HOME # Location of Java installation -# export JAVA_MIN_MEM # Minimum memory for the JVM -#export JAVA_MAX_MEM=512M # Maximum memory for the JVM -# export JAVA_PERM_MEM # Minimum perm memory for the JVM -# export JAVA_MAX_PERM_MEM # Maximum perm memory for the JVM -#export JAVA_MAX_PERM_MEM=256M # Maximum perm memory for the JVM -# export EXTRA_JAVA_OPTS # Additional JVM options -# export KARAF_HOME # Karaf home folder -# export KARAF_DATA # Karaf data folder -# export KARAF_BASE # Karaf base folder -# export KARAF_ETC # Karaf etc folder -# export KARAF_OPTS # Additional available Karaf options -# export KARAF_DEBUG # Enable debug mode -# export KARAF_REDIRECT # Enable/set the std/err redirection when using bin/start - - -export KARAF_OPTS='-Djava.net.preferIPv4Stack=true' diff --git a/karaf-assembly/src/main/resources/deploy/flow-policy-example.pl b/karaf-assembly/src/main/resources/deploy/flow-policy-example.pl deleted file mode 100644 index 5d94233a6..000000000 --- a/karaf-assembly/src/main/resources/deploy/flow-policy-example.pl +++ /dev/null @@ -1,45 +0,0 @@ -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% Prolog representation of a data flow policy -% -% Source: default -% -% Do not edit this file, it has been generated automatically -% by XText/Xtend. -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% Only required for SWI-Prolog -% Allow the following predicates to be scattered around the prolog file. -% Otherwise Prolog will issue a warning if they are not stated in subsequent lines. -%:- discontiguous service/1. -%:- discontiguous has_endpoint/2. -%:- discontiguous creates_label/2. -%:- discontiguous removes_label/2. -%:- discontiguous rule/1. -%:- discontiguous rule_priority/2. -%:- discontiguous receives_label/1. -%:- discontiguous has_decision/2. -%:- discontiguous has_target/2. -%:- discontiguous has_capability/2. -%:- discontiguous has_property/3. -%:- discontiguous requires_prerequisites/2. -%:- discontiguous has_alternativedecision/2. -%:- discontiguous has_obligation/2. - -%%%%%%%%% Basic Blocking Rule %%%%%%%%%% -rule(dropAll). -rule_priority(dropAll,0). -has_decision(dropAll,drop). -receives_label(dropAll). -has_target(dropAll,serviceAll). - -%%%%%%%%%% Catch All Service %%%%%%%%%%% -service(serviceAll). -has_endpoint(serviceAll,'.*'). - -%%%%%%%%%%%%%%%% Rules %%%%%%%%%%%%%%%%% -% Allow everything -rule(allowAll). -rule_priority(allowAll, 1). -has_target(allowAll, serviceAll). -receives_label(allowAll). -has_decision(allowAll, allow). \ No newline at end of file diff --git a/karaf-assembly/src/main/resources/etc/consumer-keystore.p12 b/karaf-assembly/src/main/resources/etc/consumer-keystore.p12 deleted file mode 100644 index 6607767d644aea4ea7a11e98ac540c623b80283e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2693 zcmY+^c{me}9|v%oZEjNTkejgC%rV#ZtNNm(CKKhpG734SAy+F$TXQXP--^vdu`x%k zkXx=UBv;PlOvtbA^Zb6l@9+1==lML(`~5ucKVNVH_dOth9ZujjgK(+Fo{!z-18@NH z3EU_Ufm`c$42Kgy3;$G*d;;j*?`Q-FVEg_0{%HVkNeK797kB{>I6sK9JVi88`A7=| z1ah)P6F~VZywpW&3z4n6S^2p{Kk$V%E=f<@tZGQd-P=J8Hk|AIlG1>yU0>xCvxy@* z72iX0B z^iNOOYZnWAA17!za&dVjSl|0p{BTpRI7}087_@ATLFmf_szlX=%EBu2{)pmvw&aJx zG6#b{-am5m!=QAl{S4&x>Mb)z5*-oub}-w+acmngdOgJ$qpu{_qK;afIiH=4fT0dv zNAG?Q*OEFm!#bpEeQa>jv&y9hxDw;TSjy=FZ{}(a5pzSxiIT=yj%fvu#`m%BZ09m_ zABR8-G2y_w6^$79uhophGzE4&(>1$(|D;UF)i$ z{*NqRf9&PtUYvuAHQHGCyKM@yxV~SE){sbW40>n@)%*)61=3!ny(OLjxUa>2!IoK0 znXUnu=C1Qy;hskX3utTp)SU~Hrj+#54C_ddr(fD0x3AlknVEjGmqTmVekc@oLI`68 zK1+t0bcN@aEZyisINyA$LE`vT(z>Z0fq3?+E`@;tcaa@5Rr3 zDaeeIVB_@uC`Nkfa0*$0Zj5upWWjWzgmqC8h@gfy&tULFrOE9jMxCrxyD07OQ(2>W^QkYMmZrbM((0 zctCIT{255Lfk%t;1j+&v>#Kt{&uPcSpZCIJIVUufon9=&wyH~_R9W&N$kGg+z@{PL zY(*5K;}aUBm)tJPzh0H|s}Dy~vKQ_UI>E+cr0q;n63IIU+Yk#YA`&h8BlimIKJQO* z!>${8(V*eS_X{sYHoMBdpCcd3E=#aCNmC*5fQBOZ%(*3Xfll1AzPbR~TGUrc)nT zGo*-VxZR358&I5M)MfLluG;rccK;s@j#tzcy*M-`Sa%a5lIh!Fs9wlw)bop)-bx++A>y3?OEjjAaxCa)^L!NG(rEE1#5k&`I5 z6jxwSFKq4RaIU#3b1T1)r~KLj=Wg7+<(_fk?xjKb9y*tnDN$rT0-YT{d+*5Pby|}J zrD^GNQbwHq_T$;Beg66qdG8 zO;2vL4nn~8uo;P`G2h1$nbFagdwVHS@XIKp8kbHi?kGryS*cQ0Ng6Y>;Lri{{K%n6 z!2k3N3*RC44)xH9!K&C-ZLMJM>Arm@q*@f9*Dt7R$B1gavI(*799D7w9`PA@B8)Q? zWfkS~_9YLpKjw{9e`Rimmr#@zNP_Y!!}`4kvuGV+-lc$c^-qN4{i)d>Fg}m+LD<97 zg$ELBiTJa(Vp*$6OEGE)e69OoBHnUlbIgoYX)7dTv-Y-h?qule3mJ(NX}H>gXT?0gKHAc5m4GP9-ld#v3ha=8)GL&M@z( ztjZ7TM${6Iw0NtV0S=eDj|RGCg`L>dgF~<4NvDjjK}SQv$kJ2h3Dyz*i9T!{lb-R!&|MzClh?;^W+@-tW{05F?w<5 z(z}Ip4kPmN2kYC|Z^v}BRDL0=UhcO^dNFA^chxakzg}Gh@wjfTfWL5H_6)4MskT6| zLM`|XL*e`eByU^Vuv%KU{vz7{J;8Sp76@$k;+mo}~m6Um+61^@$*YdK72rK z<3^vjq&E$`h^9B*&bu#RLLd2}EC>g~>`X%F+s?MRGpX;DG~T^dInUj$FsV07dbPG= zCVK7(#`e^P#jKik9~GUCP=w3>S4S>kga}CJeMEJi#7poF&yM-m$u)bS(k-btI07yU x=YoLM_}PIHU^bADxShH5uH&M#qzmn5a<0*Q!>&8%Qya3@?X+^2G#%o diff --git a/karaf-assembly/src/main/resources/etc/custom.properties b/karaf-assembly/src/main/resources/etc/custom.properties deleted file mode 100644 index 9e1ee6462..000000000 --- a/karaf-assembly/src/main/resources/etc/custom.properties +++ /dev/null @@ -1,41 +0,0 @@ -################################################################################ -# -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -################################################################################ - -# -# All the values specified here will override the default values given -# in config.properties. -# - -karaf.systemBundlesStartLevel=50 - -# -# You can place any customized configuration here. -# - -java.net.preferIPv4Stack=true - -# Disable shutdown port -karaf.shutdown.port=-1 - -# Re-enabled SSH server to allow attaching to a running Docker-version of the Trusted Connector. -# TODO: find a better solution to handle this. Pivotal story id: #157912999 -karaf.startRemoteShell=true - -# Reduce the default 20 threads to a reasonable size -org.apache.felix.eventadmin.ThreadPoolSize=3 diff --git a/karaf-assembly/src/main/resources/etc/de.fhg.dfcontrol.rules.cfg b/karaf-assembly/src/main/resources/etc/de.fhg.dfcontrol.rules.cfg deleted file mode 100644 index fff7023ca..000000000 --- a/karaf-assembly/src/main/resources/etc/de.fhg.dfcontrol.rules.cfg +++ /dev/null @@ -1,5 +0,0 @@ -LABEL .*input AS raw -LABEL .*process AS processed -REMOVELABEL raw FROM .*process -ALLOW raw TO .*process -ALLOW processed TO hdfs.* diff --git a/karaf-assembly/src/main/resources/etc/idscp2/aisecconnector1-keystore.p12 b/karaf-assembly/src/main/resources/etc/idscp2/aisecconnector1-keystore.p12 deleted file mode 100644 index bca94974f6805074438e1e6324f91800b37241b8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2853 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 diff --git a/karaf-assembly/src/main/resources/etc/idscp2/client-truststore_new.p12 b/karaf-assembly/src/main/resources/etc/idscp2/client-truststore_new.p12 deleted file mode 100644 index 0791c1d13bd74468f1a7f3b97338405cb598c3bc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2266 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 diff --git a/karaf-assembly/src/main/resources/etc/import_ca_chain_into_keystore.sh b/karaf-assembly/src/main/resources/etc/import_ca_chain_into_keystore.sh deleted file mode 100644 index b4875954e..000000000 --- a/karaf-assembly/src/main/resources/etc/import_ca_chain_into_keystore.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash -# -# Imports CA chain and connector cert into karaf keystore. Execute in $(Karaf-dir)/etc/keystores/ -# Then, build karaf. The keystore is automatically deployed. - -keytool -keystore keystore.jks -storepass password -importcert -trustcacerts -noprompt -alias root -file ../../../../../ssl/ca/rootca.cert -keytool -keystore keystore.jks -storepass password -importcert -alias ca -file ../../../../../ssl/ca/subca.cert -keytool -keystore keystore.jks -storepass password -importcert -alias client -file ../../../../../ssl/certs/client.cert -keytool -keystore keystore.jks -storepass password -importcert -alias server -file ../../../../../ssl/certs/server.cert - diff --git a/karaf-assembly/src/main/resources/etc/jetty.xml b/karaf-assembly/src/main/resources/etc/jetty.xml deleted file mode 100644 index 626e0e4f4..000000000 --- a/karaf-assembly/src/main/resources/etc/jetty.xml +++ /dev/null @@ -1,91 +0,0 @@ - - - - - - - - https - - - - - - - - - - - - - - - - - - - - - /etc/tls-webconsole/keystore_latest.p12 - - password - password - - - - - - SSL - SSLv2 - SSLv2Hello - SSLv3 - - - - - ^.*_(MD5|SHA|SHA1)$ - ^TLS_RSA_.*$ - ^SSL_.*$ - ^.*_NULL_.*$ - ^.*_anon_.*$ - - - - - - - - - - - - - - - - - - - http/1.1 - - - - - - - - - - - - - 0.0.0.0:8443 - - - - - - - - - \ No newline at end of file diff --git a/karaf-assembly/src/main/resources/etc/karaf_maven_settings.xml b/karaf-assembly/src/main/resources/etc/karaf_maven_settings.xml deleted file mode 100644 index 7f8349b4d..000000000 --- a/karaf-assembly/src/main/resources/etc/karaf_maven_settings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - \ No newline at end of file diff --git a/karaf-assembly/src/main/resources/etc/org.apache.felix.fileinstall-deploy.cfg b/karaf-assembly/src/main/resources/etc/org.apache.felix.fileinstall-deploy.cfg deleted file mode 100644 index 966ff752c..000000000 --- a/karaf-assembly/src/main/resources/etc/org.apache.felix.fileinstall-deploy.cfg +++ /dev/null @@ -1,25 +0,0 @@ -################################################################################ -# -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -################################################################################ - -felix.fileinstall.dir = ${karaf.base}/deploy -felix.fileinstall.tmpdir = ${karaf.data}/generated-bundles -felix.fileinstall.poll = 15000 -felix.fileinstall.start.level = 80 -felix.fileinstall.active.level = 80 -felix.fileinstall.log.level = 3 diff --git a/karaf-assembly/src/main/resources/etc/org.apache.karaf.management.cfg b/karaf-assembly/src/main/resources/etc/org.apache.karaf.management.cfg deleted file mode 100644 index 9a4141c9e..000000000 --- a/karaf-assembly/src/main/resources/etc/org.apache.karaf.management.cfg +++ /dev/null @@ -1,112 +0,0 @@ - -# -# The properties in this file define the configuration of Apache Karaf's JMX Management -# - -# -# Port number for RMI registry connection -# -#rmiRegistryPort = 1099 -#rmiRegistryPort = -1 - -# -# Host for RMI registry -# -#rmiRegistryHost = 127.0.0.1 - -# -# Port number for RMI server connection -# -#rmiServerPort = 44444 -#rmiServerPort = -1 - -# -# Host for RMI server -# -#rmiServerHost = 127.0.0.1 - -# -# Name of the JAAS realm used for authentication -# -jmxRealm = karaf - -# -# The service URL for the JMXConnectorServer -# -#serviceUrl = service:jmx:rmi://127.0.0.1:44444/jndi/rmi://127.0.0.1:1099/karaf-root -# Empty service URL disabled JMXConnectorServer. This will generate an error in the logs but this is intended -serviceUrl = - -# -# Whether any threads started for the JMXConnectorServer should be started as daemon threads -# -daemon = true - -# -# Whether the JMXConnectorServer should be started in a separate thread -# -threaded = true - -# -# The ObjectName used to register the JMXConnectorServer -# -#objectName = connector:name=rmi - -# -# Timeout to lookup for the keystore in case of SSL authentication usage -# -#keyStoreAvailabilityTimeout = 5000 - -# -# The type of authentication -# -#authenticatorType = password -authenticatorType = password - -# -# Enable or not SSL/TLS -# -#secured = false - -# -# Secure algorithm to use -# -#secureAlgorithm = default - -# -# Secure protocol to use -# -#secureProtocol = TLS - -# -# Keystore to use for secure mode -# -#keyStore = karaf.ks - -# -# Alias of the key to use in the keystore -# -#keyAlias = karaf - -# -# Truststore to use for secure mode -# -#trustStore = karaf.ts - -# -# Create the JMX RMI registry -# -#createRmiRegistry = true -createRmiRegistry = false - -# -# Locate the JMX RMI registry -# -#locateRmiRegistry = true -locateRmiRegistry = false - -# -# Locate an existing MBean server if possible (useful when Karaf is embedded) -# -#locateExistingMBeanServerIfPossible = true - diff --git a/karaf-assembly/src/main/resources/etc/org.ops4j.pax.logging.cfg b/karaf-assembly/src/main/resources/etc/org.ops4j.pax.logging.cfg deleted file mode 100644 index b27ab52ff..000000000 --- a/karaf-assembly/src/main/resources/etc/org.ops4j.pax.logging.cfg +++ /dev/null @@ -1,106 +0,0 @@ -################################################################################ -# -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -################################################################################ - -# Common pattern layout for appenders -log4j2.pattern = %d{ISO8601} | %-5p | %-16t | %-32c{1} | %X{bundle.id} - %X{bundle.name} - %X{bundle.version} | %m%n - -# Root logger -log4j2.rootLogger.level = INFO -# uncomment to use asynchronous loggers, which require mvn:com.lmax/disruptor/3.3.2 library -#log4j2.rootLogger.type = asyncRoot -#log4j2.rootLogger.includeLocation = false -log4j2.rootLogger.appenderRef.RollingFile.ref = RollingFile -log4j2.rootLogger.appenderRef.PaxOsgi.ref = PaxOsgi -log4j2.rootLogger.appenderRef.Console.ref = Console -log4j2.rootLogger.appenderRef.Console.filter.threshold.type = ThresholdFilter -log4j2.rootLogger.appenderRef.Console.filter.threshold.level = OFF - -# Loggers configurations useful for debugging - -log4j2.logger.ids.name = de.fhg.aisec.ids -log4j2.logger.ids.level = DEBUG - -# IDSCP2 logger -;log4j2.logger.idscp2.name = de.fhg.aisec.ids.idscp2 -;log4j2.logger.idscp2.level = TRACE - -# Felix logger -#log4j2.logger.felix.name = org.apache.felix -#log4j2.logger.felix.level = DEBUG - -# Karaf logger -#log4j2.logger.karaf.name = org.apache.karaf -#log4j2.logger.karaf.level = DEBUG - -# Spifly logger -log4j2.logger.spifly.name = org.apache.aries.spifly -log4j2.logger.spifly.level = INFO - -# Security audit logger -log4j2.logger.audit.name = org.apache.karaf.jaas.modules.audit -log4j2.logger.audit.level = INFO -log4j2.logger.audit.additivity = false -log4j2.logger.audit.appenderRef.AuditRollingFile.ref = AuditRollingFile - -# Appenders configuration - -# Console appender not used by default (see log4j2.rootLogger.appenderRefs) -log4j2.appender.console.type = Console -log4j2.appender.console.name = Console -log4j2.appender.console.layout.type = PatternLayout -log4j2.appender.console.layout.pattern = %d{ISO8601} | %-5p | %-16t | %-32c{1} | %X{bundle.id} - %X{bundle.name} - %X{bundle.version} | %m%n - -# Rolling file appender -log4j2.appender.rolling.type = RollingRandomAccessFile -log4j2.appender.rolling.name = RollingFile -log4j2.appender.rolling.fileName = log/karaf.log -log4j2.appender.rolling.filePattern = log/karaf.log.%i -# uncomment to not force a disk flush -#log4j2.appender.rolling.immediateFlush = false -log4j2.appender.rolling.append = true -log4j2.appender.rolling.layout.type = PatternLayout -log4j2.appender.rolling.layout.pattern = %d{ISO8601} | %-5p | %-16t | %-32c{1} | %X{bundle.id} - %X{bundle.name} - %X{bundle.version} | %m%n -log4j2.appender.rolling.policies.type = Policies -log4j2.appender.rolling.policies.size.type = SizeBasedTriggeringPolicy -log4j2.appender.rolling.policies.size.size = 16MB - -# Audit file appender -log4j2.appender.audit.type = RollingRandomAccessFile -log4j2.appender.audit.name = AuditRollingFile -log4j2.appender.audit.fileName = security/audit.log -log4j2.appender.audit.filePattern = security/audit.log.%i -log4j2.appender.audit.append = true -log4j2.appender.audit.layout.type = PatternLayout -log4j2.appender.audit.layout.pattern = %d{ISO8601} | %-5p | %-16t | %-32c{1} | %X{bundle.id} - %X{bundle.name} - %X{bundle.version} | %m%n -log4j2.appender.audit.policies.type = Policies -log4j2.appender.audit.policies.size.type = SizeBasedTriggeringPolicy -log4j2.appender.audit.policies.size.size = 8MB - -# OSGi appender -log4j2.appender.osgi.type = PaxOsgi -log4j2.appender.osgi.name = PaxOsgi -log4j2.appender.osgi.filter = * - -# help with identification of maven-related problems with pax-url-aether -#log4j2.logger.aether.name = shaded.org.eclipse.aether -#log4j2.logger.aether.level = TRACE -#log4j2.logger.http-headers.name = shaded.org.apache.http.headers -#log4j2.logger.http-headers.level = DEBUG -#log4j2.logger.maven.name = org.ops4j.pax.url.mvn -#log4j2.logger.maven.level = TRACE diff --git a/karaf-assembly/src/main/resources/etc/org.ops4j.pax.url.mvn.cfg b/karaf-assembly/src/main/resources/etc/org.ops4j.pax.url.mvn.cfg deleted file mode 100644 index b675f9cb8..000000000 --- a/karaf-assembly/src/main/resources/etc/org.ops4j.pax.url.mvn.cfg +++ /dev/null @@ -1,42 +0,0 @@ -################################################################################## -# -# This overrides Karaf's default org.ops4j.pax.url.mvn.cfg file to make sure -# that Karaf does not use any online repositories to pull in features or bundles. -# -################################################################################## - -# Make sure that no custom maven settings are used -org.ops4j.pax.url.mvn.settings=${karaf.home}/etc/karaf_maven_settings.xml - -# Local repositories containing all required core bundles -org.ops4j.pax.url.mvn.defaultRepositories=file:${karaf.home}/system@snapshots -org.ops4j.pax.url.mvn.localRepository=${karaf.home}/system@snapshots -org.ops4j.pax.url.mvn.useFallbackRepositories=false - - -# Remote repositories that are used when resolution of "org.ops4j.pax.url.mvn.defaultRepositories" fails -org.ops4j.pax.url.mvn.repositories= \ - https://repo1.maven.org/maven2@id=central, \ - https://repository.apache.org/content/groups/snapshots-group@id=apache@snapshots@noreleases, \ - https://oss.sonatype.org/content/repositories/ops4j-snapshots@id=ops4j.sonatype.snapshots.deploy@snapshots@noreleases - -# -# default value for connection and read timeouts, when socket.readTimeout and socket.connectionTimeout -# are not specified -org.ops4j.pax.url.mvn.timeout = 5000 -# timeout in ms when establishing http connection during artifact resolution -org.ops4j.pax.url.mvn.socket.connectionTimeout = 5000 -# timeout in ms when reading data after connecting to remote repository -org.ops4j.pax.url.mvn.socket.readTimeout = 30000 -# SO_KEEPALIVE option for sockets, defaults to false -org.ops4j.pax.url.mvn.socket.keepAlive = false -# SO_LINGER option for sockets, defaults to -1 -org.ops4j.pax.url.mvn.socket.linger = -1 -# SO_REUSEADDR option for sockets, defaults to false -org.ops4j.pax.url.mvn.socket.reuseAddress = false -# TCP_NODELAY option for sockets, defaults to true -org.ops4j.pax.url.mvn.socket.tcpNoDelay = true -# Configure buffer size for HTTP connections (output and input buffers), defaults to 8192 bytes -org.ops4j.pax.url.mvn.connection.bufferSize = 8192 -# Number of connection retries after failure is detected in http client. httpclient uses default value "3" -org.ops4j.pax.url.mvn.connection.retryCount = 3 \ No newline at end of file diff --git a/karaf-assembly/src/main/resources/etc/org.ops4j.pax.web.cfg b/karaf-assembly/src/main/resources/etc/org.ops4j.pax.web.cfg deleted file mode 100644 index 8463d022d..000000000 --- a/karaf-assembly/src/main/resources/etc/org.ops4j.pax.web.cfg +++ /dev/null @@ -1,64 +0,0 @@ -# Explicitly make pax-web aware of our jetty configuration -org.ops4j.pax.web.config.file = ${karaf.etc}/jetty.xml - -# -# min server threads -# -org.ops4j.pax.web.server.minThreads = 1 - -# -# max server threads -# -org.ops4j.pax.web.server.maxThreads = 20 - -# -# enable https -# -org.osgi.service.http.secure.enabled = true - -# -# http port. -# This is currently also in the setenv -org.osgi.service.http.port = 8181 - -# -# https port, default is 8443. -# This is currently also in the setenv -org.osgi.service.http.port.secure = 8443 - -org.ops4j.pax.web.ssl.keystore = ${karaf.etc}/test.jks -org.ops4j.pax.web.ssl.password = ids -org.ops4j.pax.web.ssl.keypassword = ids - -# -# The number of minutes after which an inactive session will timeout. -# -org.ops4j.pax.web.session.timeout = 2 - -# -# Specifies if the connections established use the nio classes from java. -# -org.osgi.service.http.useNIO = true - -# -# Set to true if certificate-based client authentication at the server is "wanted". -# -org.ops4j.pax.web.ssl.clientauthwanted = false - -# -# Set to true if certificate-based client authentication at the server is "required". -# -org.ops4j.pax.web.ssl.clientauthneeded = false - -# -# The time in milliseconds that the connection can be idle before it is closed. -# -org.ops4j.pax.web.server.idleTimeout = 10000 - -# -# Listening addresses. This should match host in the sslconnector/name attribute in jetty.xml -# Default is 0.0.0.0 -# This is currently also in the setenv -# -#org.ops4j.pax.web.listening.addresses = 0.0.0.0 - diff --git a/karaf-assembly/src/main/resources/etc/provider-keystore.p12 b/karaf-assembly/src/main/resources/etc/provider-keystore.p12 deleted file mode 100644 index 830797f6993b334c9886c6aae7031b06a96bcb4d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2693 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 diff --git a/karaf-assembly/src/main/resources/etc/users.properties b/karaf-assembly/src/main/resources/etc/users.properties deleted file mode 100644 index 7a8e789be..000000000 --- a/karaf-assembly/src/main/resources/etc/users.properties +++ /dev/null @@ -1,37 +0,0 @@ -################################################################################ -# -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -################################################################################ - -# -# This file contains the users, groups, and roles. -# Each line has to be of the format: -# -# USER=PASSWORD,ROLE1,ROLE2,... -# USER=PASSWORD,_g_:GROUP,... -# _g_\:GROUP=ROLE1,ROLE2,... -# -# All users, groups, and roles entered in this file are available after Karaf startup -# and modifiable via the JAAS command group. These users reside in a JAAS domain -# with the name "karaf". -# -karaf = karaf,_g_:admingroup -ids = ids,_g_:idsgroup -# Re-enabled SSH server to allow attaching to a running Docker-version of the Trusted Connector. -# TODO: find a better solution to handle this. Pivotal story id: #157912999 -_g_\:admingroup = group,admin,manager,viewer,systembundles,ssh -_g_\:idsgroup = group,manager,api,viewer diff --git a/karaf-assembly/src/main/template-resources/etc/branding.properties b/karaf-assembly/src/main/template-resources/etc/branding.properties deleted file mode 100644 index ef375b39a..000000000 --- a/karaf-assembly/src/main/template-resources/etc/branding.properties +++ /dev/null @@ -1,22 +0,0 @@ -{ - -} -welcome = \ -\u001B[36m _____ _ _ ____ _ \u001B[0m\r\n\ -\u001B[36m |_ _| __ _ _ ___| |_ ___ __| | / ___|___ _ __ _ __ ___ ___| |_ ___ _ __ \u001B[0m\r\n\ -\u001B[36m | || '__| | | / __| __/ _ \\/ _` | | | / _ \\| '_ \\| '_ \\ / _ \\/ __| __/ _ \\| '__| \u001B[0m\r\n\ -\u001B[36m | || | | |_| \\__ \\ || __/ (_| | | |__| (_) | | | | | | | __/ (__| || (_) | | \u001B[0m\r\n\ -\u001B[36m |_||_| \\__,_|___/\\__\\___|\\__,_| \\____\\___/|_| |_|_| |_|\\___|\\___|\\__\\___/|_| \u001B[0m\r\n\ -\r\n\ -\u001B[1m ${branding.first} \r\n\ -\r\n\ -\u001B[1m ${branding.second} \r\n\ -\r\n\ -Hit '\u001B[1m\u001B[0m' for a list of available commands\r\n\ - and '\u001B[1m[cmd] --help\u001B[0m' for help on a specific command.\r\n\ -Hit '\u001B[1m\u001B[0m' or '\u001B[1msystem:shutdown\u001B[0m' to shutdown Console.\r\n - -prompt = \u001B[1m${USER}\u001B[0m@${APPLICATION}\u001B[0m> -{ - -} \ No newline at end of file diff --git a/karaf-assembly/src/main/template-resources/etc/org.apache.karaf.features.xml b/karaf-assembly/src/main/template-resources/etc/org.apache.karaf.features.xml deleted file mode 100644 index 4bec48902..000000000 --- a/karaf-assembly/src/main/template-resources/etc/org.apache.karaf.features.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - jetty - - - - mvn:org.apache.karaf.features/standard/[0,${versions.karaf})/xml/features - mvn:org.apache.karaf.features/spring-legacy/[0,${versions.karaf})/xml/features - mvn:org.ops4j.pax.web/pax-web-features/[0,${versions.pax})/xml/features - - \ No newline at end of file diff --git a/karaf-assembly/src/test/java/de/fhg/aisec/ids/assembly/AssemblyIT.java b/karaf-assembly/src/test/java/de/fhg/aisec/ids/assembly/AssemblyIT.java deleted file mode 100644 index f4392f859..000000000 --- a/karaf-assembly/src/test/java/de/fhg/aisec/ids/assembly/AssemblyIT.java +++ /dev/null @@ -1,112 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * karaf-assembly - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.assembly; - -import de.fhg.aisec.ids.api.conm.ConnectionManager; -import de.fhg.aisec.ids.api.settings.ConnectorConfig; -import de.fhg.aisec.ids.api.settings.Settings; -import org.apache.karaf.itests.KarafTestSupport; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.ops4j.pax.exam.Configuration; -import org.ops4j.pax.exam.Option; -import org.ops4j.pax.exam.junit.PaxExam; -import org.ops4j.pax.exam.karaf.options.KarafDistributionBaseConfigurationOption; -import org.ops4j.pax.exam.karaf.options.KarafDistributionOption; -import org.ops4j.pax.exam.karaf.options.LogLevelOption; -import org.ops4j.pax.exam.options.MavenArtifactUrlReference; -import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy; -import org.ops4j.pax.exam.spi.reactors.PerClass; -import org.ops4j.pax.exam.util.Filter; - -import javax.inject.Inject; -import java.io.File; -import java.net.MalformedURLException; -import java.util.Arrays; -import java.util.LinkedList; - -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNotNull; - -@RunWith(PaxExam.class) -@ExamReactorStrategy(PerClass.class) -public class AssemblyIT extends KarafTestSupport { - - @Inject - @Filter(timeout = 30000) - private ConnectionManager connectionManager; - - @Inject - @Filter(timeout = 30000) - private Settings settings; - - @Override - public MavenArtifactUrlReference getKarafDistribution() { - return new MavenArtifactUrlReference() { - @Override - public String getURL() { - try { - return new File("build/karaf-assembly-" + System.getProperty("project.version") + ".tar.gz") - .toURI().toURL().toString(); - } catch (MalformedURLException e) { - throw new RuntimeException(e); - } - } - }; - } - - @Configuration - public Option[] config() { - final var options = new LinkedList<>(Arrays.asList(super.config())); - // Modify distribution config - ((KarafDistributionBaseConfigurationOption) options.get(0)) - .unpackDirectory(new File("build/exam")) - .useDeployFolder(false); - // Fix log level - options.replaceAll(o -> { - if (o instanceof LogLevelOption) { - return KarafDistributionOption.logLevel(LogLevelOption.LogLevel.TRACE); - } else { - return o; - } - }); - return options.toArray(new Option[0]); - } - - @Test - public void testSettings() { - ConnectorConfig cc = settings.getConnectorConfig(); - assertNotNull(cc); - assertNotNull(cc.getAppstoreUrl()); - assertNotNull(cc.getAcmeDnsWebcon()); - assertNotEquals(0, cc.getAcmePortWebcon()); - assertNotNull(cc.getAcmeServerWebcon()); - assertNotNull(cc.getAppstoreUrl()); - assertNotNull(cc.getBrokerUrl()); - assertNotNull(cc.getTtpHost()); - } - - @Test - public void testConnectionManager() { - assertNotNull(connectionManager.listAvailableEndpoints()); - assertNotNull(connectionManager.listIncomingConnections()); - assertNotNull(connectionManager.listOutgoingConnections()); - } -} diff --git a/karaf-assembly/system/index.xml b/karaf-assembly/system/index.xml deleted file mode 100644 index 1393b6a8f..000000000 --- a/karaf-assembly/system/index.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/karaf-assembly/system/index.xml.sha b/karaf-assembly/system/index.xml.sha deleted file mode 100644 index 7329e1e8f..000000000 --- a/karaf-assembly/system/index.xml.sha +++ /dev/null @@ -1 +0,0 @@ -3226ce12d80ddc00c2e0461d10ed95395caa84e0bcfce0a334886a4ee149ff28 \ No newline at end of file diff --git a/libraryVersions.yaml b/libraryVersions.yaml index a2c3ff6cb..442d25bdc 100644 --- a/libraryVersions.yaml +++ b/libraryVersions.yaml @@ -1,4 +1,7 @@ -idscp2: "0.4.3" +idscp2: "0.4.2" +ktlint: "0.41.0" + +# Pinning okhttp: "4.9.1" # Kotlin library/compiler version diff --git a/settings.gradle.kts b/settings.gradle.kts index 363383dcb..347414cae 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -2,11 +2,11 @@ rootProject.name = "trusted-connector-core" include(":camel-influxdb") include(":camel-multipart-processor") -//include(":ids-acme") +// include(":ids-acme") include(":ids-api") include(":ids-container-manager") include(":ids-dataflow-control") -//include(":ids-dynamic-tls") +// include(":ids-dynamic-tls") include(":ids-endpoint-config") include(":ids-infomodel-manager") include(":ids-route-manager") @@ -17,4 +17,3 @@ include(":ids-connector") // will be extracted to a separate repository later include(":example-idscp2-client-server") - From b0716b776809a6fa8d10df3eb11c838db73e2be7 Mon Sep 17 00:00:00 2001 From: Christian Banse Date: Fri, 30 Apr 2021 16:51:19 +0200 Subject: [PATCH 13/54] BootRun of Example works --- .../de/fhg/aisec/ids/ExampleIdscpClient.kt | 18 +++++++++++++++--- .../de/fhg/aisec/ids/ExampleIdscpServer.kt | 16 ++++++++++++++-- .../etc/consumer-core-protocol-test.p12 | Bin 0 -> 2709 bytes .../etc/provider-core-protocol-test.p12 | Bin 0 -> 2709 bytes ids-connector/build.gradle.kts | 8 ++++++++ 5 files changed, 37 insertions(+), 5 deletions(-) create mode 100644 example-idscp2-client-server/src/main/resources/etc/consumer-core-protocol-test.p12 create mode 100644 example-idscp2-client-server/src/main/resources/etc/provider-core-protocol-test.p12 diff --git a/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpClient.kt b/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpClient.kt index f2a879484..e13f8f85c 100644 --- a/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpClient.kt +++ b/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpClient.kt @@ -27,6 +27,7 @@ import org.apache.camel.support.jsse.SSLContextParameters import org.apache.camel.support.jsse.TrustManagersParameters import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration +import java.io.File import java.nio.file.FileSystems @Configuration @@ -39,12 +40,23 @@ open class ExampleIdscpClient { ctx.keyManagers = KeyManagersParameters() ctx.keyManagers.keyStore = KeyStoreParameters() ctx.keyManagers.keyStore.resource = - FileSystems.getDefault().getPath("etc", "provider-keystore.p12").toFile().path + File( + Thread.currentThread() + .contextClassLoader + .getResource("etc/consumer-core-protocol-test.p12") + .path + ) + .path ctx.keyManagers.keyStore.password = "password" ctx.trustManagers = TrustManagersParameters() ctx.trustManagers.keyStore = KeyStoreParameters() ctx.trustManagers.keyStore.resource = - FileSystems.getDefault().getPath("etc", "truststore.p12").toFile().path + File( + Thread.currentThread() + .contextClassLoader + .getResource("etc/truststore.p12") + .path + ).path ctx.trustManagers.keyStore.password = "password" return ctx @@ -58,7 +70,7 @@ open class ExampleIdscpClient { .setBody().simple("PING") .setHeader("idscp2-header").simple("ping") .log("Client sends: \${body} (Header: \${headers[idscp2-header]})") - .to("idscp2client://consumer-core:29292?awaitResponse=true&sslContextParameters=#clientSslContext") + .to("idscp2client://127.0.0.1:29292?awaitResponse=true&sslContextParameters=#clientSslContext") .log("Client received: \${body} (Header: \${headers[idscp2-header]})") .removeHeader("idscp2-header") // Prevents client consumer from sending the message back to the server .setBody().simple("\${null}") diff --git a/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpServer.kt b/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpServer.kt index c4358c4a2..ec1732da3 100644 --- a/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpServer.kt +++ b/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpServer.kt @@ -27,6 +27,7 @@ import org.apache.camel.support.jsse.SSLContextParameters import org.apache.camel.support.jsse.TrustManagersParameters import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration +import java.io.File import java.nio.file.FileSystems @Configuration @@ -39,12 +40,23 @@ open class ExampleIdscpServer { ctx.keyManagers = KeyManagersParameters() ctx.keyManagers.keyStore = KeyStoreParameters() ctx.keyManagers.keyStore.resource = - FileSystems.getDefault().getPath("etc", "consumer-keystore.p12").toFile().path + File( + Thread.currentThread() + .contextClassLoader + .getResource("etc/consumer-core-protocol-test.p12") + .path + ) + .path ctx.keyManagers.keyStore.password = "password" ctx.trustManagers = TrustManagersParameters() ctx.trustManagers.keyStore = KeyStoreParameters() ctx.trustManagers.keyStore.resource = - FileSystems.getDefault().getPath("etc", "truststore.p12").toFile().path + File( + Thread.currentThread() + .contextClassLoader + .getResource("etc/truststore.p12") + .path + ).path ctx.trustManagers.keyStore.password = "password" return ctx diff --git a/example-idscp2-client-server/src/main/resources/etc/consumer-core-protocol-test.p12 b/example-idscp2-client-server/src/main/resources/etc/consumer-core-protocol-test.p12 new file mode 100644 index 0000000000000000000000000000000000000000..b9022b7f7b58878a01de63efdf91d0df67d3e00d GIT binary patch literal 2709 zcmV;G3TpK*f(nrW0Ru3C3ReaRDuzgg_YDCD0ic2kNCbikL@M3t zMH4m#0s;sCfPw_D1jn0KTM5L?cD$TEiH*GiT%7LX$$K5YWT3$BM{QQ!UXf65UZmKO znKc*^mEH!eqQ!n{@YC#^!6EdTAHKr9rmEJoeyR~Up(B>SK6I+sibm*N=H+&>`g87O zSO7D}Ie^D0nvxy7fgn=CF9&cA2>02ZoPP2Lv&L9Q<;;Vx$kyoDNf2;Iqwch$fhALw z&W%rZJ5lB@D&%-h=Fw!%oU&HmD~M<XlYK`Qo z1r*r;)$}qyxy3P(MF!?J1XZSmAjM2zJN)}2_cQ1PNO8)0qy>t(Zj%y<=F}%ukI8NCE;3X?cHnLS
-3?R$*)FBmO3H&PfaLGrXlZSY>& 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 P6LsbnYPsWf0s;sC@3->f literal 0 HcmV?d00001 diff --git a/ids-connector/build.gradle.kts b/ids-connector/build.gradle.kts index f24b84f54..ed998c803 100644 --- a/ids-connector/build.gradle.kts +++ b/ids-connector/build.gradle.kts @@ -12,6 +12,14 @@ plugins { kotlin("plugin.spring") } +tasks.withType { + enabled = true +} + +tasks.withType { + classifier = "boot" +} + apply(plugin = "idea") buildConfig { From 9c4e59ff359af4645f40ca979625c7cd8900c4ea Mon Sep 17 00:00:00 2001 From: "Banse, Christian" Date: Fri, 30 Apr 2021 17:24:44 +0200 Subject: [PATCH 14/54] spotless apply --- .../de/fhg/aisec/ids/ExampleIdscpClient.kt | 1 - .../de/fhg/aisec/ids/ExampleIdscpServer.kt | 19 +++++++++---------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpClient.kt b/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpClient.kt index e13f8f85c..a0404a257 100644 --- a/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpClient.kt +++ b/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpClient.kt @@ -28,7 +28,6 @@ import org.apache.camel.support.jsse.TrustManagersParameters import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration import java.io.File -import java.nio.file.FileSystems @Configuration open class ExampleIdscpClient { diff --git a/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpServer.kt b/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpServer.kt index ec1732da3..7acb8d03b 100644 --- a/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpServer.kt +++ b/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpServer.kt @@ -7,9 +7,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -28,7 +28,6 @@ import org.apache.camel.support.jsse.TrustManagersParameters import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration import java.io.File -import java.nio.file.FileSystems @Configuration open class ExampleIdscpServer { @@ -40,13 +39,13 @@ open class ExampleIdscpServer { ctx.keyManagers = KeyManagersParameters() ctx.keyManagers.keyStore = KeyStoreParameters() ctx.keyManagers.keyStore.resource = - File( - Thread.currentThread() - .contextClassLoader - .getResource("etc/consumer-core-protocol-test.p12") - .path - ) - .path + File( + Thread.currentThread() + .contextClassLoader + .getResource("etc/consumer-core-protocol-test.p12") + .path + ) + .path ctx.keyManagers.keyStore.password = "password" ctx.trustManagers = TrustManagersParameters() ctx.trustManagers.keyStore = KeyStoreParameters() From 71ee2091b9462e2274ac3c4e29defbe33aac9544 Mon Sep 17 00:00:00 2001 From: "Banse, Christian" Date: Fri, 30 Apr 2021 17:39:44 +0200 Subject: [PATCH 15/54] back to consumer-core/provider-core certs --- .../src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpClient.kt | 5 +++-- .../src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpServer.kt | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpClient.kt b/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpClient.kt index a0404a257..808ea0e48 100644 --- a/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpClient.kt +++ b/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpClient.kt @@ -42,7 +42,8 @@ open class ExampleIdscpClient { File( Thread.currentThread() .contextClassLoader - .getResource("etc/consumer-core-protocol-test.p12") + //.getResource("etc/provider-core-protocol-test.p12") + .getResource("etc/provider-keystore.p12") .path ) .path @@ -69,7 +70,7 @@ open class ExampleIdscpClient { .setBody().simple("PING") .setHeader("idscp2-header").simple("ping") .log("Client sends: \${body} (Header: \${headers[idscp2-header]})") - .to("idscp2client://127.0.0.1:29292?awaitResponse=true&sslContextParameters=#clientSslContext") + .to("idscp2client://consumer-core:29292?awaitResponse=true&sslContextParameters=#clientSslContext") .log("Client received: \${body} (Header: \${headers[idscp2-header]})") .removeHeader("idscp2-header") // Prevents client consumer from sending the message back to the server .setBody().simple("\${null}") diff --git a/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpServer.kt b/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpServer.kt index 7acb8d03b..e47db6176 100644 --- a/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpServer.kt +++ b/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpServer.kt @@ -42,7 +42,8 @@ open class ExampleIdscpServer { File( Thread.currentThread() .contextClassLoader - .getResource("etc/consumer-core-protocol-test.p12") + //.getResource("etc/consumer-core-protocol-test.p12") + .getResource("etc/consumer-keystore.p12") .path ) .path From 7a8302402f3f5d95ef8f6993378586a70ab0ef73 Mon Sep 17 00:00:00 2001 From: "Banse, Christian" Date: Tue, 4 May 2021 14:52:28 +0200 Subject: [PATCH 16/54] Fixed spotless --- .../src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpClient.kt | 2 +- .../src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpServer.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpClient.kt b/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpClient.kt index 808ea0e48..2de3ea8c7 100644 --- a/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpClient.kt +++ b/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpClient.kt @@ -42,7 +42,7 @@ open class ExampleIdscpClient { File( Thread.currentThread() .contextClassLoader - //.getResource("etc/provider-core-protocol-test.p12") + // .getResource("etc/provider-core-protocol-test.p12") .getResource("etc/provider-keystore.p12") .path ) diff --git a/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpServer.kt b/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpServer.kt index e47db6176..cba4d54f1 100644 --- a/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpServer.kt +++ b/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpServer.kt @@ -42,7 +42,7 @@ open class ExampleIdscpServer { File( Thread.currentThread() .contextClassLoader - //.getResource("etc/consumer-core-protocol-test.p12") + // .getResource("etc/consumer-core-protocol-test.p12") .getResource("etc/consumer-keystore.p12") .path ) From 983c59d08bf40c21eaacaf149b47411d1707a1b3 Mon Sep 17 00:00:00 2001 From: Jason Desktop Date: Tue, 4 May 2021 15:25:55 +0200 Subject: [PATCH 17/54] Local Loop Conversion --- .../example-idscp2-localloop.xml | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/examples/example-getting-started/example-idscp2-localloop.xml b/examples/example-getting-started/example-idscp2-localloop.xml index d7a35dc99..811f76606 100644 --- a/examples/example-getting-started/example-idscp2-localloop.xml +++ b/examples/example-getting-started/example-idscp2-localloop.xml @@ -1,9 +1,14 @@ - + @@ -26,7 +31,7 @@ - + @@ -44,4 +49,4 @@ - + From b22349e65fd4b0216e89bbb648217ff6710e0467 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Tue, 4 May 2021 15:39:41 +0200 Subject: [PATCH 18/54] Reverted/Fixed path resolving, see README.md --- example-idscp2-client-server/README.md | 7 ++++++ .../etc/consumer-core-protocol-test.p12 | Bin .../resources => }/etc/consumer-keystore.p12 | Bin .../etc/provider-core-protocol-test.p12 | Bin .../resources => }/etc/provider-keystore.p12 | Bin .../main/resources => }/etc/settings.mapdb | Bin .../main/resources => }/etc/truststore.p12 | Bin .../de/fhg/aisec/ids/ExampleIdscpClient.kt | 18 +++----------- .../de/fhg/aisec/ids/ExampleIdscpServer.kt | 22 ++++-------------- 9 files changed, 15 insertions(+), 32 deletions(-) create mode 100644 example-idscp2-client-server/README.md rename example-idscp2-client-server/{src/main/resources => }/etc/consumer-core-protocol-test.p12 (100%) rename example-idscp2-client-server/{src/main/resources => }/etc/consumer-keystore.p12 (100%) rename example-idscp2-client-server/{src/main/resources => }/etc/provider-core-protocol-test.p12 (100%) rename example-idscp2-client-server/{src/main/resources => }/etc/provider-keystore.p12 (100%) rename example-idscp2-client-server/{src/main/resources => }/etc/settings.mapdb (100%) rename example-idscp2-client-server/{src/main/resources => }/etc/truststore.p12 (100%) diff --git a/example-idscp2-client-server/README.md b/example-idscp2-client-server/README.md new file mode 100644 index 000000000..43e2c7836 --- /dev/null +++ b/example-idscp2-client-server/README.md @@ -0,0 +1,7 @@ +## Example Usage + +In order to launch this example with proper path resolving for certificates and settings database, +execute as follows: + +- `cd` into this directory +- Run `../gradlew bootRun` to start the example, using this directory as working directory \ No newline at end of file diff --git a/example-idscp2-client-server/src/main/resources/etc/consumer-core-protocol-test.p12 b/example-idscp2-client-server/etc/consumer-core-protocol-test.p12 similarity index 100% rename from example-idscp2-client-server/src/main/resources/etc/consumer-core-protocol-test.p12 rename to example-idscp2-client-server/etc/consumer-core-protocol-test.p12 diff --git a/example-idscp2-client-server/src/main/resources/etc/consumer-keystore.p12 b/example-idscp2-client-server/etc/consumer-keystore.p12 similarity index 100% rename from example-idscp2-client-server/src/main/resources/etc/consumer-keystore.p12 rename to example-idscp2-client-server/etc/consumer-keystore.p12 diff --git a/example-idscp2-client-server/src/main/resources/etc/provider-core-protocol-test.p12 b/example-idscp2-client-server/etc/provider-core-protocol-test.p12 similarity index 100% rename from example-idscp2-client-server/src/main/resources/etc/provider-core-protocol-test.p12 rename to example-idscp2-client-server/etc/provider-core-protocol-test.p12 diff --git a/example-idscp2-client-server/src/main/resources/etc/provider-keystore.p12 b/example-idscp2-client-server/etc/provider-keystore.p12 similarity index 100% rename from example-idscp2-client-server/src/main/resources/etc/provider-keystore.p12 rename to example-idscp2-client-server/etc/provider-keystore.p12 diff --git a/example-idscp2-client-server/src/main/resources/etc/settings.mapdb b/example-idscp2-client-server/etc/settings.mapdb similarity index 100% rename from example-idscp2-client-server/src/main/resources/etc/settings.mapdb rename to example-idscp2-client-server/etc/settings.mapdb diff --git a/example-idscp2-client-server/src/main/resources/etc/truststore.p12 b/example-idscp2-client-server/etc/truststore.p12 similarity index 100% rename from example-idscp2-client-server/src/main/resources/etc/truststore.p12 rename to example-idscp2-client-server/etc/truststore.p12 diff --git a/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpClient.kt b/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpClient.kt index 2de3ea8c7..f2a879484 100644 --- a/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpClient.kt +++ b/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpClient.kt @@ -27,7 +27,7 @@ import org.apache.camel.support.jsse.SSLContextParameters import org.apache.camel.support.jsse.TrustManagersParameters import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration -import java.io.File +import java.nio.file.FileSystems @Configuration open class ExampleIdscpClient { @@ -39,24 +39,12 @@ open class ExampleIdscpClient { ctx.keyManagers = KeyManagersParameters() ctx.keyManagers.keyStore = KeyStoreParameters() ctx.keyManagers.keyStore.resource = - File( - Thread.currentThread() - .contextClassLoader - // .getResource("etc/provider-core-protocol-test.p12") - .getResource("etc/provider-keystore.p12") - .path - ) - .path + FileSystems.getDefault().getPath("etc", "provider-keystore.p12").toFile().path ctx.keyManagers.keyStore.password = "password" ctx.trustManagers = TrustManagersParameters() ctx.trustManagers.keyStore = KeyStoreParameters() ctx.trustManagers.keyStore.resource = - File( - Thread.currentThread() - .contextClassLoader - .getResource("etc/truststore.p12") - .path - ).path + FileSystems.getDefault().getPath("etc", "truststore.p12").toFile().path ctx.trustManagers.keyStore.password = "password" return ctx diff --git a/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpServer.kt b/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpServer.kt index cba4d54f1..c4358c4a2 100644 --- a/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpServer.kt +++ b/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpServer.kt @@ -7,9 +7,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -27,7 +27,7 @@ import org.apache.camel.support.jsse.SSLContextParameters import org.apache.camel.support.jsse.TrustManagersParameters import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration -import java.io.File +import java.nio.file.FileSystems @Configuration open class ExampleIdscpServer { @@ -39,24 +39,12 @@ open class ExampleIdscpServer { ctx.keyManagers = KeyManagersParameters() ctx.keyManagers.keyStore = KeyStoreParameters() ctx.keyManagers.keyStore.resource = - File( - Thread.currentThread() - .contextClassLoader - // .getResource("etc/consumer-core-protocol-test.p12") - .getResource("etc/consumer-keystore.p12") - .path - ) - .path + FileSystems.getDefault().getPath("etc", "consumer-keystore.p12").toFile().path ctx.keyManagers.keyStore.password = "password" ctx.trustManagers = TrustManagersParameters() ctx.trustManagers.keyStore = KeyStoreParameters() ctx.trustManagers.keyStore.resource = - File( - Thread.currentThread() - .contextClassLoader - .getResource("etc/truststore.p12") - .path - ).path + FileSystems.getDefault().getPath("etc", "truststore.p12").toFile().path ctx.trustManagers.keyStore.password = "password" return ctx From 3caae33396f9e94a003bcddca29ee034ec4c3d6a Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Tue, 4 May 2021 15:40:45 +0200 Subject: [PATCH 19/54] Minor change to avoid deprecated "classifier" value --- ids-connector/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ids-connector/build.gradle.kts b/ids-connector/build.gradle.kts index ed998c803..b3ea87d9f 100644 --- a/ids-connector/build.gradle.kts +++ b/ids-connector/build.gradle.kts @@ -17,7 +17,7 @@ tasks.withType { } tasks.withType { - classifier = "boot" + archiveClassifier.set("boot") } apply(plugin = "idea") From b0e5551c477abca64f33e55aa6d475b516d91204 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Tue, 4 May 2021 15:43:13 +0200 Subject: [PATCH 20/54] Added description to example README --- example-idscp2-client-server/README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/example-idscp2-client-server/README.md b/example-idscp2-client-server/README.md index 43e2c7836..fa7bd81b7 100644 --- a/example-idscp2-client-server/README.md +++ b/example-idscp2-client-server/README.md @@ -1,3 +1,8 @@ +## Description + +This subproject shows an example connector launch that is using the RouteBuilder pattern of +Apache Camel to create the message flow that is also found in `examples/example-getting-started`. + ## Example Usage In order to launch this example with proper path resolving for certificates and settings database, From 87e3d055c580df274193ce922145c74f7e16e4af Mon Sep 17 00:00:00 2001 From: Jason Desktop Date: Tue, 4 May 2021 15:38:20 +0200 Subject: [PATCH 21/54] Conversion of the Rest to Spring --- .../example-idscp2-client.xml | 20 +++++++++++-------- .../example-idscp2-server.xml | 20 +++++++++++-------- .../example-idscp2-client-broadcast.xml | 20 +++++++++++-------- .../example-idscp2/example-idscp2-client.xml | 19 +++++++++++------- .../example-idscp2-server-broadcast.xml | 20 +++++++++++-------- .../example-idscp2/example-idscp2-server.xml | 20 +++++++++++-------- examples/route-examples/demo-route.xml | 20 +++++++++++-------- .../example-idscp2-client-broadcast.xml | 20 +++++++++++-------- .../route-examples/example-idscp2-client.xml | 20 +++++++++++-------- .../example-idscp2-server-broadcast.xml | 20 +++++++++++-------- .../route-examples/example-idscp2-server.xml | 20 +++++++++++-------- .../ids-multipart-echo-route.xml | 20 +++++++++++-------- .../route-examples/ids-multipart-route.xml | 20 +++++++++++-------- 13 files changed, 156 insertions(+), 103 deletions(-) diff --git a/examples/example-idscp2-uc/example-idscp2-client.xml b/examples/example-idscp2-uc/example-idscp2-client.xml index c75908056..f51dc3649 100644 --- a/examples/example-idscp2-uc/example-idscp2-client.xml +++ b/examples/example-idscp2-uc/example-idscp2-client.xml @@ -1,9 +1,14 @@ - + @@ -19,8 +24,7 @@ - - + @@ -67,4 +71,4 @@ - + \ No newline at end of file diff --git a/examples/example-idscp2-uc/example-idscp2-server.xml b/examples/example-idscp2-uc/example-idscp2-server.xml index 94db29984..3ab2e3794 100644 --- a/examples/example-idscp2-uc/example-idscp2-server.xml +++ b/examples/example-idscp2-uc/example-idscp2-server.xml @@ -1,9 +1,14 @@ - + @@ -19,8 +24,7 @@ - - + @@ -56,4 +60,4 @@ - + \ No newline at end of file diff --git a/examples/example-idscp2/example-idscp2-client-broadcast.xml b/examples/example-idscp2/example-idscp2-client-broadcast.xml index b080f3821..44cc1222b 100644 --- a/examples/example-idscp2/example-idscp2-client-broadcast.xml +++ b/examples/example-idscp2/example-idscp2-client-broadcast.xml @@ -1,9 +1,14 @@ - + @@ -14,8 +19,7 @@ - - + @@ -28,4 +32,4 @@ - + \ No newline at end of file diff --git a/examples/example-idscp2/example-idscp2-client.xml b/examples/example-idscp2/example-idscp2-client.xml index e005090a5..9542e7dfd 100644 --- a/examples/example-idscp2/example-idscp2-client.xml +++ b/examples/example-idscp2/example-idscp2-client.xml @@ -1,9 +1,14 @@ - + @@ -14,7 +19,7 @@ - + @@ -36,4 +41,4 @@ - + \ No newline at end of file diff --git a/examples/example-idscp2/example-idscp2-server-broadcast.xml b/examples/example-idscp2/example-idscp2-server-broadcast.xml index 097ddf003..01f544712 100644 --- a/examples/example-idscp2/example-idscp2-server-broadcast.xml +++ b/examples/example-idscp2/example-idscp2-server-broadcast.xml @@ -1,9 +1,14 @@ - + @@ -14,8 +19,7 @@ - - + @@ -30,4 +34,4 @@ - + \ No newline at end of file diff --git a/examples/example-idscp2/example-idscp2-server.xml b/examples/example-idscp2/example-idscp2-server.xml index 9114d41d2..5d0422158 100644 --- a/examples/example-idscp2/example-idscp2-server.xml +++ b/examples/example-idscp2/example-idscp2-server.xml @@ -1,9 +1,14 @@ - + @@ -14,8 +19,7 @@ - - + @@ -30,4 +34,4 @@ - + \ No newline at end of file diff --git a/examples/route-examples/demo-route.xml b/examples/route-examples/demo-route.xml index bedb85a63..5f7e1f4ab 100644 --- a/examples/route-examples/demo-route.xml +++ b/examples/route-examples/demo-route.xml @@ -1,9 +1,14 @@ - + @@ -26,8 +31,7 @@ - - + @@ -169,4 +173,4 @@ - + diff --git a/examples/route-examples/example-idscp2-client-broadcast.xml b/examples/route-examples/example-idscp2-client-broadcast.xml index 20263637c..9b6636d06 100644 --- a/examples/route-examples/example-idscp2-client-broadcast.xml +++ b/examples/route-examples/example-idscp2-client-broadcast.xml @@ -1,9 +1,14 @@ - + @@ -14,8 +19,7 @@ - - + @@ -25,4 +29,4 @@ - + \ No newline at end of file diff --git a/examples/route-examples/example-idscp2-client.xml b/examples/route-examples/example-idscp2-client.xml index 637511eda..e4243077f 100644 --- a/examples/route-examples/example-idscp2-client.xml +++ b/examples/route-examples/example-idscp2-client.xml @@ -1,9 +1,14 @@ - + @@ -14,8 +19,7 @@ - - + @@ -37,4 +41,4 @@ - + \ No newline at end of file diff --git a/examples/route-examples/example-idscp2-server-broadcast.xml b/examples/route-examples/example-idscp2-server-broadcast.xml index 7a57ca681..b7815e47f 100644 --- a/examples/route-examples/example-idscp2-server-broadcast.xml +++ b/examples/route-examples/example-idscp2-server-broadcast.xml @@ -1,9 +1,14 @@ - + @@ -14,8 +19,7 @@ - - + @@ -30,4 +34,4 @@ - + diff --git a/examples/route-examples/example-idscp2-server.xml b/examples/route-examples/example-idscp2-server.xml index eca646e31..9dc46354e 100644 --- a/examples/route-examples/example-idscp2-server.xml +++ b/examples/route-examples/example-idscp2-server.xml @@ -1,9 +1,14 @@ - + @@ -14,8 +19,7 @@ - - + @@ -30,4 +34,4 @@ - + \ No newline at end of file diff --git a/examples/route-examples/ids-multipart-echo-route.xml b/examples/route-examples/ids-multipart-echo-route.xml index e19163e55..0b622e7a5 100644 --- a/examples/route-examples/ids-multipart-echo-route.xml +++ b/examples/route-examples/ids-multipart-echo-route.xml @@ -1,17 +1,21 @@ - + - - + @@ -43,4 +47,4 @@ - + diff --git a/examples/route-examples/ids-multipart-route.xml b/examples/route-examples/ids-multipart-route.xml index 7d7c143a1..651119ad4 100644 --- a/examples/route-examples/ids-multipart-route.xml +++ b/examples/route-examples/ids-multipart-route.xml @@ -1,17 +1,21 @@ - + - - + @@ -41,4 +45,4 @@ - + From b9b97b5838ff461e2e4d7f931052c8250db33852 Mon Sep 17 00:00:00 2001 From: Christian Banse Date: Tue, 4 May 2021 18:05:36 +0200 Subject: [PATCH 22/54] Small change to execute spotlessApply during build This will ensure spotless compliant code in most cases, since most IDEs, such as IntelliJ uses the `build` task to build and this will automatically invoke `spotlessApply` on build. --- build.gradle.kts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build.gradle.kts b/build.gradle.kts index 2120cee17..67aaf4f39 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -62,6 +62,7 @@ subprojects { apply(plugin = "java-library") apply(plugin = "org.jetbrains.kotlin.jvm") apply(plugin = "io.spring.dependency-management") + apply(plugin = "com.diffplug.spotless") configure { imports { @@ -149,6 +150,7 @@ subprojects { options.encoding = "UTF-8" options.compilerArgs.add("-Xlint:unchecked") // options.isDeprecation = true + dependsOn("spotlessApply") } tasks.jar { From 14e72991b8b6c99195b25687f7ee9172a1c879ca Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Thu, 6 May 2021 14:24:54 +0200 Subject: [PATCH 23/54] Spring XML cleanup --- .../example-getting-started/example-idscp2-localloop.xml | 5 +---- examples/example-idscp2-uc/example-idscp2-client.xml | 5 +---- examples/example-idscp2-uc/example-idscp2-server.xml | 5 +---- examples/example-idscp2/example-idscp2-client-broadcast.xml | 5 +---- examples/example-idscp2/example-idscp2-client.xml | 5 +---- examples/example-idscp2/example-idscp2-server-broadcast.xml | 5 +---- examples/example-idscp2/example-idscp2-server.xml | 6 ++---- examples/route-examples/demo-route.xml | 5 +---- examples/route-examples/example-idscp2-client-broadcast.xml | 5 +---- examples/route-examples/example-idscp2-client.xml | 5 +---- examples/route-examples/example-idscp2-server-broadcast.xml | 5 +---- examples/route-examples/example-idscp2-server.xml | 5 +---- examples/route-examples/ids-multipart-echo-route.xml | 6 +----- examples/route-examples/ids-multipart-route.xml | 6 +----- 14 files changed, 15 insertions(+), 58 deletions(-) diff --git a/examples/example-getting-started/example-idscp2-localloop.xml b/examples/example-getting-started/example-idscp2-localloop.xml index 811f76606..f37e3c78d 100644 --- a/examples/example-getting-started/example-idscp2-localloop.xml +++ b/examples/example-getting-started/example-idscp2-localloop.xml @@ -2,13 +2,10 @@ + http://camel.apache.org/schema/spring/camel-spring.xsd"> diff --git a/examples/example-idscp2-uc/example-idscp2-client.xml b/examples/example-idscp2-uc/example-idscp2-client.xml index f51dc3649..d14474e7c 100644 --- a/examples/example-idscp2-uc/example-idscp2-client.xml +++ b/examples/example-idscp2-uc/example-idscp2-client.xml @@ -2,13 +2,10 @@ + http://camel.apache.org/schema/spring/camel-spring.xsd"> diff --git a/examples/example-idscp2-uc/example-idscp2-server.xml b/examples/example-idscp2-uc/example-idscp2-server.xml index 3ab2e3794..7171cabed 100644 --- a/examples/example-idscp2-uc/example-idscp2-server.xml +++ b/examples/example-idscp2-uc/example-idscp2-server.xml @@ -2,13 +2,10 @@ + http://camel.apache.org/schema/spring/camel-spring.xsd"> diff --git a/examples/example-idscp2/example-idscp2-client-broadcast.xml b/examples/example-idscp2/example-idscp2-client-broadcast.xml index 44cc1222b..48f2dabe5 100644 --- a/examples/example-idscp2/example-idscp2-client-broadcast.xml +++ b/examples/example-idscp2/example-idscp2-client-broadcast.xml @@ -2,13 +2,10 @@ + http://camel.apache.org/schema/spring/camel-spring.xsd"> diff --git a/examples/example-idscp2/example-idscp2-client.xml b/examples/example-idscp2/example-idscp2-client.xml index 9542e7dfd..13434cfe3 100644 --- a/examples/example-idscp2/example-idscp2-client.xml +++ b/examples/example-idscp2/example-idscp2-client.xml @@ -2,13 +2,10 @@ + http://camel.apache.org/schema/spring/camel-spring.xsd"> diff --git a/examples/example-idscp2/example-idscp2-server-broadcast.xml b/examples/example-idscp2/example-idscp2-server-broadcast.xml index 01f544712..24f4de528 100644 --- a/examples/example-idscp2/example-idscp2-server-broadcast.xml +++ b/examples/example-idscp2/example-idscp2-server-broadcast.xml @@ -2,13 +2,10 @@ + http://camel.apache.org/schema/spring/camel-spring.xsd"> diff --git a/examples/example-idscp2/example-idscp2-server.xml b/examples/example-idscp2/example-idscp2-server.xml index 5d0422158..2f0f92b9a 100644 --- a/examples/example-idscp2/example-idscp2-server.xml +++ b/examples/example-idscp2/example-idscp2-server.xml @@ -2,13 +2,10 @@ + http://camel.apache.org/schema/spring/camel-spring.xsd"> @@ -20,6 +17,7 @@ + diff --git a/examples/route-examples/demo-route.xml b/examples/route-examples/demo-route.xml index 5f7e1f4ab..6782accbc 100644 --- a/examples/route-examples/demo-route.xml +++ b/examples/route-examples/demo-route.xml @@ -2,13 +2,10 @@ + http://camel.apache.org/schema/spring/camel-spring.xsd"> diff --git a/examples/route-examples/example-idscp2-client-broadcast.xml b/examples/route-examples/example-idscp2-client-broadcast.xml index 9b6636d06..4ae5a16d6 100644 --- a/examples/route-examples/example-idscp2-client-broadcast.xml +++ b/examples/route-examples/example-idscp2-client-broadcast.xml @@ -2,13 +2,10 @@ + http://camel.apache.org/schema/spring/camel-spring.xsd"> diff --git a/examples/route-examples/example-idscp2-client.xml b/examples/route-examples/example-idscp2-client.xml index e4243077f..176071e22 100644 --- a/examples/route-examples/example-idscp2-client.xml +++ b/examples/route-examples/example-idscp2-client.xml @@ -2,13 +2,10 @@ + http://camel.apache.org/schema/spring/camel-spring.xsd"> diff --git a/examples/route-examples/example-idscp2-server-broadcast.xml b/examples/route-examples/example-idscp2-server-broadcast.xml index b7815e47f..c08df4372 100644 --- a/examples/route-examples/example-idscp2-server-broadcast.xml +++ b/examples/route-examples/example-idscp2-server-broadcast.xml @@ -2,13 +2,10 @@ + http://camel.apache.org/schema/spring/camel-spring.xsd"> diff --git a/examples/route-examples/example-idscp2-server.xml b/examples/route-examples/example-idscp2-server.xml index 9dc46354e..9a941b695 100644 --- a/examples/route-examples/example-idscp2-server.xml +++ b/examples/route-examples/example-idscp2-server.xml @@ -2,13 +2,10 @@ + http://camel.apache.org/schema/spring/camel-spring.xsd"> diff --git a/examples/route-examples/ids-multipart-echo-route.xml b/examples/route-examples/ids-multipart-echo-route.xml index 0b622e7a5..f43e39380 100644 --- a/examples/route-examples/ids-multipart-echo-route.xml +++ b/examples/route-examples/ids-multipart-echo-route.xml @@ -1,14 +1,10 @@ + http://camel.apache.org/schema/spring/camel-spring.xsd"> diff --git a/examples/route-examples/ids-multipart-route.xml b/examples/route-examples/ids-multipart-route.xml index 651119ad4..66f3d0a2e 100644 --- a/examples/route-examples/ids-multipart-route.xml +++ b/examples/route-examples/ids-multipart-route.xml @@ -1,14 +1,10 @@ + http://camel.apache.org/schema/spring/camel-spring.xsd"> From f552968e490c3369ca77ddd067f5a4905f9d494f Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Thu, 6 May 2021 14:25:54 +0200 Subject: [PATCH 24/54] XML deploy watcher implemented --- .../de/fhg/aisec/ids/rm/XmlDeployWatcher.kt | 114 ++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/XmlDeployWatcher.kt diff --git a/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/XmlDeployWatcher.kt b/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/XmlDeployWatcher.kt new file mode 100644 index 000000000..05b207e52 --- /dev/null +++ b/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/XmlDeployWatcher.kt @@ -0,0 +1,114 @@ +package de.fhg.aisec.ids.rm + +import org.slf4j.Logger +import org.slf4j.LoggerFactory +import org.springframework.context.support.AbstractXmlApplicationContext +import org.springframework.context.support.FileSystemXmlApplicationContext +import org.springframework.stereotype.Component +import java.nio.file.FileSystems +import java.nio.file.Files +import java.nio.file.Path +import java.nio.file.StandardWatchEventKinds +import java.nio.file.WatchKey +import java.util.concurrent.CompletableFuture + +@Component("xmlDeployWatcher") +class XmlDeployWatcher { + private val xmlContexts = mutableMapOf>() + + private fun startXmlApplicationContext(xmlPath: String) { + LOG.info("XML file {} detected, creating XmlApplicationContext...", xmlPath) + val xmlContextFuture: CompletableFuture = CompletableFuture.supplyAsync { + FileSystemXmlApplicationContext(xmlPath) + } + xmlContexts += xmlPath to xmlContextFuture + } + + private fun stopXmlApplicationContext(xmlPath: String) { + // If entry is in xmlContexts, remove it stop XmlApplicationContext + xmlContexts.remove(xmlPath)?.let { ctx -> + LOG.info("XML file {} deleted, stopping XmlApplicationContext...", xmlPath) + ctx.thenAccept { it.stop() } + } + } + + private fun restartXmlApplicationContext(xmlPath: String) { + xmlContexts.remove(xmlPath)?.let { ctx -> + LOG.info("XML file {} modified, restarting XmlApplicationContext...", xmlPath) + ctx.thenAccept { + it.stop() + val xmlContextFuture: CompletableFuture = CompletableFuture.supplyAsync { + FileSystemXmlApplicationContext(xmlPath) + } + xmlContexts += xmlPath to xmlContextFuture + } + } + } + + init { + val fs = FileSystems.getDefault() + val deployPath = fs.getPath("deploy") + Files.walk(deployPath) + .filter { Files.isRegularFile(it) && it.toString().endsWith(".xml") } + .forEach { startXmlApplicationContext(it.toString()) } + Thread( + { + val watcher = fs.newWatchService() + deployPath.register( + watcher, + StandardWatchEventKinds.ENTRY_CREATE, + StandardWatchEventKinds.ENTRY_DELETE, + StandardWatchEventKinds.ENTRY_MODIFY + ) + while (true) { + // Get watch key (blocking) to query file events + val key: WatchKey = try { + watcher.take() + } catch (x: InterruptedException) { + LOG.warn("Watcher stopped by interrupt") + break + } + // Poll the events that happened since last iteration + for (watchEvent in key.pollEvents()) { + try { + val xmlPath = deployPath.resolve(watchEvent.context() as Path) + val xmlPathString = xmlPath.toString() + when (watchEvent.kind()) { + StandardWatchEventKinds.ENTRY_CREATE -> { + // Must check whether the path represents a valid XML file + if (Files.isRegularFile(xmlPath) || xmlPathString.endsWith(".xml")) { + startXmlApplicationContext(xmlPathString) + } + } + StandardWatchEventKinds.ENTRY_DELETE -> { + stopXmlApplicationContext(xmlPathString) + } + StandardWatchEventKinds.ENTRY_MODIFY -> { + restartXmlApplicationContext(xmlPathString) + } + else -> { + LOG.warn("Unhandled WatchEvent: {}", watchEvent) + } + } + } catch (e: Exception) { + LOG.error("Error occurred in Deploy Watcher", e) + } + } + // Key must be reset for next iteration, if reset() returns false, key is invalid -> exit + if (!key.reset()) { + LOG.warn("Watcher stopped by failed reset()") + break + } + } + }, + "XML Deploy Folder Watcher" + ).run { + isDaemon = true + start() + } + } + + companion object { + val LOG: Logger = LoggerFactory.getLogger(XmlDeployWatcher::class.java) + } +} From c963ecbacffd94f7856396f7ad7597536b01dcd3 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Thu, 6 May 2021 14:31:14 +0200 Subject: [PATCH 25/54] Minor code cleanup --- .../src/main/kotlin/de/fhg/aisec/ids/ConnectorConfiguration.kt | 3 --- .../src/main/kotlin/de/fhg/aisec/ids/TrustedConnector.kt | 3 ++- .../main/kotlin/de/fhg/aisec/ids/settings/SettingsComponent.kt | 3 ++- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/ids-connector/src/main/kotlin/de/fhg/aisec/ids/ConnectorConfiguration.kt b/ids-connector/src/main/kotlin/de/fhg/aisec/ids/ConnectorConfiguration.kt index 2bfef6164..efa971121 100644 --- a/ids-connector/src/main/kotlin/de/fhg/aisec/ids/ConnectorConfiguration.kt +++ b/ids-connector/src/main/kotlin/de/fhg/aisec/ids/ConnectorConfiguration.kt @@ -35,11 +35,8 @@ import java.util.Arrays class ConnectorConfiguration { @Autowired(required = false) private var cml: ContainerManager? = null - @Autowired private lateinit var settings: Settings - @Autowired private lateinit var im: InfoModel - @Autowired private lateinit var rm: RouteManagerService @Bean diff --git a/ids-connector/src/main/kotlin/de/fhg/aisec/ids/TrustedConnector.kt b/ids-connector/src/main/kotlin/de/fhg/aisec/ids/TrustedConnector.kt index 501c5966f..cabc721ec 100644 --- a/ids-connector/src/main/kotlin/de/fhg/aisec/ids/TrustedConnector.kt +++ b/ids-connector/src/main/kotlin/de/fhg/aisec/ids/TrustedConnector.kt @@ -19,6 +19,7 @@ */ package de.fhg.aisec.ids +import org.slf4j.Logger import org.slf4j.LoggerFactory import org.springframework.boot.autoconfigure.SpringBootApplication import org.springframework.boot.runApplication @@ -29,7 +30,7 @@ class TrustedConnector { companion object { - val LOG = LoggerFactory.getLogger(TrustedConnector::class.java) + val LOG: Logger = LoggerFactory.getLogger(TrustedConnector::class.java) @JvmStatic fun main(args: Array) { diff --git a/ids-settings/src/main/kotlin/de/fhg/aisec/ids/settings/SettingsComponent.kt b/ids-settings/src/main/kotlin/de/fhg/aisec/ids/settings/SettingsComponent.kt index f09961040..41a47934f 100644 --- a/ids-settings/src/main/kotlin/de/fhg/aisec/ids/settings/SettingsComponent.kt +++ b/ids-settings/src/main/kotlin/de/fhg/aisec/ids/settings/SettingsComponent.kt @@ -28,12 +28,13 @@ import org.mapdb.DB import org.mapdb.DBMaker import org.mapdb.Serializer import org.slf4j.LoggerFactory +import org.springframework.stereotype.Component import java.nio.file.FileSystems import java.util.Collections import java.util.concurrent.ConcurrentMap import javax.annotation.PreDestroy -@org.springframework.stereotype.Component +@Component class SettingsComponent : Settings { init { From 0631ce6e0155e28fb07376abccd02dc3f1978223 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Mon, 10 May 2021 13:33:48 +0200 Subject: [PATCH 26/54] Begin Gradle 7.0 transition, minor code improvements --- build.gradle.kts | 8 ++--- gradle/wrapper/gradle-wrapper.properties | 2 +- ids-connector/build.gradle.kts | 25 ++++++++------ .../de/fhg/aisec/ids/rm/XmlDeployWatcher.kt | 34 +++++++++++++++---- libraryVersions.yaml | 2 +- 5 files changed, 49 insertions(+), 22 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 67aaf4f39..39c3cbff0 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,3 +1,4 @@ +import io.spring.gradle.dependencymanagement.dsl.DependencyManagementExtension import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.yaml.snakeyaml.Yaml @@ -13,7 +14,6 @@ repositories { plugins { java - maven // Spring Boot id("org.springframework.boot") version "2.3.4.RELEASE" apply false @@ -64,14 +64,14 @@ subprojects { apply(plugin = "io.spring.dependency-management") apply(plugin = "com.diffplug.spotless") - configure { + configure { imports { mavenBom("org.springframework.boot:spring-boot-dependencies:${libraryVersions["springBoot"]}") } imports { - // need to stick to 3.0 because of org.apache.camel.support.dump.RouteStatDump and ModelHelper - mavenBom("org.apache.camel.springboot:camel-spring-boot-dependencies:3.0.0") + // need to stick to 3.0.1 because of org.apache.camel.support.dump.RouteStatDump and ModelHelper + mavenBom("org.apache.camel.springboot:camel-spring-boot-dependencies:3.0.1") } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index be52383ef..f371643ee 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/ids-connector/build.gradle.kts b/ids-connector/build.gradle.kts index b3ea87d9f..afb58ec90 100644 --- a/ids-connector/build.gradle.kts +++ b/ids-connector/build.gradle.kts @@ -1,3 +1,5 @@ +// import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar +import org.gradle.plugins.ide.idea.model.IdeaModel import org.springframework.boot.gradle.tasks.bundling.BootJar @Suppress("UNCHECKED_CAST") @@ -7,6 +9,7 @@ plugins { application id("org.springframework.boot") id("com.github.gmazzo.buildconfig") version "2.0.2" + // id("com.github.johnrengelman.shadow") version "7.0.0" kotlin("jvm") kotlin("plugin.spring") @@ -17,9 +20,18 @@ tasks.withType { } tasks.withType { - archiveClassifier.set("boot") + archiveFileName.set("ids-connector.jar") + layered() +} + +configure { + mainClass.set("de.fhg.aisec.ids.TrustedConnector") } +// tasks.withType { +// archiveFileName.set("ids-connector.jar") +// } + apply(plugin = "idea") buildConfig { @@ -32,18 +44,13 @@ buildConfig { } } -configure { +configure { module { // mark as generated sources for IDEA generatedSourceDirs.add(File("$buildDir/generated/source/buildConfig/main/main")) } } -tasks.getByName("bootJar") { - launchScript() - layered() -} - dependencies { api(project(":ids-webconsole")) api(project(":ids-settings")) @@ -59,9 +66,7 @@ dependencies { implementation("org.apache.camel.springboot:camel-rest-starter") implementation("org.apache.camel.springboot:camel-http-starter") - implementation("de.fhg.aisec.ids", "camel-idscp2", libraryVersions["idscp2"]) { - exclude("org.slf4j", "slf4j-simple") // needed until https://github.com/industrial-data-space/idscp2-java/pull/4 is merged - } + implementation("de.fhg.aisec.ids", "camel-idscp2", libraryVersions["idscp2"]) // Spring Boot implementation("org.springframework.boot:spring-boot-starter") diff --git a/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/XmlDeployWatcher.kt b/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/XmlDeployWatcher.kt index 05b207e52..861d6e688 100644 --- a/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/XmlDeployWatcher.kt +++ b/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/XmlDeployWatcher.kt @@ -1,7 +1,28 @@ +/*- + * ========================LICENSE_START================================= + * ids-route-manager + * %% + * Copyright (C) 2021 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ package de.fhg.aisec.ids.rm import org.slf4j.Logger import org.slf4j.LoggerFactory +import org.springframework.boot.context.event.ApplicationReadyEvent +import org.springframework.context.event.EventListener import org.springframework.context.support.AbstractXmlApplicationContext import org.springframework.context.support.FileSystemXmlApplicationContext import org.springframework.stereotype.Component @@ -26,17 +47,17 @@ class XmlDeployWatcher { private fun stopXmlApplicationContext(xmlPath: String) { // If entry is in xmlContexts, remove it stop XmlApplicationContext - xmlContexts.remove(xmlPath)?.let { ctx -> + xmlContexts.remove(xmlPath)?.let { ctxFuture -> LOG.info("XML file {} deleted, stopping XmlApplicationContext...", xmlPath) - ctx.thenAccept { it.stop() } + ctxFuture.thenAccept { it.stop() } } } private fun restartXmlApplicationContext(xmlPath: String) { - xmlContexts.remove(xmlPath)?.let { ctx -> + xmlContexts.remove(xmlPath)?.let { ctxFuture -> LOG.info("XML file {} modified, restarting XmlApplicationContext...", xmlPath) - ctx.thenAccept { - it.stop() + ctxFuture.thenAccept { ctx -> + ctx.stop() val xmlContextFuture: CompletableFuture = CompletableFuture.supplyAsync { FileSystemXmlApplicationContext(xmlPath) } @@ -45,7 +66,8 @@ class XmlDeployWatcher { } } - init { + @EventListener(ApplicationReadyEvent::class) + private fun startXmlDeployWatcher() { val fs = FileSystems.getDefault() val deployPath = fs.getPath("deploy") Files.walk(deployPath) diff --git a/libraryVersions.yaml b/libraryVersions.yaml index 442d25bdc..2a0c32d0d 100644 --- a/libraryVersions.yaml +++ b/libraryVersions.yaml @@ -1,4 +1,4 @@ -idscp2: "0.4.2" +idscp2: "0.4.3" ktlint: "0.41.0" # Pinning From df1c7102f190507ba4d8f3d55f5bee09f79eb559 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Mon, 10 May 2021 14:28:44 +0200 Subject: [PATCH 27/54] Bumped spring and related dependencies --- build.gradle.kts | 7 +++---- libraryVersions.yaml | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 39c3cbff0..b8375cd49 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -16,8 +16,8 @@ plugins { java // Spring Boot - id("org.springframework.boot") version "2.3.4.RELEASE" apply false - id("io.spring.dependency-management") version "1.0.8.RELEASE" + id("org.springframework.boot") version "2.4.5" apply false + id("io.spring.dependency-management") version "1.0.11.RELEASE" // Other needed plugins id("com.moowork.node") version "1.3.1" apply false @@ -70,8 +70,7 @@ subprojects { } imports { - // need to stick to 3.0.1 because of org.apache.camel.support.dump.RouteStatDump and ModelHelper - mavenBom("org.apache.camel.springboot:camel-spring-boot-dependencies:3.0.1") + mavenBom("org.apache.camel.springboot:camel-spring-boot-dependencies:${libraryVersions["camel"]}") } } diff --git a/libraryVersions.yaml b/libraryVersions.yaml index 2a0c32d0d..b67da4f6e 100644 --- a/libraryVersions.yaml +++ b/libraryVersions.yaml @@ -98,4 +98,4 @@ awaitility: "3.1.6" servicemixHamcrest: "1.3_1" javaxAnnotation: "1.3.2" -springBoot: "2.3.4.RELEASE" \ No newline at end of file +springBoot: "2.4.5" \ No newline at end of file From 9b937df12941e52158f528e8bf713c378184bd4b Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Mon, 10 May 2021 16:58:17 +0200 Subject: [PATCH 28/54] Adapted example, added Dockerfile, some cleanup --- .../resources => examples}/etc/settings.mapdb | Bin .../docker-compose.yaml | 1 + ids-connector/Dockerfile | 30 ++++ ids-connector/build.gradle.kts | 27 +-- .../resources/deploy/flow-policy-example.pl | 45 ----- .../src/main/resources/etc/custom.properties | 41 ----- .../resources/etc/de.fhg.dfcontrol.rules.cfg | 5 - .../etc/idscp2/aisecconnector1-keystore.jks | Bin 2527 -> 0 bytes .../etc/idscp2/client-truststore_new.jks | Bin 1974 -> 0 bytes .../etc/import_ca_chain_into_keystore.sh | 10 -- .../src/main/resources/etc/jetty.xml | 91 ---------- .../org.apache.felix.fileinstall-deploy.cfg | 25 --- .../etc/org.apache.karaf.management.cfg | 112 ------------- .../resources/etc/org.ops4j.pax.logging.cfg | 102 ------------ .../resources/etc/org.ops4j.pax.url.mvn.cfg | 42 ----- .../main/resources/etc/org.ops4j.pax.web.cfg | 64 -------- .../src/main/resources/etc/system.properties | 155 ------------------ .../etc/tls-webconsole/keystore_latest.jks | Bin 5239 -> 0 bytes .../src/main/resources/etc/users.properties | 37 ----- ids-webconsole/build.gradle.kts | 5 +- runConnector.sh | 2 - 21 files changed, 49 insertions(+), 745 deletions(-) rename {ids-connector/src/main/resources => examples}/etc/settings.mapdb (100%) create mode 100644 ids-connector/Dockerfile delete mode 100644 ids-connector/src/main/resources/deploy/flow-policy-example.pl delete mode 100644 ids-connector/src/main/resources/etc/custom.properties delete mode 100644 ids-connector/src/main/resources/etc/de.fhg.dfcontrol.rules.cfg delete mode 100644 ids-connector/src/main/resources/etc/idscp2/aisecconnector1-keystore.jks delete mode 100644 ids-connector/src/main/resources/etc/idscp2/client-truststore_new.jks delete mode 100644 ids-connector/src/main/resources/etc/import_ca_chain_into_keystore.sh delete mode 100644 ids-connector/src/main/resources/etc/jetty.xml delete mode 100644 ids-connector/src/main/resources/etc/org.apache.felix.fileinstall-deploy.cfg delete mode 100644 ids-connector/src/main/resources/etc/org.apache.karaf.management.cfg delete mode 100644 ids-connector/src/main/resources/etc/org.ops4j.pax.logging.cfg delete mode 100644 ids-connector/src/main/resources/etc/org.ops4j.pax.url.mvn.cfg delete mode 100644 ids-connector/src/main/resources/etc/org.ops4j.pax.web.cfg delete mode 100644 ids-connector/src/main/resources/etc/system.properties delete mode 100644 ids-connector/src/main/resources/etc/tls-webconsole/keystore_latest.jks delete mode 100644 ids-connector/src/main/resources/etc/users.properties delete mode 100755 runConnector.sh diff --git a/ids-connector/src/main/resources/etc/settings.mapdb b/examples/etc/settings.mapdb similarity index 100% rename from ids-connector/src/main/resources/etc/settings.mapdb rename to examples/etc/settings.mapdb diff --git a/examples/example-getting-started/docker-compose.yaml b/examples/example-getting-started/docker-compose.yaml index 04b93c3e9..ca8e16f62 100644 --- a/examples/example-getting-started/docker-compose.yaml +++ b/examples/example-getting-started/docker-compose.yaml @@ -9,6 +9,7 @@ services: volumes: - ../log/:/root/log/ - /var/run/docker.sock:/var/run/docker.sock + - ../etc/settings.mapdb:/root/etc/settings.mapdb - ../cert-stores/consumer-keystore.p12:/root/etc/consumer-keystore.p12 - ../cert-stores/provider-keystore.p12:/root/etc/provider-keystore.p12 - ../cert-stores/truststore.p12:/root/etc/truststore.p12 diff --git a/ids-connector/Dockerfile b/ids-connector/Dockerfile new file mode 100644 index 000000000..06152e2f4 --- /dev/null +++ b/ids-connector/Dockerfile @@ -0,0 +1,30 @@ +ARG BASE_IMAGE=adoptopenjdk:11-jdk-hotspot-focal +FROM $BASE_IMAGE + +LABEL AUTHOR="Michael Lux (michael.lux@aisec.fraunhofer.de)" + +# Install socat for UNIX socket debugging and ps command for karaf scripts +RUN apt-get update -qq && apt-get install -qq socat procps + +# Optional: Install oh-my-zsh for a better shell (~ 20 MiB overhead) +RUN apt-get update -qq && apt-get install -qq wget git zsh fonts-powerline \ + && wget https://github.com/robbyrussell/oh-my-zsh/raw/master/tools/install.sh -O - | zsh || true \ + # Set nice theme + && sed -ie 's/^ZSH_THEME=".*"$/ZSH_THEME="agnoster"/' ~/.zshrc \ + # Disable automatic update + && sed -ie 's/^# DISABLE_AUTO_UPDATE$/DISABLE_AUTO_UPDATE/' ~/.zshrc \ + # Remove git, Cleanup + && apt-get remove --purge -qq git && apt-get autoremove --purge -qq \ + # Inject karaf console start command into zsh history + && echo ": 0:0;bin/client" > ~/.zsh_history + +# Add the actual core platform files to /root +ADD build/libs/lib /root/lib/ +ADD build/libs/ids-connector.jar /root/ + +WORKDIR "/root" + +# Ports to expose +EXPOSE 8080 29292 + +ENTRYPOINT ["java", "--class-path", "./ids-connector.jar:./lib/*", "de.fhg.aisec.ids.TrustedConnector"] diff --git a/ids-connector/build.gradle.kts b/ids-connector/build.gradle.kts index afb58ec90..d01c4ec5a 100644 --- a/ids-connector/build.gradle.kts +++ b/ids-connector/build.gradle.kts @@ -1,4 +1,3 @@ -// import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar import org.gradle.plugins.ide.idea.model.IdeaModel import org.springframework.boot.gradle.tasks.bundling.BootJar @@ -9,29 +8,33 @@ plugins { application id("org.springframework.boot") id("com.github.gmazzo.buildconfig") version "2.0.2" - // id("com.github.johnrengelman.shadow") version "7.0.0" kotlin("jvm") kotlin("plugin.spring") } -tasks.withType { - enabled = true +// Clears library JARs before copying +val cleanLibs = tasks.create("deleteLibs") { + delete("$buildDir/libs/lib") +} +// Copies all runtime library JARs to build/libs/lib +val copyLibs = tasks.create("copyLibs") { + from(configurations.runtimeClasspath) + destinationDir = file("$buildDir/libs/lib") + dependsOn(cleanLibs) } -tasks.withType { +tasks.withType { + enabled = true archiveFileName.set("ids-connector.jar") - layered() + dependsOn(copyLibs) } -configure { - mainClass.set("de.fhg.aisec.ids.TrustedConnector") +// Disable bootJar, as the JAR packaging of Spring Boot prevents dynamic Spring XML parsing due to classpath issues! +tasks.withType { + enabled = false } -// tasks.withType { -// archiveFileName.set("ids-connector.jar") -// } - apply(plugin = "idea") buildConfig { diff --git a/ids-connector/src/main/resources/deploy/flow-policy-example.pl b/ids-connector/src/main/resources/deploy/flow-policy-example.pl deleted file mode 100644 index 5d94233a6..000000000 --- a/ids-connector/src/main/resources/deploy/flow-policy-example.pl +++ /dev/null @@ -1,45 +0,0 @@ -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% Prolog representation of a data flow policy -% -% Source: default -% -% Do not edit this file, it has been generated automatically -% by XText/Xtend. -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% Only required for SWI-Prolog -% Allow the following predicates to be scattered around the prolog file. -% Otherwise Prolog will issue a warning if they are not stated in subsequent lines. -%:- discontiguous service/1. -%:- discontiguous has_endpoint/2. -%:- discontiguous creates_label/2. -%:- discontiguous removes_label/2. -%:- discontiguous rule/1. -%:- discontiguous rule_priority/2. -%:- discontiguous receives_label/1. -%:- discontiguous has_decision/2. -%:- discontiguous has_target/2. -%:- discontiguous has_capability/2. -%:- discontiguous has_property/3. -%:- discontiguous requires_prerequisites/2. -%:- discontiguous has_alternativedecision/2. -%:- discontiguous has_obligation/2. - -%%%%%%%%% Basic Blocking Rule %%%%%%%%%% -rule(dropAll). -rule_priority(dropAll,0). -has_decision(dropAll,drop). -receives_label(dropAll). -has_target(dropAll,serviceAll). - -%%%%%%%%%% Catch All Service %%%%%%%%%%% -service(serviceAll). -has_endpoint(serviceAll,'.*'). - -%%%%%%%%%%%%%%%% Rules %%%%%%%%%%%%%%%%% -% Allow everything -rule(allowAll). -rule_priority(allowAll, 1). -has_target(allowAll, serviceAll). -receives_label(allowAll). -has_decision(allowAll, allow). \ No newline at end of file diff --git a/ids-connector/src/main/resources/etc/custom.properties b/ids-connector/src/main/resources/etc/custom.properties deleted file mode 100644 index 9e1ee6462..000000000 --- a/ids-connector/src/main/resources/etc/custom.properties +++ /dev/null @@ -1,41 +0,0 @@ -################################################################################ -# -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -################################################################################ - -# -# All the values specified here will override the default values given -# in config.properties. -# - -karaf.systemBundlesStartLevel=50 - -# -# You can place any customized configuration here. -# - -java.net.preferIPv4Stack=true - -# Disable shutdown port -karaf.shutdown.port=-1 - -# Re-enabled SSH server to allow attaching to a running Docker-version of the Trusted Connector. -# TODO: find a better solution to handle this. Pivotal story id: #157912999 -karaf.startRemoteShell=true - -# Reduce the default 20 threads to a reasonable size -org.apache.felix.eventadmin.ThreadPoolSize=3 diff --git a/ids-connector/src/main/resources/etc/de.fhg.dfcontrol.rules.cfg b/ids-connector/src/main/resources/etc/de.fhg.dfcontrol.rules.cfg deleted file mode 100644 index fff7023ca..000000000 --- a/ids-connector/src/main/resources/etc/de.fhg.dfcontrol.rules.cfg +++ /dev/null @@ -1,5 +0,0 @@ -LABEL .*input AS raw -LABEL .*process AS processed -REMOVELABEL raw FROM .*process -ALLOW raw TO .*process -ALLOW processed TO hdfs.* diff --git a/ids-connector/src/main/resources/etc/idscp2/aisecconnector1-keystore.jks b/ids-connector/src/main/resources/etc/idscp2/aisecconnector1-keystore.jks deleted file mode 100644 index 8cac581c388491153679329a43ce082c6877ea64..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2527 zcma)7c{tSD8=vo(rOY5ROvSaAvW@Q;W9<$ajeQA~J+ojcjL@Yd3?sU>a4(}|m+jh; zx}{vCv6gb_whA{(wh^w914=XpP8dEax+^LgL1F}pDffk2?b4s3UT zAhcMvQr6872pkG>U>l$~LR13*zyNiqBmlr6Fb?cv-KJ@&kq+ja7sO?NWIV!)lDM=O zThg^J9CI+W@tY}GMCmQHwPuFO4OMd*!6A0xpjm7WT$Jq;=N;vugZ0+`MTS{zD>ob%e25AL~8DpY!z+nh%`@Isikt8I|+syQq@DJ$T5ru^A<5_ z<5GeLvAa6URbw>9DO*ReBEe0gbu34*Fjx9Uw1SWO@vo@`CEw+zD;5@4)kIvL7DWQs z>wn}V55|=hni6%XxVPt3Q~Zu+g)Zh4m2{7jvk<(sXMOi0>Vx?uFT}5N6V;Whdf?h-# zF)%Ym?Y%C`pDCl%9kOP3iu>#0*-p=6vS#Wp2QWgGSEL>sbeek>pR_TDJ6rZL@3fQ$52GK0S*iZc4I!AjxXz z9ZS`(rv^gF&F^({3vtVYGQ?!#m2Zq_?N7?LzMDc;)-dT?x@B@Yr)RU*YcA$wtHB$` zW4`l;35;H~pFH;%w`hJk+2gp`J%NJe(K2t#lbkujMcn*G%N~o#@qzdTR{5Eduuznu zaa-d8WC4Dtn1=yNl6zgWkmFOeN~-PGaEfmj-CB;R{==+(@PLO=IJoj`)NNHl!NP-IW2ci9o%D z;`e$(i{u|?DCsBZCk^Gls^0;iKF3(BkAUESWDk)I5A%zNk4G&@i1J<=|rDKxcg?8b`JJUvrh;A*42y_ zO`nO8bz*v?x6g?FN}i;P_0t5~q&&`JLhA3N`)l#H*NVPBJ~!w3B|f5^$JL=eFQ~+eH!XiYI}F z5D4s=upnlG9Fgb(5hwtK0=q#m#7^}D%Y+p%06@VZpeX?b?nHdD%Va*re01^=4xG0nZ0FdmnT&-%}gEpi@(v+f^roH&% zUI#1VhTG`!^?Y?Cr8xb<_pMZPP8%yoY!3p%JMC#{FRPvEacVfR{WNO~F&m}UlocGF zG7~O%=5Nh9KkU^74LLNkDF1W(wPNYpX2@GDvsZQcKk1ED&(>9VrY^HD+-P$9w!wkL z!?w*{jc`Da0~us_>IB?WBV*&-Q;;-7*>Svea-JyX!WD=ZrRJ%lI#ON&#LD_uKf;42 z(yfd@8V|g;Y&2e6{tWPhE=HP0k`8k#* ziWjRVvz04*>r`keuZ|GlQ+^(=dS9o_EiVq^xKI%Q0u*zA^THQ72g(VbR!$s-gGs&Z zSx05Y69LI-udJ-ZhY?XH)~rE=t!Wk59uOBJ)sxI`;+`*8DeIB0+U=-4?o08S+?IUHMW&C-~{V*IT^|w0_=sy+!25y~J66OaoIXeT`3|at-9U8__5}t{{4hr&Rgt0>i z{}t;pOqgMi%P>&@DzS~bwo!5$G24jUMyYL--bUQNn^FLWI{ zI(_X2>9eX`jj#DAwSwUTF9md(%G;w@lV2Zy^Sm+csb*owj;iw0Bj^`FxKTT?rF^)^ zlz&xAU<_9rs!uhGbzFO*`^zKKYIm$>pi9i7OSx+nKcS}y#7%VY;d*{_{}Zc^dQZoE zWT}Kz61-k76P>5M-}b}uRIpwIW2PMWE-H$sj5G+AiE&fSef4pl+++mHKXHnOm9HOa zm>s=oQy#+pRQ-f`FS5ayvR35W)^RHF0OHIpj_wHm3g0$3lLuzR+9kffzq;>tzK;(h zr&(_oKJ`&#yUR$a4e7dDcq!SG$1tbpONmRd4^J$1DZPNN6y$1Pyv9;8RB%nIvx`Fs KwRVuWxBmm2L>qhn diff --git a/ids-connector/src/main/resources/etc/idscp2/client-truststore_new.jks b/ids-connector/src/main/resources/etc/idscp2/client-truststore_new.jks deleted file mode 100644 index 998f04c7d601ba0540b4d4d15fe86bdcb7af0bbf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1974 zcmezO_TO6u1_mZLW=c+EU|`Jf5m7g0V2#i-HLzr0V9qvZVoo<`V)9?W%*4pV#L2LU z@x9*Bv>WXPylk9WZ60mkc^Mg5Ss4tR47m+B*_cCF*o2u}Tn&W{1VJ1w9xk_{#L~Qs z{It{}LpcK(kRUUUsHaP?LQsBwi9$$fafyPnqk@rvp@o5*IIp3Fp@FfXp_!qPfl-t= zuQ8BoWCrC@#f~OMC1j^FvNA9?G4eAQG%<29H8CvpkK@{zD!3fL8WmPNPq_~x&Fw@qo$5yw>f^z%Zipp*lu$0)ca^by}UFXjJ-QyZ?{>+ZV)9WPPWv_2jS{fCjs&lH-W0AJn z^d`@i3n>%5^?q;5x~aP$C}VQp@AKi}X;aJWgPVg@UHk&fq9!lNkFaBXHhY0NA8+i_ z0|h1%t(fN-%nR$yK6gH$%}Ddu&jpRiqF$e_G?cswTARIFYr)q`)f4V%ADcNjK_c{Q z_q-7GTP|1ZCae^(R(4Tf{QLLpf@vwwp0dPEJAHcYPH;|SEiO$0XT+SFY+JMu8SxV^ zBfbM>#A}d@$jFEsg4{I8fF{5U2+Vv2MwZ|VXcA@MKtv{&F^~erGcc12gEBcde+QQ) z!Lm4^?6+E_C(QqrT35-%gSVdjJEkXlX2wb9;|r=H&qqG5@jDQwm3?>1vkmJM4k%n( zWv&{pG$U!(o-1X4P89uFp5kG)-PAZD(@k=FV1bFvhNg&8W6iMqlh41(Dg6<-eZFGO zN~O6gqQ3`)HTed1&Qp6Y(r*y`BceUJ`C-GRNBlWeWeayq(t8#haQL8tV;V2-&qF^h zo0Pr35$7su*`aXqw@F9hk+cPe1tJctZOfML_ddntp6}9fIC9deG*Ly7N>#??wqo-l z84qW^R&lRtdE3}~FXyK<>)157N;ibrNN7Cy_8h_%#>n1pqxPn8;3R< zu*_#?WMuI$a5Hd$@eP>TETCqjMyJrDyeHG|6o z!KqSj-)zyd{agKa!QYw;4yWw+wJm3*g11jl;{112E#n$j-WJx6t=(6%)q*aUGGw#; zy5KBQD;fNflWV%jv40{$Cu%Mn59m$5oqTVV=eg`$_O5mFERRlnzrL02cVNM#Bj2{L zt8KjXc+FOed5P!u`?=4S4b1Y%-??DNvK1R{JxO@1*&4G}H&rvC`l;9g`I=)%Z~u9) zG}_O%emwg|cZGCR_eZxl%g_5C^<^ZTee+9vMniO0Y-gh0r`;LVbKcZFJ($0dnWyoe zYrYYqA=e$%<_Ut+7Vmn}bu&WYORM6`YKBXK_xC*O*&X-8P$I!$Zrc3ySu?wxy5@h* jKJsPXQbv^>U)0#*vbc9$N>rMBDW~+|HRjd{yhWM-qpIG& diff --git a/ids-connector/src/main/resources/etc/import_ca_chain_into_keystore.sh b/ids-connector/src/main/resources/etc/import_ca_chain_into_keystore.sh deleted file mode 100644 index b4875954e..000000000 --- a/ids-connector/src/main/resources/etc/import_ca_chain_into_keystore.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash -# -# Imports CA chain and connector cert into karaf keystore. Execute in $(Karaf-dir)/etc/keystores/ -# Then, build karaf. The keystore is automatically deployed. - -keytool -keystore keystore.jks -storepass password -importcert -trustcacerts -noprompt -alias root -file ../../../../../ssl/ca/rootca.cert -keytool -keystore keystore.jks -storepass password -importcert -alias ca -file ../../../../../ssl/ca/subca.cert -keytool -keystore keystore.jks -storepass password -importcert -alias client -file ../../../../../ssl/certs/client.cert -keytool -keystore keystore.jks -storepass password -importcert -alias server -file ../../../../../ssl/certs/server.cert - diff --git a/ids-connector/src/main/resources/etc/jetty.xml b/ids-connector/src/main/resources/etc/jetty.xml deleted file mode 100644 index 98e1ca6a5..000000000 --- a/ids-connector/src/main/resources/etc/jetty.xml +++ /dev/null @@ -1,91 +0,0 @@ - - - - - - - - https - - - - - - - - - - - - - - - - - - - - - /etc/tls-webconsole/keystore_latest.jks - - ids - ids - - - - - - SSL - SSLv2 - SSLv2Hello - SSLv3 - - - - - ^.*_(MD5|SHA|SHA1)$ - ^TLS_RSA_.*$ - ^SSL_.*$ - ^.*_NULL_.*$ - ^.*_anon_.*$ - - - - - - - - - - - - - - - - - - - http/1.1 - - - - - - - - - - - - - 0.0.0.0:8443 - - - - - - - - - \ No newline at end of file diff --git a/ids-connector/src/main/resources/etc/org.apache.felix.fileinstall-deploy.cfg b/ids-connector/src/main/resources/etc/org.apache.felix.fileinstall-deploy.cfg deleted file mode 100644 index 966ff752c..000000000 --- a/ids-connector/src/main/resources/etc/org.apache.felix.fileinstall-deploy.cfg +++ /dev/null @@ -1,25 +0,0 @@ -################################################################################ -# -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -################################################################################ - -felix.fileinstall.dir = ${karaf.base}/deploy -felix.fileinstall.tmpdir = ${karaf.data}/generated-bundles -felix.fileinstall.poll = 15000 -felix.fileinstall.start.level = 80 -felix.fileinstall.active.level = 80 -felix.fileinstall.log.level = 3 diff --git a/ids-connector/src/main/resources/etc/org.apache.karaf.management.cfg b/ids-connector/src/main/resources/etc/org.apache.karaf.management.cfg deleted file mode 100644 index 9a4141c9e..000000000 --- a/ids-connector/src/main/resources/etc/org.apache.karaf.management.cfg +++ /dev/null @@ -1,112 +0,0 @@ - -# -# The properties in this file define the configuration of Apache Karaf's JMX Management -# - -# -# Port number for RMI registry connection -# -#rmiRegistryPort = 1099 -#rmiRegistryPort = -1 - -# -# Host for RMI registry -# -#rmiRegistryHost = 127.0.0.1 - -# -# Port number for RMI server connection -# -#rmiServerPort = 44444 -#rmiServerPort = -1 - -# -# Host for RMI server -# -#rmiServerHost = 127.0.0.1 - -# -# Name of the JAAS realm used for authentication -# -jmxRealm = karaf - -# -# The service URL for the JMXConnectorServer -# -#serviceUrl = service:jmx:rmi://127.0.0.1:44444/jndi/rmi://127.0.0.1:1099/karaf-root -# Empty service URL disabled JMXConnectorServer. This will generate an error in the logs but this is intended -serviceUrl = - -# -# Whether any threads started for the JMXConnectorServer should be started as daemon threads -# -daemon = true - -# -# Whether the JMXConnectorServer should be started in a separate thread -# -threaded = true - -# -# The ObjectName used to register the JMXConnectorServer -# -#objectName = connector:name=rmi - -# -# Timeout to lookup for the keystore in case of SSL authentication usage -# -#keyStoreAvailabilityTimeout = 5000 - -# -# The type of authentication -# -#authenticatorType = password -authenticatorType = password - -# -# Enable or not SSL/TLS -# -#secured = false - -# -# Secure algorithm to use -# -#secureAlgorithm = default - -# -# Secure protocol to use -# -#secureProtocol = TLS - -# -# Keystore to use for secure mode -# -#keyStore = karaf.ks - -# -# Alias of the key to use in the keystore -# -#keyAlias = karaf - -# -# Truststore to use for secure mode -# -#trustStore = karaf.ts - -# -# Create the JMX RMI registry -# -#createRmiRegistry = true -createRmiRegistry = false - -# -# Locate the JMX RMI registry -# -#locateRmiRegistry = true -locateRmiRegistry = false - -# -# Locate an existing MBean server if possible (useful when Karaf is embedded) -# -#locateExistingMBeanServerIfPossible = true - diff --git a/ids-connector/src/main/resources/etc/org.ops4j.pax.logging.cfg b/ids-connector/src/main/resources/etc/org.ops4j.pax.logging.cfg deleted file mode 100644 index 0964e6264..000000000 --- a/ids-connector/src/main/resources/etc/org.ops4j.pax.logging.cfg +++ /dev/null @@ -1,102 +0,0 @@ -################################################################################ -# -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -################################################################################ - -# Common pattern layout for appenders -log4j2.pattern = %d{ISO8601} | %-5p | %-16t | %-32c{1} | %X{bundle.id} - %X{bundle.name} - %X{bundle.version} | %m%n - -# Root logger -log4j2.rootLogger.level = INFO -# uncomment to use asynchronous loggers, which require mvn:com.lmax/disruptor/3.3.2 library -#log4j2.rootLogger.type = asyncRoot -#log4j2.rootLogger.includeLocation = false -log4j2.rootLogger.appenderRef.RollingFile.ref = RollingFile -log4j2.rootLogger.appenderRef.PaxOsgi.ref = PaxOsgi -log4j2.rootLogger.appenderRef.Console.ref = Console -log4j2.rootLogger.appenderRef.Console.filter.threshold.type = ThresholdFilter -log4j2.rootLogger.appenderRef.Console.filter.threshold.level = OFF - -# Loggers configurations useful for debugging - -log4j2.logger.ids.name = de.fhg.aisec.ids -log4j2.logger.ids.level = DEBUG - -# Felix logger -#log4j2.logger.felix.name = org.apache.felix -#log4j2.logger.felix.level = DEBUG - -# Karaf logger -#log4j2.logger.karaf.name = org.apache.karaf -#log4j2.logger.karaf.level = DEBUG - -# Spifly logger -log4j2.logger.spifly.name = org.apache.aries.spifly -log4j2.logger.spifly.level = INFO - -# Security audit logger -log4j2.logger.audit.name = org.apache.karaf.jaas.modules.audit -log4j2.logger.audit.level = INFO -log4j2.logger.audit.additivity = false -log4j2.logger.audit.appenderRef.AuditRollingFile.ref = AuditRollingFile - -# Appenders configuration - -# Console appender not used by default (see log4j2.rootLogger.appenderRefs) -log4j2.appender.console.type = Console -log4j2.appender.console.name = Console -log4j2.appender.console.layout.type = PatternLayout -log4j2.appender.console.layout.pattern = %d{ISO8601} | %-5p | %-16t | %-32c{1} | %X{bundle.id} - %X{bundle.name} - %X{bundle.version} | %m%n - -# Rolling file appender -log4j2.appender.rolling.type = RollingRandomAccessFile -log4j2.appender.rolling.name = RollingFile -log4j2.appender.rolling.fileName = log/karaf.log -log4j2.appender.rolling.filePattern = log/karaf.log.%i -# uncomment to not force a disk flush -#log4j2.appender.rolling.immediateFlush = false -log4j2.appender.rolling.append = true -log4j2.appender.rolling.layout.type = PatternLayout -log4j2.appender.rolling.layout.pattern = %d{ISO8601} | %-5p | %-16t | %-32c{1} | %X{bundle.id} - %X{bundle.name} - %X{bundle.version} | %m%n -log4j2.appender.rolling.policies.type = Policies -log4j2.appender.rolling.policies.size.type = SizeBasedTriggeringPolicy -log4j2.appender.rolling.policies.size.size = 16MB - -# Audit file appender -log4j2.appender.audit.type = RollingRandomAccessFile -log4j2.appender.audit.name = AuditRollingFile -log4j2.appender.audit.fileName = security/audit.log -log4j2.appender.audit.filePattern = security/audit.log.%i -log4j2.appender.audit.append = true -log4j2.appender.audit.layout.type = PatternLayout -log4j2.appender.audit.layout.pattern = %d{ISO8601} | %-5p | %-16t | %-32c{1} | %X{bundle.id} - %X{bundle.name} - %X{bundle.version} | %m%n -log4j2.appender.audit.policies.type = Policies -log4j2.appender.audit.policies.size.type = SizeBasedTriggeringPolicy -log4j2.appender.audit.policies.size.size = 8MB - -# OSGi appender -log4j2.appender.osgi.type = PaxOsgi -log4j2.appender.osgi.name = PaxOsgi -log4j2.appender.osgi.filter = * - -# help with identification of maven-related problems with pax-url-aether -#log4j2.logger.aether.name = shaded.org.eclipse.aether -#log4j2.logger.aether.level = TRACE -#log4j2.logger.http-headers.name = shaded.org.apache.http.headers -#log4j2.logger.http-headers.level = DEBUG -#log4j2.logger.maven.name = org.ops4j.pax.url.mvn -#log4j2.logger.maven.level = TRACE diff --git a/ids-connector/src/main/resources/etc/org.ops4j.pax.url.mvn.cfg b/ids-connector/src/main/resources/etc/org.ops4j.pax.url.mvn.cfg deleted file mode 100644 index b675f9cb8..000000000 --- a/ids-connector/src/main/resources/etc/org.ops4j.pax.url.mvn.cfg +++ /dev/null @@ -1,42 +0,0 @@ -################################################################################## -# -# This overrides Karaf's default org.ops4j.pax.url.mvn.cfg file to make sure -# that Karaf does not use any online repositories to pull in features or bundles. -# -################################################################################## - -# Make sure that no custom maven settings are used -org.ops4j.pax.url.mvn.settings=${karaf.home}/etc/karaf_maven_settings.xml - -# Local repositories containing all required core bundles -org.ops4j.pax.url.mvn.defaultRepositories=file:${karaf.home}/system@snapshots -org.ops4j.pax.url.mvn.localRepository=${karaf.home}/system@snapshots -org.ops4j.pax.url.mvn.useFallbackRepositories=false - - -# Remote repositories that are used when resolution of "org.ops4j.pax.url.mvn.defaultRepositories" fails -org.ops4j.pax.url.mvn.repositories= \ - https://repo1.maven.org/maven2@id=central, \ - https://repository.apache.org/content/groups/snapshots-group@id=apache@snapshots@noreleases, \ - https://oss.sonatype.org/content/repositories/ops4j-snapshots@id=ops4j.sonatype.snapshots.deploy@snapshots@noreleases - -# -# default value for connection and read timeouts, when socket.readTimeout and socket.connectionTimeout -# are not specified -org.ops4j.pax.url.mvn.timeout = 5000 -# timeout in ms when establishing http connection during artifact resolution -org.ops4j.pax.url.mvn.socket.connectionTimeout = 5000 -# timeout in ms when reading data after connecting to remote repository -org.ops4j.pax.url.mvn.socket.readTimeout = 30000 -# SO_KEEPALIVE option for sockets, defaults to false -org.ops4j.pax.url.mvn.socket.keepAlive = false -# SO_LINGER option for sockets, defaults to -1 -org.ops4j.pax.url.mvn.socket.linger = -1 -# SO_REUSEADDR option for sockets, defaults to false -org.ops4j.pax.url.mvn.socket.reuseAddress = false -# TCP_NODELAY option for sockets, defaults to true -org.ops4j.pax.url.mvn.socket.tcpNoDelay = true -# Configure buffer size for HTTP connections (output and input buffers), defaults to 8192 bytes -org.ops4j.pax.url.mvn.connection.bufferSize = 8192 -# Number of connection retries after failure is detected in http client. httpclient uses default value "3" -org.ops4j.pax.url.mvn.connection.retryCount = 3 \ No newline at end of file diff --git a/ids-connector/src/main/resources/etc/org.ops4j.pax.web.cfg b/ids-connector/src/main/resources/etc/org.ops4j.pax.web.cfg deleted file mode 100644 index 8463d022d..000000000 --- a/ids-connector/src/main/resources/etc/org.ops4j.pax.web.cfg +++ /dev/null @@ -1,64 +0,0 @@ -# Explicitly make pax-web aware of our jetty configuration -org.ops4j.pax.web.config.file = ${karaf.etc}/jetty.xml - -# -# min server threads -# -org.ops4j.pax.web.server.minThreads = 1 - -# -# max server threads -# -org.ops4j.pax.web.server.maxThreads = 20 - -# -# enable https -# -org.osgi.service.http.secure.enabled = true - -# -# http port. -# This is currently also in the setenv -org.osgi.service.http.port = 8181 - -# -# https port, default is 8443. -# This is currently also in the setenv -org.osgi.service.http.port.secure = 8443 - -org.ops4j.pax.web.ssl.keystore = ${karaf.etc}/test.jks -org.ops4j.pax.web.ssl.password = ids -org.ops4j.pax.web.ssl.keypassword = ids - -# -# The number of minutes after which an inactive session will timeout. -# -org.ops4j.pax.web.session.timeout = 2 - -# -# Specifies if the connections established use the nio classes from java. -# -org.osgi.service.http.useNIO = true - -# -# Set to true if certificate-based client authentication at the server is "wanted". -# -org.ops4j.pax.web.ssl.clientauthwanted = false - -# -# Set to true if certificate-based client authentication at the server is "required". -# -org.ops4j.pax.web.ssl.clientauthneeded = false - -# -# The time in milliseconds that the connection can be idle before it is closed. -# -org.ops4j.pax.web.server.idleTimeout = 10000 - -# -# Listening addresses. This should match host in the sslconnector/name attribute in jetty.xml -# Default is 0.0.0.0 -# This is currently also in the setenv -# -#org.ops4j.pax.web.listening.addresses = 0.0.0.0 - diff --git a/ids-connector/src/main/resources/etc/system.properties b/ids-connector/src/main/resources/etc/system.properties deleted file mode 100644 index 3c042fc0d..000000000 --- a/ids-connector/src/main/resources/etc/system.properties +++ /dev/null @@ -1,155 +0,0 @@ -################################################################################ -# -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -################################################################################ - -# -# The properties defined in this file will be made available through system -# properties at the very beginning of the Karaf's boot process. -# - - -# Log level when the pax-logging service is not available -# This level will only be used while the pax-logging service bundle -# is not fully available. -# To change log levels, please refer to the org.ops4j.pax.logging.cfg file -# instead. -org.ops4j.pax.logging.DefaultServiceLog.level = ERROR - -# -# Name of this Karaf instance. -# -karaf.name = root - -# -# Default repository where bundles will be loaded from before using -# other Maven repositories. For the full Maven configuration, see -# the org.ops4j.pax.url.mvn.cfg file. -# -karaf.default.repository = system - -# -# Location of a shell script that will be run when starting a shell -# session. This script can be used to create aliases and define -# additional commands. -# -karaf.shell.init.script = shell.init.script - -# -# Sets the maximum size of the shell command history. If not set, -# defaults to 500 entries. Setting to 0 will disable history. -# -# karaf.shell.history.maxSize = 0 - -# -# Deletes the entire karaf.data directory at every start -# -karaf.clean.all = false - -# -# Deletes the karaf.data/cache directory at every start -# -karaf.clean.cache = true - -# -# User name for the Karaf local console -# -karaf.local.user = karaf - -# -# Roles to use when for the default user in the local Karaf console. -# -# The syntax is the following: -# [classname:]principal -# where classname is the class name of the principal object -# (defaults to org.apache.karaf.jaas.modules.RolePrincipal) -# and principal is the name of the principal of that class -# (defaults to instance). -# -karaf.local.roles = admin,manager,viewer,systembundles - -# -# Set this empty property to avoid errors when validating xml documents. -# -xml.catalog.files = - -# -# Suppress the bell in the console when hitting backspace too many times -# for example -# -jline.nobell = true - -# -# ServiceMix specs options -# -org.apache.servicemix.specs.debug = false -org.apache.servicemix.specs.timeout = 0 - -# -# Settings for the OSGi 4.3 Weaving -# By default, we will not weave any classes. Change this setting to include classes -# that you application needs to have woven. -# -org.apache.aries.proxy.weaving.enabled = none -# Classes not to weave - Aries default + Xerces which is known to have issues. -org.apache.aries.proxy.weaving.disabled = org.objectweb.asm.*,org.slf4j.*,org.apache.log4j.*,javax.*,org.apache.xerces.* - -# -# By default, only Karaf shell commands are secured, but additional services can be -# secured by expanding this filter -# -karaf.secured.services = (&(osgi.command.scope=*)(osgi.command.function=*)) - -# -# By default, if there's no ACL policy for a certain karaf command, this command is allowed to access -# without the RBAC. We can change this behavior by enable the following property, which means -# if a karaf command has no corresponding ACL then access it must have one of the karaf.secured.command.compulsory.roles -# -#karaf.secured.command.compulsory.roles=admin - -# -# Security properties -# -# To enable OSGi security, uncomment the properties below, -# install the framework-security feature and restart. -# -#java.security.policy=${karaf.etc}/all.policy -#org.osgi.framework.security=osgi -#org.osgi.framework.trust.repositories=${karaf.etc}/trustStore.ks - -# -# HA/Lock configuration -# -# Karaf uses a lock mechanism to know which instance is the master (HA) -# The lock can be on the filesystem (default) or on a database. -# -# See http://karaf.apache.org/manual/latest/users-guide/failover.html for details. -# -# Even using a single instance, Karaf creates the lock file -# You can specify the location of the lock file using the -# karaf.lock.dir=/path/to/the/directory/containing/the/lock -# -# By default, the slave instances start but are passive. -# If you want to prevent the slave instances startup, you can use -# the karaf.lock.slave.block property (false by default): -# karaf.lock.slave.block=true - -javax.net.ssl.keyStore=${karaf.etc}/provider-keystore.p12 -javax.net.ssl.keyStorePassword=password -javax.net.ssl.trustStore=${karaf.etc}/truststore.p12 -javax.net.ssl-trustStorePassword=password - diff --git a/ids-connector/src/main/resources/etc/tls-webconsole/keystore_latest.jks b/ids-connector/src/main/resources/etc/tls-webconsole/keystore_latest.jks deleted file mode 100644 index bd19b8f5c0b2c5fd6a92e95e34065036fbfd9bb3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5239 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 diff --git a/ids-connector/src/main/resources/etc/users.properties b/ids-connector/src/main/resources/etc/users.properties deleted file mode 100644 index 7a8e789be..000000000 --- a/ids-connector/src/main/resources/etc/users.properties +++ /dev/null @@ -1,37 +0,0 @@ -################################################################################ -# -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -################################################################################ - -# -# This file contains the users, groups, and roles. -# Each line has to be of the format: -# -# USER=PASSWORD,ROLE1,ROLE2,... -# USER=PASSWORD,_g_:GROUP,... -# _g_\:GROUP=ROLE1,ROLE2,... -# -# All users, groups, and roles entered in this file are available after Karaf startup -# and modifiable via the JAAS command group. These users reside in a JAAS domain -# with the name "karaf". -# -karaf = karaf,_g_:admingroup -ids = ids,_g_:idsgroup -# Re-enabled SSH server to allow attaching to a running Docker-version of the Trusted Connector. -# TODO: find a better solution to handle this. Pivotal story id: #157912999 -_g_\:admingroup = group,admin,manager,viewer,systembundles,ssh -_g_\:idsgroup = group,manager,api,viewer diff --git a/ids-webconsole/build.gradle.kts b/ids-webconsole/build.gradle.kts index 6e83a1b35..23ad2ce25 100644 --- a/ids-webconsole/build.gradle.kts +++ b/ids-webconsole/build.gradle.kts @@ -116,8 +116,9 @@ dependencies { } node { - // download.set(true) - // currently broken on M1 + // This is important for a hassle-free build without pre-installed yarn! + // To disable, pass -PnodeDownload=false to gradle! + download.set(findProperty("nodeDownload")?.toString()?.toBoolean() ?: true) } val yarnInstall by tasks.registering(YarnTask::class) { diff --git a/runConnector.sh b/runConnector.sh deleted file mode 100755 index 854a4cf1d..000000000 --- a/runConnector.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -karaf-assembly/build/assembly/bin/karaf clean debug From beaacff9d06c60843d7c9aca712b7afe6729a10a Mon Sep 17 00:00:00 2001 From: Jean-Luc Reding Date: Mon, 10 May 2021 17:44:18 +0200 Subject: [PATCH 29/54] Static resources experiments --- ids-connector/build.gradle.kts | 2 ++ ids-connector/src/main/resources/application.yml | 10 +++++++++- .../de/fhg/aisec/ids/webconsole/Controller.kt | 16 ++++++++++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/Controller.kt diff --git a/ids-connector/build.gradle.kts b/ids-connector/build.gradle.kts index d01c4ec5a..d9108ed22 100644 --- a/ids-connector/build.gradle.kts +++ b/ids-connector/build.gradle.kts @@ -73,4 +73,6 @@ dependencies { // Spring Boot implementation("org.springframework.boot:spring-boot-starter") + implementation("org.springframework.boot:spring-boot-starter-web") + implementation("org.springframework.boot:spring-boot-starter-test") } diff --git a/ids-connector/src/main/resources/application.yml b/ids-connector/src/main/resources/application.yml index 32c946ce0..829482d13 100644 --- a/ids-connector/src/main/resources/application.yml +++ b/ids-connector/src/main/resources/application.yml @@ -1,4 +1,12 @@ logging: level: ROOT: INFO - de.fhg.aisec: TRACE \ No newline at end of file + de.fhg.aisec: TRACE + +#spring: +# resources: +# static-locations=classpath:/static/ + +#spring: +# mvc: +# static-path-pattern=/static/ \ No newline at end of file diff --git a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/Controller.kt b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/Controller.kt new file mode 100644 index 000000000..5c8cf567f --- /dev/null +++ b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/Controller.kt @@ -0,0 +1,16 @@ +package de.fhg.aisec.ids.webconsole + +import de.fhg.aisec.ids.webconsole.api.* +import org.slf4j.LoggerFactory +import org.springframework.stereotype.Controller +import org.springframework.web.bind.annotation.RequestMapping +import javax.ws.rs.ApplicationPath + +@Controller +class Controller { + @RequestMapping("/") + fun c(model: Map?): String { + //return "index.html" + return "/www/src/app/login/login.component.html" + } +} \ No newline at end of file From 6f1bda965c20b3987a78eab94014c3dccf44c16b Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Mon, 10 May 2021 19:02:24 +0200 Subject: [PATCH 30/54] Fixed and finalized static resources serving --- ids-connector/build.gradle.kts | 2 -- .../src/main/resources/application.yml | 10 ++---- ids-webconsole/bnd.bnd | 22 ------------ ids-webconsole/build.gradle.kts | 28 +++++++-------- .../www => angular}/.browserslistrc | 0 .../{resources/www => angular}/.dockerignore | 0 .../{resources/www => angular}/.editorconfig | 0 .../{resources/www => angular}/.gitignore | 0 .../{resources/www => angular}/Dockerfile | 0 .../main/{resources/www => angular}/README.md | 0 .../{resources/www => angular}/angular.json | 0 .../{resources/www => angular}/package.json | 2 +- .../www => angular}/proxy.conf.json | 0 .../OSGI-INF/blueprint => angular}/rest.xml | 0 .../src/app/_guards/auth.guard.ts | 0 .../src/app/_interceptors/jwt.interceptor.ts | 0 .../www => angular}/src/app/app.component.css | 0 .../www => angular}/src/app/app.component.ts | 0 .../www => angular}/src/app/app.module.ts | 0 .../www => angular}/src/app/app.routing.ts | 0 .../app/application-http-client.service.ts | 0 .../src/app/apps/app-card.component.html | 0 .../src/app/apps/app-card.component.ts | 0 .../apps/app-search-result-card.component.css | 0 .../app-search-result-card.component.html | 0 .../apps/app-search-result-card.component.ts | 0 .../src/app/apps/app-status.ts | 0 .../src/app/apps/app.port.def.ts | 0 .../src/app/apps/app.service.ts | 0 .../www => angular}/src/app/apps/app.ts | 0 .../src/app/apps/apps-search.component.html | 0 .../src/app/apps/apps-search.component.ts | 0 .../src/app/apps/apps.component.html | 0 .../src/app/apps/apps.component.ts | 0 .../www => angular}/src/app/apps/cml.ts | 0 .../src/app/confirm/confirm.component.css | 0 .../src/app/confirm/confirm.component.html | 0 .../src/app/confirm/confirm.component.ts | 0 .../src/app/confirm/confirm.service.ts | 0 .../connection-configuration/configuration.ts | 0 .../connection-configuration.component.css | 0 .../connection-configuration.component.html | 0 .../connection-configuration.component.ts | 0 .../connection-configuration.service.ts | 0 .../settings.interface.ts | 0 .../connection-report.component.css | 0 .../connection-report.component.html | 0 .../connection-report.component.ts | 0 .../connection-report.service.ts | 0 .../src/app/connection-report/endpoint.ts | 0 .../connection-report/incoming-connection.ts | 0 .../connection-report/outgoing-connection.ts | 0 .../app/dashboard/dashboard.component.html | 0 .../src/app/dashboard/dashboard.component.ts | 0 .../app/dashboard/metric-card.component.html | 0 .../app/dashboard/metric-card.component.ts | 0 .../dataflowpolicies.component.html | 0 .../dataflowpolicies.component.ts | 0 .../dataflowpoliciesnew.component.html | 0 .../dataflowpoliciesnew.component.ts | 0 .../app/dataflowpolicies/policy.interface.ts | 0 .../app/dataflowpolicies/policy.service.ts | 0 .../src/app/ids/ids.component.css | 0 .../src/app/ids/ids.component.html | 0 .../src/app/ids/ids.component.ts | 0 .../src/app/ids/settings.interface.ts | 0 .../src/app/ids/settings.service.ts | 0 .../src/app/ids/terms-of-service.interface.ts | 0 .../app/keycerts/cert-upload.component.html | 0 .../src/app/keycerts/cert-upload.component.ts | 0 .../keycerts/certificate-card.component.css | 0 .../keycerts/certificate-card.component.html | 0 .../keycerts/certificate-card.component.ts | 0 .../src/app/keycerts/certificate.ts | 0 .../src/app/keycerts/identity.interface.ts | 0 .../app/keycerts/identitynew.component.html | 0 .../src/app/keycerts/identitynew.component.ts | 0 .../src/app/keycerts/keycert.service.ts | 0 .../src/app/keycerts/keycerts.component.html | 0 .../src/app/keycerts/keycerts.component.ts | 0 .../home-layout/home-layout.component.html | 0 .../home-layout/home-layout.component.ts | 0 .../login-layout/login-layout.component.html | 0 .../login-layout/login-layout.component.ts | 0 .../src/app/login/login.component.html | 0 .../src/app/login/login.component.ts | 0 .../src/app/login/login.service.ts | 0 .../src/app/login/token.interface.ts | 0 .../src/app/mdl-upgrade-element-directive.ts | 0 .../src/app/metric/metric.service.ts | 0 .../src/app/prettify-json.pipe.ts | 0 .../www => angular}/src/app/result.ts | 0 .../www => angular}/src/app/route-result.ts | 0 .../src/app/routes/counter-example.ts | 0 .../route-card/route-card.component.css | 0 .../route-card/route-card.component.html | 0 .../routes/route-card/route-card.component.ts | 0 .../src/app/routes/route-metrics.ts | 0 .../src/app/routes/route.service.ts | 0 .../www => angular}/src/app/routes/route.ts | 0 .../routeeditor/routeeditor.component.css | 0 .../routeeditor/routeeditor.component.html | 0 .../routeeditor/routeeditor.component.ts | 0 .../src/app/routes/routes.component.css | 0 .../src/app/routes/routes.component.html | 0 .../src/app/routes/routes.component.ts | 0 .../src/app/routes/validation-info.ts | 0 .../routes/zoom-viz/zoom-viz.component.css | 0 .../routes/zoom-viz/zoom-viz.component.html | 0 .../app/routes/zoom-viz/zoom-viz.component.ts | 0 .../src/app/sensor/sensor.service.ts | 0 .../www => angular}/src/app/values.pipe.ts | 0 .../src/css/fontawesome/all.css | 0 .../src/css/material.teal-pink.min.css | 0 .../www => angular}/src/css/styles.css | 0 .../src/css/webfonts/fa-brands-400.eot | Bin .../src/css/webfonts/fa-brands-400.svg | 0 .../src/css/webfonts/fa-brands-400.ttf | Bin .../src/css/webfonts/fa-brands-400.woff | Bin .../src/css/webfonts/fa-brands-400.woff2 | Bin .../src/css/webfonts/fa-regular-400.eot | Bin .../src/css/webfonts/fa-regular-400.svg | 0 .../src/css/webfonts/fa-regular-400.ttf | Bin .../src/css/webfonts/fa-regular-400.woff | Bin .../src/css/webfonts/fa-regular-400.woff2 | Bin .../src/css/webfonts/fa-solid-900.eot | Bin .../src/css/webfonts/fa-solid-900.svg | 0 .../src/css/webfonts/fa-solid-900.ttf | Bin .../src/css/webfonts/fa-solid-900.woff | Bin .../src/css/webfonts/fa-solid-900.woff2 | Bin .../www => angular}/src/data/eu.topo.json | 0 .../www => angular}/src/data/locations.tsv | 0 .../www => angular}/src/data/topo_data.json | 0 .../src/environments/environment.prod.ts | 0 .../src/environments/environment.ts | 0 .../www => angular}/src/favicon.ico | Bin .../www => angular}/src/fonts/LICENSE.txt | 0 .../src/fonts/Material_Icons-normal-400.woff | Bin .../src/fonts/Roboto-normal-300.woff | Bin .../src/fonts/Roboto-normal-400.woff | Bin .../src/fonts/Roboto-normal-500.woff | Bin .../src/fonts/Roboto-normal-700.woff | Bin .../www => angular}/src/fonts/fonts.css | 0 .../www => angular}/src/images/Account.png | Bin .../src/images/Infrastructure.png | Bin .../www => angular}/src/images/WebService.png | Bin .../www => angular}/src/images/aisec.jpg | Bin .../www => angular}/src/images/aisec.png | Bin .../{resources/www => angular}/src/index.html | 0 .../{resources/www => angular}/src/main.ts | 0 .../www => angular}/src/polyfills.ts | 0 .../www => angular}/src/tsconfig.json | 0 .../www => angular}/src/typings.d.ts | 0 .../{resources/www => angular}/tslint.json | 0 .../main/{resources/www => angular}/yarn.lock | 0 .../de/fhg/aisec/ids/webconsole/Controller.kt | 32 ++++++++++++++---- 156 files changed, 43 insertions(+), 53 deletions(-) delete mode 100644 ids-webconsole/bnd.bnd rename ids-webconsole/src/main/{resources/www => angular}/.browserslistrc (100%) rename ids-webconsole/src/main/{resources/www => angular}/.dockerignore (100%) rename ids-webconsole/src/main/{resources/www => angular}/.editorconfig (100%) rename ids-webconsole/src/main/{resources/www => angular}/.gitignore (100%) rename ids-webconsole/src/main/{resources/www => angular}/Dockerfile (100%) rename ids-webconsole/src/main/{resources/www => angular}/README.md (100%) rename ids-webconsole/src/main/{resources/www => angular}/angular.json (100%) rename ids-webconsole/src/main/{resources/www => angular}/package.json (97%) rename ids-webconsole/src/main/{resources/www => angular}/proxy.conf.json (100%) rename ids-webconsole/src/main/{resources/OSGI-INF/blueprint => angular}/rest.xml (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/_guards/auth.guard.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/_interceptors/jwt.interceptor.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/app.component.css (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/app.component.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/app.module.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/app.routing.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/application-http-client.service.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/apps/app-card.component.html (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/apps/app-card.component.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/apps/app-search-result-card.component.css (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/apps/app-search-result-card.component.html (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/apps/app-search-result-card.component.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/apps/app-status.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/apps/app.port.def.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/apps/app.service.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/apps/app.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/apps/apps-search.component.html (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/apps/apps-search.component.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/apps/apps.component.html (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/apps/apps.component.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/apps/cml.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/confirm/confirm.component.css (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/confirm/confirm.component.html (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/confirm/confirm.component.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/confirm/confirm.service.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/connection-configuration/configuration.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/connection-configuration/connection-configuration.component.css (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/connection-configuration/connection-configuration.component.html (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/connection-configuration/connection-configuration.component.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/connection-configuration/connection-configuration.service.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/connection-configuration/settings.interface.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/connection-report/connection-report.component.css (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/connection-report/connection-report.component.html (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/connection-report/connection-report.component.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/connection-report/connection-report.service.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/connection-report/endpoint.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/connection-report/incoming-connection.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/connection-report/outgoing-connection.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/dashboard/dashboard.component.html (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/dashboard/dashboard.component.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/dashboard/metric-card.component.html (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/dashboard/metric-card.component.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/dataflowpolicies/dataflowpolicies.component.html (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/dataflowpolicies/dataflowpolicies.component.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/dataflowpolicies/dataflowpoliciesnew.component.html (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/dataflowpolicies/dataflowpoliciesnew.component.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/dataflowpolicies/policy.interface.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/dataflowpolicies/policy.service.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/ids/ids.component.css (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/ids/ids.component.html (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/ids/ids.component.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/ids/settings.interface.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/ids/settings.service.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/ids/terms-of-service.interface.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/keycerts/cert-upload.component.html (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/keycerts/cert-upload.component.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/keycerts/certificate-card.component.css (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/keycerts/certificate-card.component.html (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/keycerts/certificate-card.component.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/keycerts/certificate.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/keycerts/identity.interface.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/keycerts/identitynew.component.html (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/keycerts/identitynew.component.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/keycerts/keycert.service.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/keycerts/keycerts.component.html (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/keycerts/keycerts.component.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/layouts/home-layout/home-layout.component.html (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/layouts/home-layout/home-layout.component.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/layouts/login-layout/login-layout.component.html (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/layouts/login-layout/login-layout.component.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/login/login.component.html (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/login/login.component.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/login/login.service.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/login/token.interface.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/mdl-upgrade-element-directive.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/metric/metric.service.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/prettify-json.pipe.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/result.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/route-result.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/routes/counter-example.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/routes/route-card/route-card.component.css (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/routes/route-card/route-card.component.html (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/routes/route-card/route-card.component.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/routes/route-metrics.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/routes/route.service.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/routes/route.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/routes/routeeditor/routeeditor.component.css (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/routes/routeeditor/routeeditor.component.html (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/routes/routeeditor/routeeditor.component.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/routes/routes.component.css (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/routes/routes.component.html (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/routes/routes.component.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/routes/validation-info.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/routes/zoom-viz/zoom-viz.component.css (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/routes/zoom-viz/zoom-viz.component.html (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/routes/zoom-viz/zoom-viz.component.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/sensor/sensor.service.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/app/values.pipe.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/css/fontawesome/all.css (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/css/material.teal-pink.min.css (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/css/styles.css (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/css/webfonts/fa-brands-400.eot (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/css/webfonts/fa-brands-400.svg (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/css/webfonts/fa-brands-400.ttf (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/css/webfonts/fa-brands-400.woff (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/css/webfonts/fa-brands-400.woff2 (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/css/webfonts/fa-regular-400.eot (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/css/webfonts/fa-regular-400.svg (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/css/webfonts/fa-regular-400.ttf (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/css/webfonts/fa-regular-400.woff (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/css/webfonts/fa-regular-400.woff2 (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/css/webfonts/fa-solid-900.eot (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/css/webfonts/fa-solid-900.svg (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/css/webfonts/fa-solid-900.ttf (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/css/webfonts/fa-solid-900.woff (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/css/webfonts/fa-solid-900.woff2 (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/data/eu.topo.json (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/data/locations.tsv (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/data/topo_data.json (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/environments/environment.prod.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/environments/environment.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/favicon.ico (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/fonts/LICENSE.txt (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/fonts/Material_Icons-normal-400.woff (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/fonts/Roboto-normal-300.woff (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/fonts/Roboto-normal-400.woff (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/fonts/Roboto-normal-500.woff (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/fonts/Roboto-normal-700.woff (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/fonts/fonts.css (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/images/Account.png (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/images/Infrastructure.png (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/images/WebService.png (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/images/aisec.jpg (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/images/aisec.png (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/index.html (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/main.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/polyfills.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/tsconfig.json (100%) rename ids-webconsole/src/main/{resources/www => angular}/src/typings.d.ts (100%) rename ids-webconsole/src/main/{resources/www => angular}/tslint.json (100%) rename ids-webconsole/src/main/{resources/www => angular}/yarn.lock (100%) diff --git a/ids-connector/build.gradle.kts b/ids-connector/build.gradle.kts index d9108ed22..86724a7ba 100644 --- a/ids-connector/build.gradle.kts +++ b/ids-connector/build.gradle.kts @@ -68,11 +68,9 @@ dependencies { // Camel components implementation("org.apache.camel.springboot:camel-rest-starter") implementation("org.apache.camel.springboot:camel-http-starter") - implementation("de.fhg.aisec.ids", "camel-idscp2", libraryVersions["idscp2"]) // Spring Boot implementation("org.springframework.boot:spring-boot-starter") implementation("org.springframework.boot:spring-boot-starter-web") - implementation("org.springframework.boot:spring-boot-starter-test") } diff --git a/ids-connector/src/main/resources/application.yml b/ids-connector/src/main/resources/application.yml index 829482d13..bd3267f4f 100644 --- a/ids-connector/src/main/resources/application.yml +++ b/ids-connector/src/main/resources/application.yml @@ -3,10 +3,6 @@ logging: ROOT: INFO de.fhg.aisec: TRACE -#spring: -# resources: -# static-locations=classpath:/static/ - -#spring: -# mvc: -# static-path-pattern=/static/ \ No newline at end of file +spring: + resources: + static-locations: classpath:/www \ No newline at end of file diff --git a/ids-webconsole/bnd.bnd b/ids-webconsole/bnd.bnd deleted file mode 100644 index b022069d8..000000000 --- a/ids-webconsole/bnd.bnd +++ /dev/null @@ -1,22 +0,0 @@ -Bundle-Name: IDS :: Web Console -Bundle-Description: A web console for the IDS Core Platform. The web console allows to configure \ - routes, containers, brokers, etc. -Export-Package: \ - de.fhg.aisec.ids.webconsole,\ - de.fhg.aisec.ids.webconsole.api,\ - de.fhg.aisec.ids.webconsole.api.data,\ - de.fhg.aised.ids.webconsole.api.deserializer -Import-Package: \ - de.fhg.aisec.ids.informationmodelmanager.deserializer,\ - !org.checkerframework.checker.*,\ - de.fraunhofer.iais.eis*,\ - org.apache.cxf.jaxrs.security,\ - org.apache.cxf.interceptor.security,\ - com.fasterxml.jackson.jaxrs.json,\ - com.fasterxml.jackson.databind,\ - !io.swagger.annotations,\ - * -Private-Package: \ - com.auth0.* -Web-ContextPath: / --wab: build/resources/main/www/ diff --git a/ids-webconsole/build.gradle.kts b/ids-webconsole/build.gradle.kts index 23ad2ce25..53ae5e960 100644 --- a/ids-webconsole/build.gradle.kts +++ b/ids-webconsole/build.gradle.kts @@ -122,38 +122,38 @@ node { } val yarnInstall by tasks.registering(YarnTask::class) { - inputs.file("src/main/resources/www/package.json").withPathSensitivity(PathSensitivity.RELATIVE) - inputs.file("src/main/resources/www/yarn.lock").withPathSensitivity(PathSensitivity.RELATIVE) - outputs.dir("src/main/resources/www/node_modules") + inputs.file("src/main/angular/package.json").withPathSensitivity(PathSensitivity.RELATIVE) + inputs.file("src/main/angular/yarn.lock").withPathSensitivity(PathSensitivity.RELATIVE) + outputs.dir("src/main/angular/node_modules") outputs.cacheIf { true } - workingDir.set(file("src/main/resources/www")) + workingDir.set(file("src/main/angular")) yarnCommand.set(listOf("install", "--ignore-optional")) onlyIf { !rootProject.hasProperty("skipAngular") } } val yarnLint by tasks.registering(YarnTask::class) { - inputs.file("src/main/resources/www/package.json").withPathSensitivity(PathSensitivity.RELATIVE) - inputs.file("src/main/resources/www/yarn.lock").withPathSensitivity(PathSensitivity.RELATIVE) - inputs.file("src/main/resources/www/tslint.json").withPathSensitivity(PathSensitivity.RELATIVE) - inputs.dir("src/main/resources/www/src").withPathSensitivity(PathSensitivity.RELATIVE) + inputs.file("src/main/angular/package.json").withPathSensitivity(PathSensitivity.RELATIVE) + inputs.file("src/main/angular/yarn.lock").withPathSensitivity(PathSensitivity.RELATIVE) + inputs.file("src/main/angular/tslint.json").withPathSensitivity(PathSensitivity.RELATIVE) + inputs.dir("src/main/angular/src").withPathSensitivity(PathSensitivity.RELATIVE) outputs.upToDateWhen { true } outputs.cacheIf { true } - workingDir.set(file("src/main/resources/www")) + workingDir.set(file("src/main/angular")) yarnCommand.set(listOf("lint")) onlyIf { !rootProject.hasProperty("skipAngular") } } val yarnBuild by tasks.registering(YarnTask::class) { - inputs.file("src/main/resources/www/package.json").withPathSensitivity(PathSensitivity.RELATIVE) - inputs.file("src/main/resources/www/yarn.lock").withPathSensitivity(PathSensitivity.RELATIVE) - inputs.file("src/main/resources/www/angular.json").withPathSensitivity(PathSensitivity.RELATIVE) - inputs.dir("src/main/resources/www/src").withPathSensitivity(PathSensitivity.RELATIVE) + inputs.file("src/main/angular/package.json").withPathSensitivity(PathSensitivity.RELATIVE) + inputs.file("src/main/angular/yarn.lock").withPathSensitivity(PathSensitivity.RELATIVE) + inputs.file("src/main/angular/angular.json").withPathSensitivity(PathSensitivity.RELATIVE) + inputs.dir("src/main/angular/src").withPathSensitivity(PathSensitivity.RELATIVE) outputs.dir("build/resources/main/www") outputs.cacheIf { true } - workingDir.set(file("src/main/resources/www")) + workingDir.set(file("src/main/angular")) yarnCommand.set(listOf("bundle")) onlyIf { !rootProject.hasProperty("skipAngular") } diff --git a/ids-webconsole/src/main/resources/www/.browserslistrc b/ids-webconsole/src/main/angular/.browserslistrc similarity index 100% rename from ids-webconsole/src/main/resources/www/.browserslistrc rename to ids-webconsole/src/main/angular/.browserslistrc diff --git a/ids-webconsole/src/main/resources/www/.dockerignore b/ids-webconsole/src/main/angular/.dockerignore similarity index 100% rename from ids-webconsole/src/main/resources/www/.dockerignore rename to ids-webconsole/src/main/angular/.dockerignore diff --git a/ids-webconsole/src/main/resources/www/.editorconfig b/ids-webconsole/src/main/angular/.editorconfig similarity index 100% rename from ids-webconsole/src/main/resources/www/.editorconfig rename to ids-webconsole/src/main/angular/.editorconfig diff --git a/ids-webconsole/src/main/resources/www/.gitignore b/ids-webconsole/src/main/angular/.gitignore similarity index 100% rename from ids-webconsole/src/main/resources/www/.gitignore rename to ids-webconsole/src/main/angular/.gitignore diff --git a/ids-webconsole/src/main/resources/www/Dockerfile b/ids-webconsole/src/main/angular/Dockerfile similarity index 100% rename from ids-webconsole/src/main/resources/www/Dockerfile rename to ids-webconsole/src/main/angular/Dockerfile diff --git a/ids-webconsole/src/main/resources/www/README.md b/ids-webconsole/src/main/angular/README.md similarity index 100% rename from ids-webconsole/src/main/resources/www/README.md rename to ids-webconsole/src/main/angular/README.md diff --git a/ids-webconsole/src/main/resources/www/angular.json b/ids-webconsole/src/main/angular/angular.json similarity index 100% rename from ids-webconsole/src/main/resources/www/angular.json rename to ids-webconsole/src/main/angular/angular.json diff --git a/ids-webconsole/src/main/resources/www/package.json b/ids-webconsole/src/main/angular/package.json similarity index 97% rename from ids-webconsole/src/main/resources/www/package.json rename to ids-webconsole/src/main/angular/package.json index 0308263a9..28af59942 100644 --- a/ids-webconsole/src/main/resources/www/package.json +++ b/ids-webconsole/src/main/angular/package.json @@ -6,7 +6,7 @@ "scripts": { "ng": "ng", "start": "ng serve", - "bundle": "ng build --prod --no-progress --output-path=\"../../../../build/resources/main/www\"", + "bundle": "ng build --prod --no-progress --output-path=\"../../../build/resources/main/www\"", "lint": "ng lint" }, "private": true, diff --git a/ids-webconsole/src/main/resources/www/proxy.conf.json b/ids-webconsole/src/main/angular/proxy.conf.json similarity index 100% rename from ids-webconsole/src/main/resources/www/proxy.conf.json rename to ids-webconsole/src/main/angular/proxy.conf.json diff --git a/ids-webconsole/src/main/resources/OSGI-INF/blueprint/rest.xml b/ids-webconsole/src/main/angular/rest.xml similarity index 100% rename from ids-webconsole/src/main/resources/OSGI-INF/blueprint/rest.xml rename to ids-webconsole/src/main/angular/rest.xml diff --git a/ids-webconsole/src/main/resources/www/src/app/_guards/auth.guard.ts b/ids-webconsole/src/main/angular/src/app/_guards/auth.guard.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/_guards/auth.guard.ts rename to ids-webconsole/src/main/angular/src/app/_guards/auth.guard.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/_interceptors/jwt.interceptor.ts b/ids-webconsole/src/main/angular/src/app/_interceptors/jwt.interceptor.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/_interceptors/jwt.interceptor.ts rename to ids-webconsole/src/main/angular/src/app/_interceptors/jwt.interceptor.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/app.component.css b/ids-webconsole/src/main/angular/src/app/app.component.css similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/app.component.css rename to ids-webconsole/src/main/angular/src/app/app.component.css diff --git a/ids-webconsole/src/main/resources/www/src/app/app.component.ts b/ids-webconsole/src/main/angular/src/app/app.component.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/app.component.ts rename to ids-webconsole/src/main/angular/src/app/app.component.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/app.module.ts b/ids-webconsole/src/main/angular/src/app/app.module.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/app.module.ts rename to ids-webconsole/src/main/angular/src/app/app.module.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/app.routing.ts b/ids-webconsole/src/main/angular/src/app/app.routing.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/app.routing.ts rename to ids-webconsole/src/main/angular/src/app/app.routing.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/application-http-client.service.ts b/ids-webconsole/src/main/angular/src/app/application-http-client.service.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/application-http-client.service.ts rename to ids-webconsole/src/main/angular/src/app/application-http-client.service.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/apps/app-card.component.html b/ids-webconsole/src/main/angular/src/app/apps/app-card.component.html similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/apps/app-card.component.html rename to ids-webconsole/src/main/angular/src/app/apps/app-card.component.html diff --git a/ids-webconsole/src/main/resources/www/src/app/apps/app-card.component.ts b/ids-webconsole/src/main/angular/src/app/apps/app-card.component.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/apps/app-card.component.ts rename to ids-webconsole/src/main/angular/src/app/apps/app-card.component.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/apps/app-search-result-card.component.css b/ids-webconsole/src/main/angular/src/app/apps/app-search-result-card.component.css similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/apps/app-search-result-card.component.css rename to ids-webconsole/src/main/angular/src/app/apps/app-search-result-card.component.css diff --git a/ids-webconsole/src/main/resources/www/src/app/apps/app-search-result-card.component.html b/ids-webconsole/src/main/angular/src/app/apps/app-search-result-card.component.html similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/apps/app-search-result-card.component.html rename to ids-webconsole/src/main/angular/src/app/apps/app-search-result-card.component.html diff --git a/ids-webconsole/src/main/resources/www/src/app/apps/app-search-result-card.component.ts b/ids-webconsole/src/main/angular/src/app/apps/app-search-result-card.component.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/apps/app-search-result-card.component.ts rename to ids-webconsole/src/main/angular/src/app/apps/app-search-result-card.component.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/apps/app-status.ts b/ids-webconsole/src/main/angular/src/app/apps/app-status.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/apps/app-status.ts rename to ids-webconsole/src/main/angular/src/app/apps/app-status.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/apps/app.port.def.ts b/ids-webconsole/src/main/angular/src/app/apps/app.port.def.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/apps/app.port.def.ts rename to ids-webconsole/src/main/angular/src/app/apps/app.port.def.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/apps/app.service.ts b/ids-webconsole/src/main/angular/src/app/apps/app.service.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/apps/app.service.ts rename to ids-webconsole/src/main/angular/src/app/apps/app.service.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/apps/app.ts b/ids-webconsole/src/main/angular/src/app/apps/app.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/apps/app.ts rename to ids-webconsole/src/main/angular/src/app/apps/app.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/apps/apps-search.component.html b/ids-webconsole/src/main/angular/src/app/apps/apps-search.component.html similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/apps/apps-search.component.html rename to ids-webconsole/src/main/angular/src/app/apps/apps-search.component.html diff --git a/ids-webconsole/src/main/resources/www/src/app/apps/apps-search.component.ts b/ids-webconsole/src/main/angular/src/app/apps/apps-search.component.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/apps/apps-search.component.ts rename to ids-webconsole/src/main/angular/src/app/apps/apps-search.component.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/apps/apps.component.html b/ids-webconsole/src/main/angular/src/app/apps/apps.component.html similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/apps/apps.component.html rename to ids-webconsole/src/main/angular/src/app/apps/apps.component.html diff --git a/ids-webconsole/src/main/resources/www/src/app/apps/apps.component.ts b/ids-webconsole/src/main/angular/src/app/apps/apps.component.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/apps/apps.component.ts rename to ids-webconsole/src/main/angular/src/app/apps/apps.component.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/apps/cml.ts b/ids-webconsole/src/main/angular/src/app/apps/cml.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/apps/cml.ts rename to ids-webconsole/src/main/angular/src/app/apps/cml.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/confirm/confirm.component.css b/ids-webconsole/src/main/angular/src/app/confirm/confirm.component.css similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/confirm/confirm.component.css rename to ids-webconsole/src/main/angular/src/app/confirm/confirm.component.css diff --git a/ids-webconsole/src/main/resources/www/src/app/confirm/confirm.component.html b/ids-webconsole/src/main/angular/src/app/confirm/confirm.component.html similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/confirm/confirm.component.html rename to ids-webconsole/src/main/angular/src/app/confirm/confirm.component.html diff --git a/ids-webconsole/src/main/resources/www/src/app/confirm/confirm.component.ts b/ids-webconsole/src/main/angular/src/app/confirm/confirm.component.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/confirm/confirm.component.ts rename to ids-webconsole/src/main/angular/src/app/confirm/confirm.component.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/confirm/confirm.service.ts b/ids-webconsole/src/main/angular/src/app/confirm/confirm.service.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/confirm/confirm.service.ts rename to ids-webconsole/src/main/angular/src/app/confirm/confirm.service.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/connection-configuration/configuration.ts b/ids-webconsole/src/main/angular/src/app/connection-configuration/configuration.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/connection-configuration/configuration.ts rename to ids-webconsole/src/main/angular/src/app/connection-configuration/configuration.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/connection-configuration/connection-configuration.component.css b/ids-webconsole/src/main/angular/src/app/connection-configuration/connection-configuration.component.css similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/connection-configuration/connection-configuration.component.css rename to ids-webconsole/src/main/angular/src/app/connection-configuration/connection-configuration.component.css diff --git a/ids-webconsole/src/main/resources/www/src/app/connection-configuration/connection-configuration.component.html b/ids-webconsole/src/main/angular/src/app/connection-configuration/connection-configuration.component.html similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/connection-configuration/connection-configuration.component.html rename to ids-webconsole/src/main/angular/src/app/connection-configuration/connection-configuration.component.html diff --git a/ids-webconsole/src/main/resources/www/src/app/connection-configuration/connection-configuration.component.ts b/ids-webconsole/src/main/angular/src/app/connection-configuration/connection-configuration.component.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/connection-configuration/connection-configuration.component.ts rename to ids-webconsole/src/main/angular/src/app/connection-configuration/connection-configuration.component.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/connection-configuration/connection-configuration.service.ts b/ids-webconsole/src/main/angular/src/app/connection-configuration/connection-configuration.service.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/connection-configuration/connection-configuration.service.ts rename to ids-webconsole/src/main/angular/src/app/connection-configuration/connection-configuration.service.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/connection-configuration/settings.interface.ts b/ids-webconsole/src/main/angular/src/app/connection-configuration/settings.interface.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/connection-configuration/settings.interface.ts rename to ids-webconsole/src/main/angular/src/app/connection-configuration/settings.interface.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/connection-report/connection-report.component.css b/ids-webconsole/src/main/angular/src/app/connection-report/connection-report.component.css similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/connection-report/connection-report.component.css rename to ids-webconsole/src/main/angular/src/app/connection-report/connection-report.component.css diff --git a/ids-webconsole/src/main/resources/www/src/app/connection-report/connection-report.component.html b/ids-webconsole/src/main/angular/src/app/connection-report/connection-report.component.html similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/connection-report/connection-report.component.html rename to ids-webconsole/src/main/angular/src/app/connection-report/connection-report.component.html diff --git a/ids-webconsole/src/main/resources/www/src/app/connection-report/connection-report.component.ts b/ids-webconsole/src/main/angular/src/app/connection-report/connection-report.component.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/connection-report/connection-report.component.ts rename to ids-webconsole/src/main/angular/src/app/connection-report/connection-report.component.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/connection-report/connection-report.service.ts b/ids-webconsole/src/main/angular/src/app/connection-report/connection-report.service.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/connection-report/connection-report.service.ts rename to ids-webconsole/src/main/angular/src/app/connection-report/connection-report.service.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/connection-report/endpoint.ts b/ids-webconsole/src/main/angular/src/app/connection-report/endpoint.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/connection-report/endpoint.ts rename to ids-webconsole/src/main/angular/src/app/connection-report/endpoint.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/connection-report/incoming-connection.ts b/ids-webconsole/src/main/angular/src/app/connection-report/incoming-connection.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/connection-report/incoming-connection.ts rename to ids-webconsole/src/main/angular/src/app/connection-report/incoming-connection.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/connection-report/outgoing-connection.ts b/ids-webconsole/src/main/angular/src/app/connection-report/outgoing-connection.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/connection-report/outgoing-connection.ts rename to ids-webconsole/src/main/angular/src/app/connection-report/outgoing-connection.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/dashboard/dashboard.component.html b/ids-webconsole/src/main/angular/src/app/dashboard/dashboard.component.html similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/dashboard/dashboard.component.html rename to ids-webconsole/src/main/angular/src/app/dashboard/dashboard.component.html diff --git a/ids-webconsole/src/main/resources/www/src/app/dashboard/dashboard.component.ts b/ids-webconsole/src/main/angular/src/app/dashboard/dashboard.component.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/dashboard/dashboard.component.ts rename to ids-webconsole/src/main/angular/src/app/dashboard/dashboard.component.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/dashboard/metric-card.component.html b/ids-webconsole/src/main/angular/src/app/dashboard/metric-card.component.html similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/dashboard/metric-card.component.html rename to ids-webconsole/src/main/angular/src/app/dashboard/metric-card.component.html diff --git a/ids-webconsole/src/main/resources/www/src/app/dashboard/metric-card.component.ts b/ids-webconsole/src/main/angular/src/app/dashboard/metric-card.component.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/dashboard/metric-card.component.ts rename to ids-webconsole/src/main/angular/src/app/dashboard/metric-card.component.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/dataflowpolicies/dataflowpolicies.component.html b/ids-webconsole/src/main/angular/src/app/dataflowpolicies/dataflowpolicies.component.html similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/dataflowpolicies/dataflowpolicies.component.html rename to ids-webconsole/src/main/angular/src/app/dataflowpolicies/dataflowpolicies.component.html diff --git a/ids-webconsole/src/main/resources/www/src/app/dataflowpolicies/dataflowpolicies.component.ts b/ids-webconsole/src/main/angular/src/app/dataflowpolicies/dataflowpolicies.component.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/dataflowpolicies/dataflowpolicies.component.ts rename to ids-webconsole/src/main/angular/src/app/dataflowpolicies/dataflowpolicies.component.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/dataflowpolicies/dataflowpoliciesnew.component.html b/ids-webconsole/src/main/angular/src/app/dataflowpolicies/dataflowpoliciesnew.component.html similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/dataflowpolicies/dataflowpoliciesnew.component.html rename to ids-webconsole/src/main/angular/src/app/dataflowpolicies/dataflowpoliciesnew.component.html diff --git a/ids-webconsole/src/main/resources/www/src/app/dataflowpolicies/dataflowpoliciesnew.component.ts b/ids-webconsole/src/main/angular/src/app/dataflowpolicies/dataflowpoliciesnew.component.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/dataflowpolicies/dataflowpoliciesnew.component.ts rename to ids-webconsole/src/main/angular/src/app/dataflowpolicies/dataflowpoliciesnew.component.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/dataflowpolicies/policy.interface.ts b/ids-webconsole/src/main/angular/src/app/dataflowpolicies/policy.interface.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/dataflowpolicies/policy.interface.ts rename to ids-webconsole/src/main/angular/src/app/dataflowpolicies/policy.interface.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/dataflowpolicies/policy.service.ts b/ids-webconsole/src/main/angular/src/app/dataflowpolicies/policy.service.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/dataflowpolicies/policy.service.ts rename to ids-webconsole/src/main/angular/src/app/dataflowpolicies/policy.service.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/ids/ids.component.css b/ids-webconsole/src/main/angular/src/app/ids/ids.component.css similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/ids/ids.component.css rename to ids-webconsole/src/main/angular/src/app/ids/ids.component.css diff --git a/ids-webconsole/src/main/resources/www/src/app/ids/ids.component.html b/ids-webconsole/src/main/angular/src/app/ids/ids.component.html similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/ids/ids.component.html rename to ids-webconsole/src/main/angular/src/app/ids/ids.component.html diff --git a/ids-webconsole/src/main/resources/www/src/app/ids/ids.component.ts b/ids-webconsole/src/main/angular/src/app/ids/ids.component.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/ids/ids.component.ts rename to ids-webconsole/src/main/angular/src/app/ids/ids.component.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/ids/settings.interface.ts b/ids-webconsole/src/main/angular/src/app/ids/settings.interface.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/ids/settings.interface.ts rename to ids-webconsole/src/main/angular/src/app/ids/settings.interface.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/ids/settings.service.ts b/ids-webconsole/src/main/angular/src/app/ids/settings.service.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/ids/settings.service.ts rename to ids-webconsole/src/main/angular/src/app/ids/settings.service.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/ids/terms-of-service.interface.ts b/ids-webconsole/src/main/angular/src/app/ids/terms-of-service.interface.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/ids/terms-of-service.interface.ts rename to ids-webconsole/src/main/angular/src/app/ids/terms-of-service.interface.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/keycerts/cert-upload.component.html b/ids-webconsole/src/main/angular/src/app/keycerts/cert-upload.component.html similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/keycerts/cert-upload.component.html rename to ids-webconsole/src/main/angular/src/app/keycerts/cert-upload.component.html diff --git a/ids-webconsole/src/main/resources/www/src/app/keycerts/cert-upload.component.ts b/ids-webconsole/src/main/angular/src/app/keycerts/cert-upload.component.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/keycerts/cert-upload.component.ts rename to ids-webconsole/src/main/angular/src/app/keycerts/cert-upload.component.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/keycerts/certificate-card.component.css b/ids-webconsole/src/main/angular/src/app/keycerts/certificate-card.component.css similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/keycerts/certificate-card.component.css rename to ids-webconsole/src/main/angular/src/app/keycerts/certificate-card.component.css diff --git a/ids-webconsole/src/main/resources/www/src/app/keycerts/certificate-card.component.html b/ids-webconsole/src/main/angular/src/app/keycerts/certificate-card.component.html similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/keycerts/certificate-card.component.html rename to ids-webconsole/src/main/angular/src/app/keycerts/certificate-card.component.html diff --git a/ids-webconsole/src/main/resources/www/src/app/keycerts/certificate-card.component.ts b/ids-webconsole/src/main/angular/src/app/keycerts/certificate-card.component.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/keycerts/certificate-card.component.ts rename to ids-webconsole/src/main/angular/src/app/keycerts/certificate-card.component.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/keycerts/certificate.ts b/ids-webconsole/src/main/angular/src/app/keycerts/certificate.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/keycerts/certificate.ts rename to ids-webconsole/src/main/angular/src/app/keycerts/certificate.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/keycerts/identity.interface.ts b/ids-webconsole/src/main/angular/src/app/keycerts/identity.interface.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/keycerts/identity.interface.ts rename to ids-webconsole/src/main/angular/src/app/keycerts/identity.interface.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/keycerts/identitynew.component.html b/ids-webconsole/src/main/angular/src/app/keycerts/identitynew.component.html similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/keycerts/identitynew.component.html rename to ids-webconsole/src/main/angular/src/app/keycerts/identitynew.component.html diff --git a/ids-webconsole/src/main/resources/www/src/app/keycerts/identitynew.component.ts b/ids-webconsole/src/main/angular/src/app/keycerts/identitynew.component.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/keycerts/identitynew.component.ts rename to ids-webconsole/src/main/angular/src/app/keycerts/identitynew.component.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/keycerts/keycert.service.ts b/ids-webconsole/src/main/angular/src/app/keycerts/keycert.service.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/keycerts/keycert.service.ts rename to ids-webconsole/src/main/angular/src/app/keycerts/keycert.service.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/keycerts/keycerts.component.html b/ids-webconsole/src/main/angular/src/app/keycerts/keycerts.component.html similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/keycerts/keycerts.component.html rename to ids-webconsole/src/main/angular/src/app/keycerts/keycerts.component.html diff --git a/ids-webconsole/src/main/resources/www/src/app/keycerts/keycerts.component.ts b/ids-webconsole/src/main/angular/src/app/keycerts/keycerts.component.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/keycerts/keycerts.component.ts rename to ids-webconsole/src/main/angular/src/app/keycerts/keycerts.component.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/layouts/home-layout/home-layout.component.html b/ids-webconsole/src/main/angular/src/app/layouts/home-layout/home-layout.component.html similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/layouts/home-layout/home-layout.component.html rename to ids-webconsole/src/main/angular/src/app/layouts/home-layout/home-layout.component.html diff --git a/ids-webconsole/src/main/resources/www/src/app/layouts/home-layout/home-layout.component.ts b/ids-webconsole/src/main/angular/src/app/layouts/home-layout/home-layout.component.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/layouts/home-layout/home-layout.component.ts rename to ids-webconsole/src/main/angular/src/app/layouts/home-layout/home-layout.component.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/layouts/login-layout/login-layout.component.html b/ids-webconsole/src/main/angular/src/app/layouts/login-layout/login-layout.component.html similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/layouts/login-layout/login-layout.component.html rename to ids-webconsole/src/main/angular/src/app/layouts/login-layout/login-layout.component.html diff --git a/ids-webconsole/src/main/resources/www/src/app/layouts/login-layout/login-layout.component.ts b/ids-webconsole/src/main/angular/src/app/layouts/login-layout/login-layout.component.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/layouts/login-layout/login-layout.component.ts rename to ids-webconsole/src/main/angular/src/app/layouts/login-layout/login-layout.component.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/login/login.component.html b/ids-webconsole/src/main/angular/src/app/login/login.component.html similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/login/login.component.html rename to ids-webconsole/src/main/angular/src/app/login/login.component.html diff --git a/ids-webconsole/src/main/resources/www/src/app/login/login.component.ts b/ids-webconsole/src/main/angular/src/app/login/login.component.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/login/login.component.ts rename to ids-webconsole/src/main/angular/src/app/login/login.component.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/login/login.service.ts b/ids-webconsole/src/main/angular/src/app/login/login.service.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/login/login.service.ts rename to ids-webconsole/src/main/angular/src/app/login/login.service.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/login/token.interface.ts b/ids-webconsole/src/main/angular/src/app/login/token.interface.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/login/token.interface.ts rename to ids-webconsole/src/main/angular/src/app/login/token.interface.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/mdl-upgrade-element-directive.ts b/ids-webconsole/src/main/angular/src/app/mdl-upgrade-element-directive.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/mdl-upgrade-element-directive.ts rename to ids-webconsole/src/main/angular/src/app/mdl-upgrade-element-directive.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/metric/metric.service.ts b/ids-webconsole/src/main/angular/src/app/metric/metric.service.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/metric/metric.service.ts rename to ids-webconsole/src/main/angular/src/app/metric/metric.service.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/prettify-json.pipe.ts b/ids-webconsole/src/main/angular/src/app/prettify-json.pipe.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/prettify-json.pipe.ts rename to ids-webconsole/src/main/angular/src/app/prettify-json.pipe.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/result.ts b/ids-webconsole/src/main/angular/src/app/result.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/result.ts rename to ids-webconsole/src/main/angular/src/app/result.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/route-result.ts b/ids-webconsole/src/main/angular/src/app/route-result.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/route-result.ts rename to ids-webconsole/src/main/angular/src/app/route-result.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/routes/counter-example.ts b/ids-webconsole/src/main/angular/src/app/routes/counter-example.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/routes/counter-example.ts rename to ids-webconsole/src/main/angular/src/app/routes/counter-example.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/routes/route-card/route-card.component.css b/ids-webconsole/src/main/angular/src/app/routes/route-card/route-card.component.css similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/routes/route-card/route-card.component.css rename to ids-webconsole/src/main/angular/src/app/routes/route-card/route-card.component.css diff --git a/ids-webconsole/src/main/resources/www/src/app/routes/route-card/route-card.component.html b/ids-webconsole/src/main/angular/src/app/routes/route-card/route-card.component.html similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/routes/route-card/route-card.component.html rename to ids-webconsole/src/main/angular/src/app/routes/route-card/route-card.component.html diff --git a/ids-webconsole/src/main/resources/www/src/app/routes/route-card/route-card.component.ts b/ids-webconsole/src/main/angular/src/app/routes/route-card/route-card.component.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/routes/route-card/route-card.component.ts rename to ids-webconsole/src/main/angular/src/app/routes/route-card/route-card.component.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/routes/route-metrics.ts b/ids-webconsole/src/main/angular/src/app/routes/route-metrics.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/routes/route-metrics.ts rename to ids-webconsole/src/main/angular/src/app/routes/route-metrics.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/routes/route.service.ts b/ids-webconsole/src/main/angular/src/app/routes/route.service.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/routes/route.service.ts rename to ids-webconsole/src/main/angular/src/app/routes/route.service.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/routes/route.ts b/ids-webconsole/src/main/angular/src/app/routes/route.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/routes/route.ts rename to ids-webconsole/src/main/angular/src/app/routes/route.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/routes/routeeditor/routeeditor.component.css b/ids-webconsole/src/main/angular/src/app/routes/routeeditor/routeeditor.component.css similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/routes/routeeditor/routeeditor.component.css rename to ids-webconsole/src/main/angular/src/app/routes/routeeditor/routeeditor.component.css diff --git a/ids-webconsole/src/main/resources/www/src/app/routes/routeeditor/routeeditor.component.html b/ids-webconsole/src/main/angular/src/app/routes/routeeditor/routeeditor.component.html similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/routes/routeeditor/routeeditor.component.html rename to ids-webconsole/src/main/angular/src/app/routes/routeeditor/routeeditor.component.html diff --git a/ids-webconsole/src/main/resources/www/src/app/routes/routeeditor/routeeditor.component.ts b/ids-webconsole/src/main/angular/src/app/routes/routeeditor/routeeditor.component.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/routes/routeeditor/routeeditor.component.ts rename to ids-webconsole/src/main/angular/src/app/routes/routeeditor/routeeditor.component.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/routes/routes.component.css b/ids-webconsole/src/main/angular/src/app/routes/routes.component.css similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/routes/routes.component.css rename to ids-webconsole/src/main/angular/src/app/routes/routes.component.css diff --git a/ids-webconsole/src/main/resources/www/src/app/routes/routes.component.html b/ids-webconsole/src/main/angular/src/app/routes/routes.component.html similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/routes/routes.component.html rename to ids-webconsole/src/main/angular/src/app/routes/routes.component.html diff --git a/ids-webconsole/src/main/resources/www/src/app/routes/routes.component.ts b/ids-webconsole/src/main/angular/src/app/routes/routes.component.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/routes/routes.component.ts rename to ids-webconsole/src/main/angular/src/app/routes/routes.component.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/routes/validation-info.ts b/ids-webconsole/src/main/angular/src/app/routes/validation-info.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/routes/validation-info.ts rename to ids-webconsole/src/main/angular/src/app/routes/validation-info.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/routes/zoom-viz/zoom-viz.component.css b/ids-webconsole/src/main/angular/src/app/routes/zoom-viz/zoom-viz.component.css similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/routes/zoom-viz/zoom-viz.component.css rename to ids-webconsole/src/main/angular/src/app/routes/zoom-viz/zoom-viz.component.css diff --git a/ids-webconsole/src/main/resources/www/src/app/routes/zoom-viz/zoom-viz.component.html b/ids-webconsole/src/main/angular/src/app/routes/zoom-viz/zoom-viz.component.html similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/routes/zoom-viz/zoom-viz.component.html rename to ids-webconsole/src/main/angular/src/app/routes/zoom-viz/zoom-viz.component.html diff --git a/ids-webconsole/src/main/resources/www/src/app/routes/zoom-viz/zoom-viz.component.ts b/ids-webconsole/src/main/angular/src/app/routes/zoom-viz/zoom-viz.component.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/routes/zoom-viz/zoom-viz.component.ts rename to ids-webconsole/src/main/angular/src/app/routes/zoom-viz/zoom-viz.component.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/sensor/sensor.service.ts b/ids-webconsole/src/main/angular/src/app/sensor/sensor.service.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/sensor/sensor.service.ts rename to ids-webconsole/src/main/angular/src/app/sensor/sensor.service.ts diff --git a/ids-webconsole/src/main/resources/www/src/app/values.pipe.ts b/ids-webconsole/src/main/angular/src/app/values.pipe.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/app/values.pipe.ts rename to ids-webconsole/src/main/angular/src/app/values.pipe.ts diff --git a/ids-webconsole/src/main/resources/www/src/css/fontawesome/all.css b/ids-webconsole/src/main/angular/src/css/fontawesome/all.css similarity index 100% rename from ids-webconsole/src/main/resources/www/src/css/fontawesome/all.css rename to ids-webconsole/src/main/angular/src/css/fontawesome/all.css diff --git a/ids-webconsole/src/main/resources/www/src/css/material.teal-pink.min.css b/ids-webconsole/src/main/angular/src/css/material.teal-pink.min.css similarity index 100% rename from ids-webconsole/src/main/resources/www/src/css/material.teal-pink.min.css rename to ids-webconsole/src/main/angular/src/css/material.teal-pink.min.css diff --git a/ids-webconsole/src/main/resources/www/src/css/styles.css b/ids-webconsole/src/main/angular/src/css/styles.css similarity index 100% rename from ids-webconsole/src/main/resources/www/src/css/styles.css rename to ids-webconsole/src/main/angular/src/css/styles.css diff --git a/ids-webconsole/src/main/resources/www/src/css/webfonts/fa-brands-400.eot b/ids-webconsole/src/main/angular/src/css/webfonts/fa-brands-400.eot similarity index 100% rename from ids-webconsole/src/main/resources/www/src/css/webfonts/fa-brands-400.eot rename to ids-webconsole/src/main/angular/src/css/webfonts/fa-brands-400.eot diff --git a/ids-webconsole/src/main/resources/www/src/css/webfonts/fa-brands-400.svg b/ids-webconsole/src/main/angular/src/css/webfonts/fa-brands-400.svg similarity index 100% rename from ids-webconsole/src/main/resources/www/src/css/webfonts/fa-brands-400.svg rename to ids-webconsole/src/main/angular/src/css/webfonts/fa-brands-400.svg diff --git a/ids-webconsole/src/main/resources/www/src/css/webfonts/fa-brands-400.ttf b/ids-webconsole/src/main/angular/src/css/webfonts/fa-brands-400.ttf similarity index 100% rename from ids-webconsole/src/main/resources/www/src/css/webfonts/fa-brands-400.ttf rename to ids-webconsole/src/main/angular/src/css/webfonts/fa-brands-400.ttf diff --git a/ids-webconsole/src/main/resources/www/src/css/webfonts/fa-brands-400.woff b/ids-webconsole/src/main/angular/src/css/webfonts/fa-brands-400.woff similarity index 100% rename from ids-webconsole/src/main/resources/www/src/css/webfonts/fa-brands-400.woff rename to ids-webconsole/src/main/angular/src/css/webfonts/fa-brands-400.woff diff --git a/ids-webconsole/src/main/resources/www/src/css/webfonts/fa-brands-400.woff2 b/ids-webconsole/src/main/angular/src/css/webfonts/fa-brands-400.woff2 similarity index 100% rename from ids-webconsole/src/main/resources/www/src/css/webfonts/fa-brands-400.woff2 rename to ids-webconsole/src/main/angular/src/css/webfonts/fa-brands-400.woff2 diff --git a/ids-webconsole/src/main/resources/www/src/css/webfonts/fa-regular-400.eot b/ids-webconsole/src/main/angular/src/css/webfonts/fa-regular-400.eot similarity index 100% rename from ids-webconsole/src/main/resources/www/src/css/webfonts/fa-regular-400.eot rename to ids-webconsole/src/main/angular/src/css/webfonts/fa-regular-400.eot diff --git a/ids-webconsole/src/main/resources/www/src/css/webfonts/fa-regular-400.svg b/ids-webconsole/src/main/angular/src/css/webfonts/fa-regular-400.svg similarity index 100% rename from ids-webconsole/src/main/resources/www/src/css/webfonts/fa-regular-400.svg rename to ids-webconsole/src/main/angular/src/css/webfonts/fa-regular-400.svg diff --git a/ids-webconsole/src/main/resources/www/src/css/webfonts/fa-regular-400.ttf b/ids-webconsole/src/main/angular/src/css/webfonts/fa-regular-400.ttf similarity index 100% rename from ids-webconsole/src/main/resources/www/src/css/webfonts/fa-regular-400.ttf rename to ids-webconsole/src/main/angular/src/css/webfonts/fa-regular-400.ttf diff --git a/ids-webconsole/src/main/resources/www/src/css/webfonts/fa-regular-400.woff b/ids-webconsole/src/main/angular/src/css/webfonts/fa-regular-400.woff similarity index 100% rename from ids-webconsole/src/main/resources/www/src/css/webfonts/fa-regular-400.woff rename to ids-webconsole/src/main/angular/src/css/webfonts/fa-regular-400.woff diff --git a/ids-webconsole/src/main/resources/www/src/css/webfonts/fa-regular-400.woff2 b/ids-webconsole/src/main/angular/src/css/webfonts/fa-regular-400.woff2 similarity index 100% rename from ids-webconsole/src/main/resources/www/src/css/webfonts/fa-regular-400.woff2 rename to ids-webconsole/src/main/angular/src/css/webfonts/fa-regular-400.woff2 diff --git a/ids-webconsole/src/main/resources/www/src/css/webfonts/fa-solid-900.eot b/ids-webconsole/src/main/angular/src/css/webfonts/fa-solid-900.eot similarity index 100% rename from ids-webconsole/src/main/resources/www/src/css/webfonts/fa-solid-900.eot rename to ids-webconsole/src/main/angular/src/css/webfonts/fa-solid-900.eot diff --git a/ids-webconsole/src/main/resources/www/src/css/webfonts/fa-solid-900.svg b/ids-webconsole/src/main/angular/src/css/webfonts/fa-solid-900.svg similarity index 100% rename from ids-webconsole/src/main/resources/www/src/css/webfonts/fa-solid-900.svg rename to ids-webconsole/src/main/angular/src/css/webfonts/fa-solid-900.svg diff --git a/ids-webconsole/src/main/resources/www/src/css/webfonts/fa-solid-900.ttf b/ids-webconsole/src/main/angular/src/css/webfonts/fa-solid-900.ttf similarity index 100% rename from ids-webconsole/src/main/resources/www/src/css/webfonts/fa-solid-900.ttf rename to ids-webconsole/src/main/angular/src/css/webfonts/fa-solid-900.ttf diff --git a/ids-webconsole/src/main/resources/www/src/css/webfonts/fa-solid-900.woff b/ids-webconsole/src/main/angular/src/css/webfonts/fa-solid-900.woff similarity index 100% rename from ids-webconsole/src/main/resources/www/src/css/webfonts/fa-solid-900.woff rename to ids-webconsole/src/main/angular/src/css/webfonts/fa-solid-900.woff diff --git a/ids-webconsole/src/main/resources/www/src/css/webfonts/fa-solid-900.woff2 b/ids-webconsole/src/main/angular/src/css/webfonts/fa-solid-900.woff2 similarity index 100% rename from ids-webconsole/src/main/resources/www/src/css/webfonts/fa-solid-900.woff2 rename to ids-webconsole/src/main/angular/src/css/webfonts/fa-solid-900.woff2 diff --git a/ids-webconsole/src/main/resources/www/src/data/eu.topo.json b/ids-webconsole/src/main/angular/src/data/eu.topo.json similarity index 100% rename from ids-webconsole/src/main/resources/www/src/data/eu.topo.json rename to ids-webconsole/src/main/angular/src/data/eu.topo.json diff --git a/ids-webconsole/src/main/resources/www/src/data/locations.tsv b/ids-webconsole/src/main/angular/src/data/locations.tsv similarity index 100% rename from ids-webconsole/src/main/resources/www/src/data/locations.tsv rename to ids-webconsole/src/main/angular/src/data/locations.tsv diff --git a/ids-webconsole/src/main/resources/www/src/data/topo_data.json b/ids-webconsole/src/main/angular/src/data/topo_data.json similarity index 100% rename from ids-webconsole/src/main/resources/www/src/data/topo_data.json rename to ids-webconsole/src/main/angular/src/data/topo_data.json diff --git a/ids-webconsole/src/main/resources/www/src/environments/environment.prod.ts b/ids-webconsole/src/main/angular/src/environments/environment.prod.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/environments/environment.prod.ts rename to ids-webconsole/src/main/angular/src/environments/environment.prod.ts diff --git a/ids-webconsole/src/main/resources/www/src/environments/environment.ts b/ids-webconsole/src/main/angular/src/environments/environment.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/environments/environment.ts rename to ids-webconsole/src/main/angular/src/environments/environment.ts diff --git a/ids-webconsole/src/main/resources/www/src/favicon.ico b/ids-webconsole/src/main/angular/src/favicon.ico similarity index 100% rename from ids-webconsole/src/main/resources/www/src/favicon.ico rename to ids-webconsole/src/main/angular/src/favicon.ico diff --git a/ids-webconsole/src/main/resources/www/src/fonts/LICENSE.txt b/ids-webconsole/src/main/angular/src/fonts/LICENSE.txt similarity index 100% rename from ids-webconsole/src/main/resources/www/src/fonts/LICENSE.txt rename to ids-webconsole/src/main/angular/src/fonts/LICENSE.txt diff --git a/ids-webconsole/src/main/resources/www/src/fonts/Material_Icons-normal-400.woff b/ids-webconsole/src/main/angular/src/fonts/Material_Icons-normal-400.woff similarity index 100% rename from ids-webconsole/src/main/resources/www/src/fonts/Material_Icons-normal-400.woff rename to ids-webconsole/src/main/angular/src/fonts/Material_Icons-normal-400.woff diff --git a/ids-webconsole/src/main/resources/www/src/fonts/Roboto-normal-300.woff b/ids-webconsole/src/main/angular/src/fonts/Roboto-normal-300.woff similarity index 100% rename from ids-webconsole/src/main/resources/www/src/fonts/Roboto-normal-300.woff rename to ids-webconsole/src/main/angular/src/fonts/Roboto-normal-300.woff diff --git a/ids-webconsole/src/main/resources/www/src/fonts/Roboto-normal-400.woff b/ids-webconsole/src/main/angular/src/fonts/Roboto-normal-400.woff similarity index 100% rename from ids-webconsole/src/main/resources/www/src/fonts/Roboto-normal-400.woff rename to ids-webconsole/src/main/angular/src/fonts/Roboto-normal-400.woff diff --git a/ids-webconsole/src/main/resources/www/src/fonts/Roboto-normal-500.woff b/ids-webconsole/src/main/angular/src/fonts/Roboto-normal-500.woff similarity index 100% rename from ids-webconsole/src/main/resources/www/src/fonts/Roboto-normal-500.woff rename to ids-webconsole/src/main/angular/src/fonts/Roboto-normal-500.woff diff --git a/ids-webconsole/src/main/resources/www/src/fonts/Roboto-normal-700.woff b/ids-webconsole/src/main/angular/src/fonts/Roboto-normal-700.woff similarity index 100% rename from ids-webconsole/src/main/resources/www/src/fonts/Roboto-normal-700.woff rename to ids-webconsole/src/main/angular/src/fonts/Roboto-normal-700.woff diff --git a/ids-webconsole/src/main/resources/www/src/fonts/fonts.css b/ids-webconsole/src/main/angular/src/fonts/fonts.css similarity index 100% rename from ids-webconsole/src/main/resources/www/src/fonts/fonts.css rename to ids-webconsole/src/main/angular/src/fonts/fonts.css diff --git a/ids-webconsole/src/main/resources/www/src/images/Account.png b/ids-webconsole/src/main/angular/src/images/Account.png similarity index 100% rename from ids-webconsole/src/main/resources/www/src/images/Account.png rename to ids-webconsole/src/main/angular/src/images/Account.png diff --git a/ids-webconsole/src/main/resources/www/src/images/Infrastructure.png b/ids-webconsole/src/main/angular/src/images/Infrastructure.png similarity index 100% rename from ids-webconsole/src/main/resources/www/src/images/Infrastructure.png rename to ids-webconsole/src/main/angular/src/images/Infrastructure.png diff --git a/ids-webconsole/src/main/resources/www/src/images/WebService.png b/ids-webconsole/src/main/angular/src/images/WebService.png similarity index 100% rename from ids-webconsole/src/main/resources/www/src/images/WebService.png rename to ids-webconsole/src/main/angular/src/images/WebService.png diff --git a/ids-webconsole/src/main/resources/www/src/images/aisec.jpg b/ids-webconsole/src/main/angular/src/images/aisec.jpg similarity index 100% rename from ids-webconsole/src/main/resources/www/src/images/aisec.jpg rename to ids-webconsole/src/main/angular/src/images/aisec.jpg diff --git a/ids-webconsole/src/main/resources/www/src/images/aisec.png b/ids-webconsole/src/main/angular/src/images/aisec.png similarity index 100% rename from ids-webconsole/src/main/resources/www/src/images/aisec.png rename to ids-webconsole/src/main/angular/src/images/aisec.png diff --git a/ids-webconsole/src/main/resources/www/src/index.html b/ids-webconsole/src/main/angular/src/index.html similarity index 100% rename from ids-webconsole/src/main/resources/www/src/index.html rename to ids-webconsole/src/main/angular/src/index.html diff --git a/ids-webconsole/src/main/resources/www/src/main.ts b/ids-webconsole/src/main/angular/src/main.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/main.ts rename to ids-webconsole/src/main/angular/src/main.ts diff --git a/ids-webconsole/src/main/resources/www/src/polyfills.ts b/ids-webconsole/src/main/angular/src/polyfills.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/polyfills.ts rename to ids-webconsole/src/main/angular/src/polyfills.ts diff --git a/ids-webconsole/src/main/resources/www/src/tsconfig.json b/ids-webconsole/src/main/angular/src/tsconfig.json similarity index 100% rename from ids-webconsole/src/main/resources/www/src/tsconfig.json rename to ids-webconsole/src/main/angular/src/tsconfig.json diff --git a/ids-webconsole/src/main/resources/www/src/typings.d.ts b/ids-webconsole/src/main/angular/src/typings.d.ts similarity index 100% rename from ids-webconsole/src/main/resources/www/src/typings.d.ts rename to ids-webconsole/src/main/angular/src/typings.d.ts diff --git a/ids-webconsole/src/main/resources/www/tslint.json b/ids-webconsole/src/main/angular/tslint.json similarity index 100% rename from ids-webconsole/src/main/resources/www/tslint.json rename to ids-webconsole/src/main/angular/tslint.json diff --git a/ids-webconsole/src/main/resources/www/yarn.lock b/ids-webconsole/src/main/angular/yarn.lock similarity index 100% rename from ids-webconsole/src/main/resources/www/yarn.lock rename to ids-webconsole/src/main/angular/yarn.lock diff --git a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/Controller.kt b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/Controller.kt index 5c8cf567f..fe8e548c2 100644 --- a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/Controller.kt +++ b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/Controller.kt @@ -1,16 +1,34 @@ +/*- + * ========================LICENSE_START================================= + * ids-webconsole + * %% + * Copyright (C) 2021 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ package de.fhg.aisec.ids.webconsole -import de.fhg.aisec.ids.webconsole.api.* -import org.slf4j.LoggerFactory import org.springframework.stereotype.Controller import org.springframework.web.bind.annotation.RequestMapping -import javax.ws.rs.ApplicationPath @Controller class Controller { + /** + * This maps browser access to the web root to index.html + */ @RequestMapping("/") - fun c(model: Map?): String { - //return "index.html" - return "/www/src/app/login/login.component.html" + fun webRoot(): String { + return "/index.html" } -} \ No newline at end of file +} From 872ed1d0acaf8615232e9247253a455dc91e59b4 Mon Sep 17 00:00:00 2001 From: gbrost Date: Tue, 11 May 2021 14:52:23 +0200 Subject: [PATCH 31/54] Update README.md Added ids ready --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 5535ff51a..eda606fcf 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,11 @@ The _Trusted Connector_ is an Apache Karaf-based platform for the Industrial Int * Data flow- and data usage control * An Apache Camel component for secure communication and remote attestation between Connectors. +The _Trusted Connector_ has acquired the IDS_ready label. +https://github.com/industrial-data-space/trusted-connector-documentation/blob/master/docs/assets/img/IDS-ready-component.jpg + +![IDS_ready](https://github.com/industrial-data-space/trusted-connector-documentation/blob/master/docs/assets/img/IDS-ready-component.jpg?raw=true) + # How to build & run Please see the [Github documentation page](https://industrial-data-space.github.io/trusted-connector-documentation/docs/dev_core/) From d20830ec560c6ce930ffcfe067e9333d08377357 Mon Sep 17 00:00:00 2001 From: gbrost Date: Tue, 11 May 2021 14:55:58 +0200 Subject: [PATCH 32/54] Update README.md --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index eda606fcf..85fe04d59 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,6 @@ The _Trusted Connector_ is an Apache Karaf-based platform for the Industrial Int * An Apache Camel component for secure communication and remote attestation between Connectors. The _Trusted Connector_ has acquired the IDS_ready label. -https://github.com/industrial-data-space/trusted-connector-documentation/blob/master/docs/assets/img/IDS-ready-component.jpg ![IDS_ready](https://github.com/industrial-data-space/trusted-connector-documentation/blob/master/docs/assets/img/IDS-ready-component.jpg?raw=true) From 234d21c89a8d4df216dfbfc39a871579caf6d2ae Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Mon, 10 May 2021 21:25:57 +0200 Subject: [PATCH 33/54] Updated web console dependencies --- ids-webconsole/src/main/angular/yarn.lock | 2315 +++++++++++---------- 1 file changed, 1209 insertions(+), 1106 deletions(-) diff --git a/ids-webconsole/src/main/angular/yarn.lock b/ids-webconsole/src/main/angular/yarn.lock index 5e7ed5719..4b32c178b 100644 --- a/ids-webconsole/src/main/angular/yarn.lock +++ b/ids-webconsole/src/main/angular/yarn.lock @@ -2,23 +2,23 @@ # yarn lockfile v1 -"@angular-devkit/architect@0.1002.0": - version "0.1002.0" - resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.1002.0.tgz#470b78aaf79308a23da6a0d3935f2d1f85dcb212" - integrity sha512-twM8V03ujBIGVpgV1PBlSDodUdxtUb7WakutfWafAvEHUsgwzfvQz2VtKWvjNZ9AiYjnCuwkQaclqVv0VHNo9w== +"@angular-devkit/architect@0.1002.3": + version "0.1002.3" + resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.1002.3.tgz#fe8f3209ee6686efa0306410de27820b6606df52" + integrity sha512-7ainXRNO1njZ6bBbJXGpMzCh0OYrzuIRe/+zRj0ncV1YfEsJb2yWBuiza0+y2Ljco7hdd4wr+7eJm7cfn+NvAw== dependencies: - "@angular-devkit/core" "10.2.0" + "@angular-devkit/core" "10.2.3" rxjs "6.6.2" "@angular-devkit/build-angular@~0.1002.0": - version "0.1002.0" - resolved "https://registry.yarnpkg.com/@angular-devkit/build-angular/-/build-angular-0.1002.0.tgz#b2d1de921b1fd37906e50442d730ca2516d7d747" - integrity sha512-cPkdp1GceokGHc79Wg0hACMqqmnJ4W3H9kY4c9qp1Xz18b3vk1aq09JNawOpfUN09S9vBCnn4glg22lRyqmJNA== - dependencies: - "@angular-devkit/architect" "0.1002.0" - "@angular-devkit/build-optimizer" "0.1002.0" - "@angular-devkit/build-webpack" "0.1002.0" - "@angular-devkit/core" "10.2.0" + version "0.1002.3" + resolved "https://registry.yarnpkg.com/@angular-devkit/build-angular/-/build-angular-0.1002.3.tgz#f23c872dd953d1a3ba623e132d2abeab0635649f" + integrity sha512-NjM8H2AUpLjcf+3mKYd99VbFgN4kwT++IBmR9BRQkqOZ4fD63g8jLPzC0KTsWGIVkZtR9Qc88YW/5sC8C3SVFQ== + dependencies: + "@angular-devkit/architect" "0.1002.3" + "@angular-devkit/build-optimizer" "0.1002.3" + "@angular-devkit/build-webpack" "0.1002.3" + "@angular-devkit/core" "10.2.3" "@babel/core" "7.11.1" "@babel/generator" "7.11.0" "@babel/plugin-transform-runtime" "7.11.0" @@ -26,7 +26,7 @@ "@babel/runtime" "7.11.2" "@babel/template" "7.10.4" "@jsdevtools/coverage-istanbul-loader" "3.0.5" - "@ngtools/webpack" "10.2.0" + "@ngtools/webpack" "10.2.3" autoprefixer "9.8.6" babel-loader "8.1.0" browserslist "^4.9.1" @@ -81,10 +81,10 @@ webpack-subresource-integrity "1.4.1" worker-plugin "5.0.0" -"@angular-devkit/build-optimizer@0.1002.0": - version "0.1002.0" - resolved "https://registry.yarnpkg.com/@angular-devkit/build-optimizer/-/build-optimizer-0.1002.0.tgz#a44300e9a68af32d3efea0ff12355f3e9a10752d" - integrity sha512-ACnm9doPMbRtSy1UZN5ir7smeLMx0g0oW7jX3jyPepeQKZ+9U1Bn09t10NLZQH+Z509jWZgvNJH/aOh85P6euw== +"@angular-devkit/build-optimizer@0.1002.3": + version "0.1002.3" + resolved "https://registry.yarnpkg.com/@angular-devkit/build-optimizer/-/build-optimizer-0.1002.3.tgz#797822cdde3e0e9892670ac515c6f4a7caa0854b" + integrity sha512-/0KbxVmmvt3S7ghk5zUH8/PWjW8ki0uSmPsnjopY8jRgAxuXN/7PXZbqswItNlUBoEj34hj2UADBUJVic7fcnQ== dependencies: loader-utils "2.0.0" source-map "0.7.3" @@ -92,19 +92,19 @@ typescript "4.0.2" webpack-sources "1.4.3" -"@angular-devkit/build-webpack@0.1002.0": - version "0.1002.0" - resolved "https://registry.yarnpkg.com/@angular-devkit/build-webpack/-/build-webpack-0.1002.0.tgz#af96b7f2caf3412119000df36326f48ff995837f" - integrity sha512-TLBBQ6ANOLKXOPxpCOnxAtoknwHA7XhsLuueN06w5qqF+QNNbWUMPoieKFGs2TnotfCgbiq6x57IDEZTyT6V0w== +"@angular-devkit/build-webpack@0.1002.3": + version "0.1002.3" + resolved "https://registry.yarnpkg.com/@angular-devkit/build-webpack/-/build-webpack-0.1002.3.tgz#763ae9c4c4b0854679e7bf1b4d0f467dd2b31c61" + integrity sha512-ngvPPA3VuYGYV275PM6X0pVI0Nl/uWx4eu2S6SUFe6mniN4BQkUHAyeCUMIbM3hkau/NAcF9xUs5AvZ9GDpvPw== dependencies: - "@angular-devkit/architect" "0.1002.0" - "@angular-devkit/core" "10.2.0" + "@angular-devkit/architect" "0.1002.3" + "@angular-devkit/core" "10.2.3" rxjs "6.6.2" -"@angular-devkit/core@10.2.0": - version "10.2.0" - resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-10.2.0.tgz#fcde160afc2786d2da0166526f065c6cf98684c0" - integrity sha512-XAszFhSF3mZw1VjoOsYGbArr5NJLcStjOvcCGjBPl1UBM2AKpuCQXHxI9XJGYKL3B93Vp5G58d8qkHvamT53OA== +"@angular-devkit/core@10.2.3": + version "10.2.3" + resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-10.2.3.tgz#499978929e58532f6f0caab8bd860c882d926eea" + integrity sha512-pMM1v9Xjqx6YLOQxQYs0D+03H6XPDZLS8cyEtoQX2iYdh8qlKHZVbJa2WsfzwMoIPtgcXfQAXn113VEgrQPLFA== dependencies: ajv "6.12.4" fast-json-stable-stringify "2.1.0" @@ -112,36 +112,36 @@ rxjs "6.6.2" source-map "0.7.3" -"@angular-devkit/schematics@10.2.0": - version "10.2.0" - resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-10.2.0.tgz#a45f316bbaa54cbabc06e2e54b04e1c8d103bc0b" - integrity sha512-TQI5NnE6iM3ChF5gZQ9qb+lZgMWa7aLoF5ksOyT3zrmOuICiQYJhA6SsjV95q7J4M55qYymwBib8KTqU/xuQww== +"@angular-devkit/schematics@10.2.3": + version "10.2.3" + resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-10.2.3.tgz#1f384eb9db6f02e3e867e442e3569628e0eb6de5" + integrity sha512-uCNeq5qH4QEiftgOud+EhTVvdriYQVBrYmX4f4BjVHkjnFhm73h30nfAgs6YuStIp8oxSI8jUGE9DAy331xvmA== dependencies: - "@angular-devkit/core" "10.2.0" + "@angular-devkit/core" "10.2.3" ora "5.0.0" rxjs "6.6.2" "@angular/animations@~10.2.0": - version "10.2.1" - resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-10.2.1.tgz#6a28e68b05b1e738cbe779a002349cf8539699b8" - integrity sha512-WD3WGMLhGdvmBNIf9l+H3NwniQr+yBnTEOyUnsOokXsX3I5LYYPCR+3E/YBRDbbBuf4Y3v3sEkijHT5xZ+jQHw== + version "10.2.5" + resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-10.2.5.tgz#9b4aaa2a2f88f848decb5a03f2ddaa2aed37642d" + integrity sha512-lIMwjY1pAqpCM4Ayndf2RsvOWRUc5QV7W82XNou6pIBv2T1i1XV6H72I5Sk9Z4sxxBYCWncEaEub+C6NcS8QRg== dependencies: tslib "^2.0.0" "@angular/cli@~10.2.0": - version "10.2.0" - resolved "https://registry.yarnpkg.com/@angular/cli/-/cli-10.2.0.tgz#b0b465120eb9a39e5efd030bf80c023c630960ed" - integrity sha512-YBzwkFBmG6CdUJk8onsPXxHX/ByU5MERBQgYhLC873e2nZlXMUu+Ttq2Wai6apyskGvsXKxZNPOQSFZTGKXzXg== - dependencies: - "@angular-devkit/architect" "0.1002.0" - "@angular-devkit/core" "10.2.0" - "@angular-devkit/schematics" "10.2.0" - "@schematics/angular" "10.2.0" - "@schematics/update" "0.1002.0" + version "10.2.3" + resolved "https://registry.yarnpkg.com/@angular/cli/-/cli-10.2.3.tgz#71f0b84f40197a3aa28b0d5f3bbff2354c127d1b" + integrity sha512-LLt0AUgLpmaoWA1R7tnUxbJDNs37+WogjNCbNLfvf4YHI04PwKx3OXgx0d8IYNtjHEaGmGp9AQRynvQ2qfXkaA== + dependencies: + "@angular-devkit/architect" "0.1002.3" + "@angular-devkit/core" "10.2.3" + "@angular-devkit/schematics" "10.2.3" + "@schematics/angular" "10.2.3" + "@schematics/update" "0.1002.3" "@yarnpkg/lockfile" "1.1.0" ansi-colors "4.1.1" debug "4.1.1" - ini "1.3.5" + ini "1.3.6" inquirer "7.3.3" npm-package-arg "8.0.1" npm-pick-manifest "6.1.0" @@ -155,16 +155,16 @@ uuid "8.3.0" "@angular/common@~10.2.0": - version "10.2.1" - resolved "https://registry.yarnpkg.com/@angular/common/-/common-10.2.1.tgz#3fbba2102fa8f02f60fae2b0c79b4495be60de2a" - integrity sha512-aJtgokgWxibd7wGmktHm0uYkR/lOrbcStrn6Qisj/PIJf9xTGXYFB0yusnk103aiuBfCIKq+Wl0ZGc1s81Okaw== + version "10.2.5" + resolved "https://registry.yarnpkg.com/@angular/common/-/common-10.2.5.tgz#5313f530446998e2f7af2dc43611addcfa6fd1c1" + integrity sha512-553yf6ZUHNqT4XpOqbW7EKKMfX56u/8DkwYXuSv8MAKdl4/AW6gliFOEJGYo04JcKF7Knq3VPvGSCO9kupf0hg== dependencies: tslib "^2.0.0" "@angular/compiler-cli@~10.2.0": - version "10.2.1" - resolved "https://registry.yarnpkg.com/@angular/compiler-cli/-/compiler-cli-10.2.1.tgz#4482cdc4814dc75bf197c18f39c401181851ac08" - integrity sha512-LSqnJ6K6lZCMrlp47SMysHwyl4NOcOAhnZ1x4aqX85w/rBL5ge1Y57KFZFJ4wYVnboXpQCnPU/uojNuQIQJ8LQ== + version "10.2.5" + resolved "https://registry.yarnpkg.com/@angular/compiler-cli/-/compiler-cli-10.2.5.tgz#adb65bb9ecea14762a501226fde7760b73c3ab1e" + integrity sha512-xddSpKudoPidEebIW3x1CvQdx69WEmnFg4DneeQi/tit7mtAKYTJemzYZmP6abdSYhtxovL0bPX5LxYlrtuxIw== dependencies: canonical-path "1.0.0" chokidar "^3.0.0" @@ -178,70 +178,70 @@ source-map "^0.6.1" sourcemap-codec "^1.4.8" tslib "^2.0.0" - yargs "15.3.0" + yargs "^16.1.1" "@angular/compiler@~10.2.0": - version "10.2.1" - resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-10.2.1.tgz#6abffc69d2c67aa10289af98142915cb9230a69c" - integrity sha512-nJkRSqwQSGeudBWr9JK30Yi2yBvURYTKW4x4GxdW3YiEGBIlKU6aX6q5yi2xHdWO4AEgRs21ZjTs/wp00qnqTg== + version "10.2.5" + resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-10.2.5.tgz#1ff8514fdd2c07ff3c265b960dc49af6376071c9" + integrity sha512-ddJiTPCoVBIGjFDYoYWDpmq3Zs8UKoWpzaeW4u+p17gWW54HwyT5XTxrgtbeUmaxIuRdL4/KT1lGHs9/9bwbCA== dependencies: tslib "^2.0.0" "@angular/core@~10.2.0": - version "10.2.1" - resolved "https://registry.yarnpkg.com/@angular/core/-/core-10.2.1.tgz#05ad30c43ba925a62074515c9d002c1c5337047c" - integrity sha512-zt9G5Ei1nxB6yVJqpiH7K6npaiEUrPWlDCq6vwXeJbmO3tbw2WWiqD55Wkx5hRfysY43swC5j7VveNytHidkkQ== + version "10.2.5" + resolved "https://registry.yarnpkg.com/@angular/core/-/core-10.2.5.tgz#2050b0dbb180aa98c2ec46bba6d4827565ba2a2d" + integrity sha512-krhOKNTj5XE92Rk9ASX5KmgTF72j7qT2PLVxrGEVjuUKjBY2XaK3TV0Kotq9zI3qa9WgeCrP/Njn6jlKQCCAEQ== dependencies: tslib "^2.0.0" "@angular/forms@~10.2.0": - version "10.2.1" - resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-10.2.1.tgz#2b1018ef8c06872355c1d75eeb251ca45b316dd5" - integrity sha512-cGJZRb/caqHeNLpl/f4uFUtCxF8hc1Jd1dkDzfxG3Ea3J96qNsApxWCdwI09aI6KyYADSvQKTjZcgdASmTr/cA== + version "10.2.5" + resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-10.2.5.tgz#12bb297118d22be351fba7176d213bb5aad2932d" + integrity sha512-EnycBx8q+DGmPaX4oSjPejJxx9u0TLb5+tpGxYitdOq/eBpQAAYyWKQGKXb1JB46rPVwJr34MmTltHgAN0zUSQ== dependencies: tslib "^2.0.0" "@angular/platform-browser-dynamic@~10.2.0": - version "10.2.1" - resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-10.2.1.tgz#865610f61b3cb607937f9b0b6c4fdd774dafacdf" - integrity sha512-AyN3dchRIHTXrN8lSni7PfZTHuJcQ4Qp3ZCunxal3dmfIqWKHBCvotJX02UXVPqVC/9qvnyZ1Ezvfw5vx8MVEg== + version "10.2.5" + resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-10.2.5.tgz#c9eea9e076a9fc8f80d7c041ba9766465613bb96" + integrity sha512-7z443I80K2CeqzczlSJ8BlABj0uRgnHUrABE8yLlU2BgifJrriBawzSXEV7UMEN7k7ezbc6NhpOn6Q6BrCKEOA== dependencies: tslib "^2.0.0" "@angular/platform-browser@~10.2.0": - version "10.2.1" - resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-10.2.1.tgz#9b6fb419773eb2492c98486cb0ed636b89dcf692" - integrity sha512-kuxqntIbiyxHIgEopBXoO10HqsFQyzV8Y11+KcnIFN0tte7oOAc6REvUxnvtwKOyFOyYQFv0BhA1QCuddqytGA== + version "10.2.5" + resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-10.2.5.tgz#40dd88c937af7af56e3fb246608c7001e4ac09c7" + integrity sha512-3JDFRGNxr0IUkjSdGK2Q1BvqnSDpy9YWo0DJP+TEpgW578R84m4X7/wI3jJmFSC2yyouMWrHsot2vcBPAQj89g== dependencies: tslib "^2.0.0" "@angular/platform-server@~10.2.0": - version "10.2.1" - resolved "https://registry.yarnpkg.com/@angular/platform-server/-/platform-server-10.2.1.tgz#3e3dc460a603469c0cc212d6f32173a4d9ba85c4" - integrity sha512-VCpd2KEyGA4zhw8E82jJb19VsKVhPiogRaHNZ7xNiMYxu3JTFIDGMnTsT3nILGAKeDxQUeyU0oyguQfXPz4wag== + version "10.2.5" + resolved "https://registry.yarnpkg.com/@angular/platform-server/-/platform-server-10.2.5.tgz#c4f7dee6c2986f37f48c423ca84d59cb79ed108f" + integrity sha512-T8DDvSp9s6iNQ9UE+ELsoeNUWqMkAl2LcChTYvJsqTEo4pbN/8m9JItN4Trc8nzfkWFEg8hPTAODGQKFHczNGw== dependencies: domino "^2.1.2" tslib "^2.0.0" xhr2 "^0.2.0" "@angular/router@~10.2.0": - version "10.2.1" - resolved "https://registry.yarnpkg.com/@angular/router/-/router-10.2.1.tgz#c3204c2a20aac871c415118908179431319dac91" - integrity sha512-w2iS/gq4dcPd4cPGgd7HGEANg5BfE+fg0cI81ah7e79OatDP+Y1atxmNXyF50gCxl8x6WDnUiNu8nfjTebgRAw== + version "10.2.5" + resolved "https://registry.yarnpkg.com/@angular/router/-/router-10.2.5.tgz#acc75a29ab0b54c8ebad7d2a896986a59d7d99ec" + integrity sha512-AtSMB/d4V+pw/FL4G/mWWoiJJtZ/075TqsGW7uEFKgxS6Gh2kalv6BTMlXVG5GO+2oU0lsuDvguq5E7Atbak3Q== dependencies: tslib "^2.0.0" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a" - integrity sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg== +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.13.tgz#dcfc826beef65e75c50e21d3837d7d95798dd658" + integrity sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g== dependencies: - "@babel/highlight" "^7.10.4" + "@babel/highlight" "^7.12.13" -"@babel/compat-data@^7.11.0", "@babel/compat-data@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.12.1.tgz#d7386a689aa0ddf06255005b4b991988021101a0" - integrity sha512-725AQupWJZ8ba0jbKceeFblZTY90McUBWMwHhkFQ9q1zKPJ95GUktljFcgcsIVwRnTnRKlcYzfiNImg5G9m6ZQ== +"@babel/compat-data@^7.11.0", "@babel/compat-data@^7.13.15", "@babel/compat-data@^7.13.8": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.14.0.tgz#a901128bce2ad02565df95e6ecbf195cf9465919" + integrity sha512-vu9V3uMM/1o5Hl5OekMUowo3FqXLJSw+s+66nt0fSWVWTtmosdzn45JHOB3cPtZoe6CTBDzvSw0RdOY85Q37+Q== "@babel/core@7.11.1": version "7.11.1" @@ -266,25 +266,24 @@ source-map "^0.5.0" "@babel/core@^7.7.5": - version "7.12.3" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.12.3.tgz#1b436884e1e3bff6fb1328dc02b208759de92ad8" - integrity sha512-0qXcZYKZp3/6N2jKYVxZv0aNCsxTSVCiK72DTiTYZAu7sjg73W0/aynWjMbiGd87EQL4WyA8reiJVh92AVla9g== - dependencies: - "@babel/code-frame" "^7.10.4" - "@babel/generator" "^7.12.1" - "@babel/helper-module-transforms" "^7.12.1" - "@babel/helpers" "^7.12.1" - "@babel/parser" "^7.12.3" - "@babel/template" "^7.10.4" - "@babel/traverse" "^7.12.1" - "@babel/types" "^7.12.1" + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.14.0.tgz#47299ff3ec8d111b493f1a9d04bf88c04e728d88" + integrity sha512-8YqpRig5NmIHlMLw09zMlPTvUVMILjqCOtVgu+TVNWEBvy9b5I3RRyhqnrV4hjgEK7n8P9OqvkWJAFmEL6Wwfw== + dependencies: + "@babel/code-frame" "^7.12.13" + "@babel/generator" "^7.14.0" + "@babel/helper-compilation-targets" "^7.13.16" + "@babel/helper-module-transforms" "^7.14.0" + "@babel/helpers" "^7.14.0" + "@babel/parser" "^7.14.0" + "@babel/template" "^7.12.13" + "@babel/traverse" "^7.14.0" + "@babel/types" "^7.14.0" convert-source-map "^1.7.0" debug "^4.1.0" - gensync "^1.0.0-beta.1" + gensync "^1.0.0-beta.2" json5 "^2.1.2" - lodash "^4.17.19" - resolve "^1.3.2" - semver "^5.4.1" + semver "^6.3.0" source-map "^0.5.0" "@babel/generator@7.11.0": @@ -296,172 +295,156 @@ jsesc "^2.5.1" source-map "^0.5.0" -"@babel/generator@^7.11.0", "@babel/generator@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.12.1.tgz#0d70be32bdaa03d7c51c8597dda76e0df1f15468" - integrity sha512-DB+6rafIdc9o72Yc3/Ph5h+6hUjeOp66pF0naQBgUFFuPqzQwIlPTm3xZR7YNvduIMtkDIj2t21LSQwnbCrXvg== +"@babel/generator@^7.11.0", "@babel/generator@^7.14.0": + version "7.14.1" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.14.1.tgz#1f99331babd65700183628da186f36f63d615c93" + integrity sha512-TMGhsXMXCP/O1WtQmZjpEYDhCYC9vFhayWZPJSZCGkPJgUqX0rF0wwtrYvnzVxIjcF80tkUertXVk5cwqi5cAQ== dependencies: - "@babel/types" "^7.12.1" + "@babel/types" "^7.14.1" jsesc "^2.5.1" source-map "^0.5.0" -"@babel/helper-annotate-as-pure@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.4.tgz#5bf0d495a3f757ac3bda48b5bf3b3ba309c72ba3" - integrity sha512-XQlqKQP4vXFB7BN8fEEerrmYvHp3fK/rBkRFz9jaJbzK0B1DSfej9Kc7ZzE8Z/OnId1jpJdNAZ3BFQjWG68rcA== +"@babel/helper-annotate-as-pure@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.13.tgz#0f58e86dfc4bb3b1fcd7db806570e177d439b6ab" + integrity sha512-7YXfX5wQ5aYM/BOlbSccHDbuXXFPxeoUmfWtz8le2yTkTZc+BxsiEnENFoi2SlmA8ewDkG2LgIMIVzzn2h8kfw== dependencies: - "@babel/types" "^7.10.4" + "@babel/types" "^7.12.13" -"@babel/helper-builder-binary-assignment-operator-visitor@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.4.tgz#bb0b75f31bf98cbf9ff143c1ae578b87274ae1a3" - integrity sha512-L0zGlFrGWZK4PbT8AszSfLTM5sDU1+Az/En9VrdT8/LmEiJt4zXt+Jve9DCAnQcbqDhCI+29y/L93mrDzddCcg== +"@babel/helper-builder-binary-assignment-operator-visitor@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.12.13.tgz#6bc20361c88b0a74d05137a65cac8d3cbf6f61fc" + integrity sha512-CZOv9tGphhDRlVjVkAgm8Nhklm9RzSmWpX2my+t7Ua/KT616pEzXsQCjinzvkRvHWJ9itO4f296efroX23XCMA== dependencies: - "@babel/helper-explode-assignable-expression" "^7.10.4" - "@babel/types" "^7.10.4" + "@babel/helper-explode-assignable-expression" "^7.12.13" + "@babel/types" "^7.12.13" -"@babel/helper-compilation-targets@^7.10.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.12.1.tgz#310e352888fbdbdd8577be8dfdd2afb9e7adcf50" - integrity sha512-jtBEif7jsPwP27GPHs06v4WBV0KrE8a/P7n0N0sSvHn2hwUCYnolP/CLmz51IzAW4NlN+HuoBtb9QcwnRo9F/g== +"@babel/helper-compilation-targets@^7.10.4", "@babel/helper-compilation-targets@^7.13.16", "@babel/helper-compilation-targets@^7.13.8": + version "7.13.16" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.16.tgz#6e91dccf15e3f43e5556dffe32d860109887563c" + integrity sha512-3gmkYIrpqsLlieFwjkGgLaSHmhnvlAYzZLlYVjlW+QwI+1zE17kGxuJGmIqDQdYp56XdmGeD+Bswx0UTyG18xA== dependencies: - "@babel/compat-data" "^7.12.1" - "@babel/helper-validator-option" "^7.12.1" - browserslist "^4.12.0" - semver "^5.5.0" + "@babel/compat-data" "^7.13.15" + "@babel/helper-validator-option" "^7.12.17" + browserslist "^4.14.5" + semver "^6.3.0" -"@babel/helper-create-class-features-plugin@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.12.1.tgz#3c45998f431edd4a9214c5f1d3ad1448a6137f6e" - integrity sha512-hkL++rWeta/OVOBTRJc9a5Azh5mt5WgZUGAKMD8JM141YsE08K//bp1unBBieO6rUKkIPyUE0USQ30jAy3Sk1w== +"@babel/helper-create-class-features-plugin@^7.13.0": + version "7.14.1" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.1.tgz#1fe11b376f3c41650ad9fedc665b0068722ea76c" + integrity sha512-r8rsUahG4ywm0QpGcCrLaUSOuNAISR3IZCg4Fx05Ozq31aCUrQsTLH6KPxy0N5ULoQ4Sn9qjNdGNtbPWAC6hYg== dependencies: - "@babel/helper-function-name" "^7.10.4" - "@babel/helper-member-expression-to-functions" "^7.12.1" - "@babel/helper-optimise-call-expression" "^7.10.4" - "@babel/helper-replace-supers" "^7.12.1" - "@babel/helper-split-export-declaration" "^7.10.4" + "@babel/helper-annotate-as-pure" "^7.12.13" + "@babel/helper-function-name" "^7.12.13" + "@babel/helper-member-expression-to-functions" "^7.13.12" + "@babel/helper-optimise-call-expression" "^7.12.13" + "@babel/helper-replace-supers" "^7.13.12" + "@babel/helper-split-export-declaration" "^7.12.13" -"@babel/helper-create-regexp-features-plugin@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.1.tgz#18b1302d4677f9dc4740fe8c9ed96680e29d37e8" - integrity sha512-rsZ4LGvFTZnzdNZR5HZdmJVuXK8834R5QkF3WvcnBhrlVtF0HSIUC6zbreL9MgjTywhKokn8RIYRiq99+DLAxA== +"@babel/helper-create-regexp-features-plugin@^7.12.13": + version "7.12.17" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.17.tgz#a2ac87e9e319269ac655b8d4415e94d38d663cb7" + integrity sha512-p2VGmBu9oefLZ2nQpgnEnG0ZlRPvL8gAGvPUMQwUdaE8k49rOMuZpOwdQoy5qJf6K8jL3bcAMhVUlHAjIgJHUg== dependencies: - "@babel/helper-annotate-as-pure" "^7.10.4" - "@babel/helper-regex" "^7.10.4" + "@babel/helper-annotate-as-pure" "^7.12.13" regexpu-core "^4.7.1" -"@babel/helper-define-map@^7.10.4": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.10.5.tgz#b53c10db78a640800152692b13393147acb9bb30" - integrity sha512-fMw4kgFB720aQFXSVaXr79pjjcW5puTCM16+rECJ/plGS+zByelE8l9nCpV1GibxTnFVmUuYG9U8wYfQHdzOEQ== +"@babel/helper-explode-assignable-expression@^7.12.13": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.13.0.tgz#17b5c59ff473d9f956f40ef570cf3a76ca12657f" + integrity sha512-qS0peLTDP8kOisG1blKbaoBg/o9OSa1qoumMjTK5pM+KDTtpxpsiubnCGP34vK8BXGcb2M9eigwgvoJryrzwWA== dependencies: - "@babel/helper-function-name" "^7.10.4" - "@babel/types" "^7.10.5" - lodash "^4.17.19" + "@babel/types" "^7.13.0" -"@babel/helper-explode-assignable-expression@^7.10.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.12.1.tgz#8006a466695c4ad86a2a5f2fb15b5f2c31ad5633" - integrity sha512-dmUwH8XmlrUpVqgtZ737tK88v07l840z9j3OEhCLwKTkjlvKpfqXVIZ0wpK3aeOxspwGrf/5AP5qLx4rO3w5rA== +"@babel/helper-function-name@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz#93ad656db3c3c2232559fd7b2c3dbdcbe0eb377a" + integrity sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA== dependencies: - "@babel/types" "^7.12.1" + "@babel/helper-get-function-arity" "^7.12.13" + "@babel/template" "^7.12.13" + "@babel/types" "^7.12.13" -"@babel/helper-function-name@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz#d2d3b20c59ad8c47112fa7d2a94bc09d5ef82f1a" - integrity sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ== +"@babel/helper-get-function-arity@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz#bc63451d403a3b3082b97e1d8b3fe5bd4091e583" + integrity sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg== dependencies: - "@babel/helper-get-function-arity" "^7.10.4" - "@babel/template" "^7.10.4" - "@babel/types" "^7.10.4" + "@babel/types" "^7.12.13" -"@babel/helper-get-function-arity@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz#98c1cbea0e2332f33f9a4661b8ce1505b2c19ba2" - integrity sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A== +"@babel/helper-hoist-variables@^7.13.0": + version "7.13.16" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.13.16.tgz#1b1651249e94b51f8f0d33439843e33e39775b30" + integrity sha512-1eMtTrXtrwscjcAeO4BVK+vvkxaLJSPFz1w1KLawz6HLNi9bPFGBNwwDyVfiu1Tv/vRRFYfoGaKhmAQPGPn5Wg== dependencies: - "@babel/types" "^7.10.4" + "@babel/traverse" "^7.13.15" + "@babel/types" "^7.13.16" -"@babel/helper-hoist-variables@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.4.tgz#d49b001d1d5a68ca5e6604dda01a6297f7c9381e" - integrity sha512-wljroF5PgCk2juF69kanHVs6vrLwIPNp6DLD+Lrl3hoQ3PpPPikaDRNFA+0t81NOoMt2DL6WW/mdU8k4k6ZzuA== +"@babel/helper-member-expression-to-functions@^7.13.12": + version "7.13.12" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz#dfe368f26d426a07299d8d6513821768216e6d72" + integrity sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw== dependencies: - "@babel/types" "^7.10.4" + "@babel/types" "^7.13.12" -"@babel/helper-member-expression-to-functions@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.1.tgz#fba0f2fcff3fba00e6ecb664bb5e6e26e2d6165c" - integrity sha512-k0CIe3tXUKTRSoEx1LQEPFU9vRQfqHtl+kf8eNnDqb4AUJEy5pz6aIiog+YWtVm2jpggjS1laH68bPsR+KWWPQ== +"@babel/helper-module-imports@^7.10.4", "@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.13.12": + version "7.13.12" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz#c6a369a6f3621cb25da014078684da9196b61977" + integrity sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA== dependencies: - "@babel/types" "^7.12.1" + "@babel/types" "^7.13.12" -"@babel/helper-module-imports@^7.10.4", "@babel/helper-module-imports@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.12.1.tgz#1644c01591a15a2f084dd6d092d9430eb1d1216c" - integrity sha512-ZeC1TlMSvikvJNy1v/wPIazCu3NdOwgYZLIkmIyAsGhqkNpiDoQQRmaCK8YP4Pq3GPTLPV9WXaPCJKvx06JxKA== +"@babel/helper-module-transforms@^7.11.0", "@babel/helper-module-transforms@^7.13.0", "@babel/helper-module-transforms@^7.14.0": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.14.0.tgz#8fcf78be220156f22633ee204ea81f73f826a8ad" + integrity sha512-L40t9bxIuGOfpIGA3HNkJhU9qYrf4y5A5LUSw7rGMSn+pcG8dfJ0g6Zval6YJGd2nEjI7oP00fRdnhLKndx6bw== dependencies: - "@babel/types" "^7.12.1" + "@babel/helper-module-imports" "^7.13.12" + "@babel/helper-replace-supers" "^7.13.12" + "@babel/helper-simple-access" "^7.13.12" + "@babel/helper-split-export-declaration" "^7.12.13" + "@babel/helper-validator-identifier" "^7.14.0" + "@babel/template" "^7.12.13" + "@babel/traverse" "^7.14.0" + "@babel/types" "^7.14.0" -"@babel/helper-module-transforms@^7.11.0", "@babel/helper-module-transforms@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz#7954fec71f5b32c48e4b303b437c34453fd7247c" - integrity sha512-QQzehgFAZ2bbISiCpmVGfiGux8YVFXQ0abBic2Envhej22DVXV9nCFaS5hIQbkyo1AdGb+gNME2TSh3hYJVV/w== - dependencies: - "@babel/helper-module-imports" "^7.12.1" - "@babel/helper-replace-supers" "^7.12.1" - "@babel/helper-simple-access" "^7.12.1" - "@babel/helper-split-export-declaration" "^7.11.0" - "@babel/helper-validator-identifier" "^7.10.4" - "@babel/template" "^7.10.4" - "@babel/traverse" "^7.12.1" - "@babel/types" "^7.12.1" - lodash "^4.17.19" - -"@babel/helper-optimise-call-expression@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz#50dc96413d594f995a77905905b05893cd779673" - integrity sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg== +"@babel/helper-optimise-call-expression@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz#5c02d171b4c8615b1e7163f888c1c81c30a2aaea" + integrity sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA== dependencies: - "@babel/types" "^7.10.4" - -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz#2f75a831269d4f677de49986dff59927533cf375" - integrity sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg== + "@babel/types" "^7.12.13" -"@babel/helper-regex@^7.10.4": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.10.5.tgz#32dfbb79899073c415557053a19bd055aae50ae0" - integrity sha512-68kdUAzDrljqBrio7DYAEgCoJHxppJOERHOgOrDN7WjOzP0ZQ1LsSDRXcemzVZaLvjaJsJEESb6qt+znNuENDg== - dependencies: - lodash "^4.17.19" +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.13.0", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz#806526ce125aed03373bc416a828321e3a6a33af" + integrity sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ== -"@babel/helper-remap-async-to-generator@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.12.1.tgz#8c4dbbf916314f6047dc05e6a2217074238347fd" - integrity sha512-9d0KQCRM8clMPcDwo8SevNs+/9a8yWVVmaE80FGJcEP8N1qToREmWEGnBn8BUlJhYRFz6fqxeRL1sl5Ogsed7A== +"@babel/helper-remap-async-to-generator@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.13.0.tgz#376a760d9f7b4b2077a9dd05aa9c3927cadb2209" + integrity sha512-pUQpFBE9JvC9lrQbpX0TmeNIy5s7GnZjna2lhhcHC7DzgBs6fWn722Y5cfwgrtrqc7NAJwMvOa0mKhq6XaE4jg== dependencies: - "@babel/helper-annotate-as-pure" "^7.10.4" - "@babel/helper-wrap-function" "^7.10.4" - "@babel/types" "^7.12.1" + "@babel/helper-annotate-as-pure" "^7.12.13" + "@babel/helper-wrap-function" "^7.13.0" + "@babel/types" "^7.13.0" -"@babel/helper-replace-supers@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.12.1.tgz#f15c9cc897439281891e11d5ce12562ac0cf3fa9" - integrity sha512-zJjTvtNJnCFsCXVi5rUInstLd/EIVNmIKA1Q9ynESmMBWPWd+7sdR+G4/wdu+Mppfep0XLyG2m7EBPvjCeFyrw== +"@babel/helper-replace-supers@^7.12.13", "@babel/helper-replace-supers@^7.13.0", "@babel/helper-replace-supers@^7.13.12": + version "7.13.12" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.13.12.tgz#6442f4c1ad912502481a564a7386de0c77ff3804" + integrity sha512-Gz1eiX+4yDO8mT+heB94aLVNCL+rbuT2xy4YfyNqu8F+OI6vMvJK891qGBTqL9Uc8wxEvRW92Id6G7sDen3fFw== dependencies: - "@babel/helper-member-expression-to-functions" "^7.12.1" - "@babel/helper-optimise-call-expression" "^7.10.4" - "@babel/traverse" "^7.12.1" - "@babel/types" "^7.12.1" + "@babel/helper-member-expression-to-functions" "^7.13.12" + "@babel/helper-optimise-call-expression" "^7.12.13" + "@babel/traverse" "^7.13.0" + "@babel/types" "^7.13.12" -"@babel/helper-simple-access@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.12.1.tgz#32427e5aa61547d38eb1e6eaf5fd1426fdad9136" - integrity sha512-OxBp7pMrjVewSSC8fXDFrHrBcJATOOFssZwv16F3/6Xtc138GHybBfPbm9kfiqQHKhYQrlamWILwlDCeyMFEaA== +"@babel/helper-simple-access@^7.13.12": + version "7.13.12" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz#dd6c538afb61819d205a012c31792a39c7a5eaf6" + integrity sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA== dependencies: - "@babel/types" "^7.12.1" + "@babel/types" "^7.13.12" "@babel/helper-skip-transparent-expression-wrappers@^7.12.1": version "7.12.1" @@ -470,164 +453,166 @@ dependencies: "@babel/types" "^7.12.1" -"@babel/helper-split-export-declaration@^7.10.4", "@babel/helper-split-export-declaration@^7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz#f8a491244acf6a676158ac42072911ba83ad099f" - integrity sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg== +"@babel/helper-split-export-declaration@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz#e9430be00baf3e88b0e13e6f9d4eaf2136372b05" + integrity sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg== dependencies: - "@babel/types" "^7.11.0" + "@babel/types" "^7.12.13" -"@babel/helper-validator-identifier@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz#a78c7a7251e01f616512d31b10adcf52ada5e0d2" - integrity sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw== +"@babel/helper-validator-identifier@^7.12.11", "@babel/helper-validator-identifier@^7.14.0": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz#d26cad8a47c65286b15df1547319a5d0bcf27288" + integrity sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A== -"@babel/helper-validator-option@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.12.1.tgz#175567380c3e77d60ff98a54bb015fe78f2178d9" - integrity sha512-YpJabsXlJVWP0USHjnC/AQDTLlZERbON577YUVO/wLpqyj6HAtVYnWaQaN0iUN+1/tWn3c+uKKXjRut5115Y2A== +"@babel/helper-validator-option@^7.12.17": + version "7.12.17" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz#d1fbf012e1a79b7eebbfdc6d270baaf8d9eb9831" + integrity sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw== -"@babel/helper-wrap-function@^7.10.4": - version "7.12.3" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.12.3.tgz#3332339fc4d1fbbf1c27d7958c27d34708e990d9" - integrity sha512-Cvb8IuJDln3rs6tzjW3Y8UeelAOdnpB8xtQ4sme2MSZ9wOxrbThporC0y/EtE16VAtoyEfLM404Xr1e0OOp+ow== +"@babel/helper-wrap-function@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.13.0.tgz#bdb5c66fda8526ec235ab894ad53a1235c79fcc4" + integrity sha512-1UX9F7K3BS42fI6qd2A4BjKzgGjToscyZTdp1DjknHLCIvpgne6918io+aL5LXFcER/8QWiwpoY902pVEqgTXA== dependencies: - "@babel/helper-function-name" "^7.10.4" - "@babel/template" "^7.10.4" - "@babel/traverse" "^7.10.4" - "@babel/types" "^7.10.4" + "@babel/helper-function-name" "^7.12.13" + "@babel/template" "^7.12.13" + "@babel/traverse" "^7.13.0" + "@babel/types" "^7.13.0" -"@babel/helpers@^7.10.4", "@babel/helpers@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.12.1.tgz#8a8261c1d438ec18cb890434df4ec768734c1e79" - integrity sha512-9JoDSBGoWtmbay98efmT2+mySkwjzeFeAL9BuWNoVQpkPFQF8SIIFUfY5os9u8wVzglzoiPRSW7cuJmBDUt43g== +"@babel/helpers@^7.10.4", "@babel/helpers@^7.14.0": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.14.0.tgz#ea9b6be9478a13d6f961dbb5f36bf75e2f3b8f62" + integrity sha512-+ufuXprtQ1D1iZTO/K9+EBRn+qPWMJjZSw/S0KlFrxCw4tkrzv9grgpDHkY9MeQTjTY8i2sp7Jep8DfU6tN9Mg== dependencies: - "@babel/template" "^7.10.4" - "@babel/traverse" "^7.12.1" - "@babel/types" "^7.12.1" + "@babel/template" "^7.12.13" + "@babel/traverse" "^7.14.0" + "@babel/types" "^7.14.0" -"@babel/highlight@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.10.4.tgz#7d1bdfd65753538fabe6c38596cdb76d9ac60143" - integrity sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA== +"@babel/highlight@^7.12.13": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.0.tgz#3197e375711ef6bf834e67d0daec88e4f46113cf" + integrity sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg== dependencies: - "@babel/helper-validator-identifier" "^7.10.4" + "@babel/helper-validator-identifier" "^7.14.0" chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.10.4", "@babel/parser@^7.11.1", "@babel/parser@^7.12.1", "@babel/parser@^7.12.3": - version "7.12.3" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.3.tgz#a305415ebe7a6c7023b40b5122a0662d928334cd" - integrity sha512-kFsOS0IbsuhO5ojF8Hc8z/8vEIOkylVBrjiZUbLTE3XFe0Qi+uu6HjzQixkFaqr0ZPAMZcBVxEwmsnsLPZ2Xsw== +"@babel/parser@^7.10.4", "@babel/parser@^7.11.1", "@babel/parser@^7.12.13", "@babel/parser@^7.14.0": + version "7.14.1" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.1.tgz#1bd644b5db3f5797c4479d89ec1817fe02b84c47" + integrity sha512-muUGEKu8E/ftMTPlNp+mc6zL3E9zKWmF5sDHZ5MSsoTP9Wyz64AhEf9kD08xYJ7w6Hdcu8H550ircnPyWSIF0Q== "@babel/plugin-proposal-async-generator-functions@^7.10.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.12.1.tgz#dc6c1170e27d8aca99ff65f4925bd06b1c90550e" - integrity sha512-d+/o30tJxFxrA1lhzJqiUcEJdI6jKlNregCv5bASeGf2Q4MXmnwH7viDo7nhx1/ohf09oaH8j1GVYG/e3Yqk6A== + version "7.13.15" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.13.15.tgz#80e549df273a3b3050431b148c892491df1bcc5b" + integrity sha512-VapibkWzFeoa6ubXy/NgV5U2U4MVnUlvnx6wo1XhlsaTrLYWE0UFpDQsVrmn22q5CzeloqJ8gEMHSKxuee6ZdA== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-remap-async-to-generator" "^7.12.1" - "@babel/plugin-syntax-async-generators" "^7.8.0" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-remap-async-to-generator" "^7.13.0" + "@babel/plugin-syntax-async-generators" "^7.8.4" "@babel/plugin-proposal-class-properties@^7.10.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.12.1.tgz#a082ff541f2a29a4821065b8add9346c0c16e5de" - integrity sha512-cKp3dlQsFsEs5CWKnN7BnSHOd0EOW8EKpEjkoz1pO2E5KzIDNV9Ros1b0CnmbVgAGXJubOYVBOGCT1OmJwOI7w== + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.13.0.tgz#146376000b94efd001e57a40a88a525afaab9f37" + integrity sha512-KnTDjFNC1g+45ka0myZNvSBFLhNCLN+GeGYLDEA8Oq7MZ6yMgfLoIRh86GRT0FjtJhZw8JyUskP9uvj5pHM9Zg== dependencies: - "@babel/helper-create-class-features-plugin" "^7.12.1" - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-create-class-features-plugin" "^7.13.0" + "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-proposal-dynamic-import@^7.10.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.12.1.tgz#43eb5c2a3487ecd98c5c8ea8b5fdb69a2749b2dc" - integrity sha512-a4rhUSZFuq5W8/OO8H7BL5zspjnc1FLd9hlOxIK/f7qG4a0qsqk8uvF/ywgBA8/OmjsapjpvaEOYItfGG1qIvQ== + version "7.13.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.13.8.tgz#876a1f6966e1dec332e8c9451afda3bebcdf2e1d" + integrity sha512-ONWKj0H6+wIRCkZi9zSbZtE/r73uOhMVHh256ys0UzfM7I3d4n+spZNWjOnJv2gzopumP2Wxi186vI8N0Y2JyQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-dynamic-import" "^7.8.0" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" "@babel/plugin-proposal-export-namespace-from@^7.10.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.12.1.tgz#8b9b8f376b2d88f5dd774e4d24a5cc2e3679b6d4" - integrity sha512-6CThGf0irEkzujYS5LQcjBx8j/4aQGiVv7J9+2f7pGfxqyKh3WnmVJYW3hdrQjyksErMGBPQrCnHfOtna+WLbw== + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.12.13.tgz#393be47a4acd03fa2af6e3cde9b06e33de1b446d" + integrity sha512-INAgtFo4OnLN3Y/j0VwAgw3HDXcDtX+C/erMvWzuV9v71r7urb6iyMXu7eM9IgLr1ElLlOkaHjJ0SbCmdOQ3Iw== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-syntax-export-namespace-from" "^7.8.3" "@babel/plugin-proposal-json-strings@^7.10.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.12.1.tgz#d45423b517714eedd5621a9dfdc03fa9f4eb241c" - integrity sha512-GoLDUi6U9ZLzlSda2Df++VSqDJg3CG+dR0+iWsv6XRw1rEq+zwt4DirM9yrxW6XWaTpmai1cWJLMfM8qQJf+yw== + version "7.13.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.13.8.tgz#bf1fb362547075afda3634ed31571c5901afef7b" + integrity sha512-w4zOPKUFPX1mgvTmL/fcEqy34hrQ1CRcGxdphBc6snDnnqJ47EZDIyop6IwXzAC8G916hsIuXB2ZMBCExC5k7Q== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-json-strings" "^7.8.0" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-json-strings" "^7.8.3" "@babel/plugin-proposal-logical-assignment-operators@^7.11.0": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.12.1.tgz#f2c490d36e1b3c9659241034a5d2cd50263a2751" - integrity sha512-k8ZmVv0JU+4gcUGeCDZOGd0lCIamU/sMtIiX3UWnUc5yzgq6YUGyEolNYD+MLYKfSzgECPcqetVcJP9Afe/aCA== + version "7.13.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.13.8.tgz#93fa78d63857c40ce3c8c3315220fd00bfbb4e1a" + integrity sha512-aul6znYB4N4HGweImqKn59Su9RS8lbUIqxtXTOcAGtNIDczoEFv+l1EhmX8rUBp3G1jMjKJm8m0jXVp63ZpS4A== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" "@babel/plugin-proposal-nullish-coalescing-operator@^7.10.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.12.1.tgz#3ed4fff31c015e7f3f1467f190dbe545cd7b046c" - integrity sha512-nZY0ESiaQDI1y96+jk6VxMOaL4LPo/QDHBqL+SF3/vl6dHkTwHlOI8L4ZwuRBHgakRBw5zsVylel7QPbbGuYgg== + version "7.13.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.13.8.tgz#3730a31dafd3c10d8ccd10648ed80a2ac5472ef3" + integrity sha512-iePlDPBn//UhxExyS9KyeYU7RM9WScAG+D3Hhno0PLJebAEpDZMocbDe64eqynhNAnwz/vZoL/q/QB2T1OH39A== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" "@babel/plugin-proposal-numeric-separator@^7.10.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.1.tgz#0e2c6774c4ce48be412119b4d693ac777f7685a6" - integrity sha512-MR7Ok+Af3OhNTCxYVjJZHS0t97ydnJZt/DbR4WISO39iDnhiD8XHrY12xuSJ90FFEGjir0Fzyyn7g/zY6hxbxA== + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.13.tgz#bd9da3188e787b5120b4f9d465a8261ce67ed1db" + integrity sha512-O1jFia9R8BUCl3ZGB7eitaAPu62TXJRHn7rh+ojNERCFyqRwJMTmhz+tJ+k0CwI6CLjX/ee4qW74FSqlq9I35w== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-syntax-numeric-separator" "^7.10.4" "@babel/plugin-proposal-object-rest-spread@^7.11.0": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.12.1.tgz#def9bd03cea0f9b72283dac0ec22d289c7691069" - integrity sha512-s6SowJIjzlhx8o7lsFx5zmY4At6CTtDvgNQDdPzkBQucle58A6b/TTeEBYtyDgmcXjUTM+vE8YOGHZzzbc/ioA== + version "7.13.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.13.8.tgz#5d210a4d727d6ce3b18f9de82cc99a3964eed60a" + integrity sha512-DhB2EuB1Ih7S3/IRX5AFVgZ16k3EzfRbq97CxAVI1KSYcW+lexV8VZb7G7L8zuPVSdQMRn0kiBpf/Yzu9ZKH0g== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-object-rest-spread" "^7.8.0" - "@babel/plugin-transform-parameters" "^7.12.1" + "@babel/compat-data" "^7.13.8" + "@babel/helper-compilation-targets" "^7.13.8" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-transform-parameters" "^7.13.0" "@babel/plugin-proposal-optional-catch-binding@^7.10.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.12.1.tgz#ccc2421af64d3aae50b558a71cede929a5ab2942" - integrity sha512-hFvIjgprh9mMw5v42sJWLI1lzU5L2sznP805zeT6rySVRA0Y18StRhDqhSxlap0oVgItRsB6WSROp4YnJTJz0g== + version "7.13.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.13.8.tgz#3ad6bd5901506ea996fc31bdcf3ccfa2bed71107" + integrity sha512-0wS/4DUF1CuTmGo+NiaHfHcVSeSLj5S3e6RivPTg/2k3wOv3jO35tZ6/ZWsQhQMvdgI7CwphjQa/ccarLymHVA== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" "@babel/plugin-proposal-optional-chaining@^7.11.0": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.12.1.tgz#cce122203fc8a32794296fc377c6dedaf4363797" - integrity sha512-c2uRpY6WzaVDzynVY9liyykS+kVU+WRZPMPYpkelXH8KBt1oXoI89kPbZKKG/jDT5UK92FTW2fZkZaJhdiBabw== + version "7.13.12" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.13.12.tgz#ba9feb601d422e0adea6760c2bd6bbb7bfec4866" + integrity sha512-fcEdKOkIB7Tf4IxrgEVeFC4zeJSTr78no9wTdBuZZbqF64kzllU0ybo2zrzm7gUQfxGhBgq4E39oRs8Zx/RMYQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.13.0" "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" - "@babel/plugin-syntax-optional-chaining" "^7.8.0" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" "@babel/plugin-proposal-private-methods@^7.10.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.12.1.tgz#86814f6e7a21374c980c10d38b4493e703f4a389" - integrity sha512-mwZ1phvH7/NHK6Kf8LP7MYDogGV+DKB1mryFOEwx5EBNQrosvIczzZFTUmWaeujd5xT6G1ELYWUz3CutMhjE1w== + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.13.0.tgz#04bd4c6d40f6e6bbfa2f57e2d8094bad900ef787" + integrity sha512-MXyyKQd9inhx1kDYPkFRVOBXQ20ES8Pto3T7UZ92xj2mY0EVD8oAVzeyYuVfy/mxAdTSIayOvg+aVzcHV2bn6Q== dependencies: - "@babel/helper-create-class-features-plugin" "^7.12.1" - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-create-class-features-plugin" "^7.13.0" + "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-proposal-unicode-property-regex@^7.10.4", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.1.tgz#2a183958d417765b9eae334f47758e5d6a82e072" - integrity sha512-MYq+l+PvHuw/rKUz1at/vb6nCnQ2gmJBNaM62z0OgH7B2W1D9pvkpYtlti9bGtizNIU1K3zm4bZF9F91efVY0w== + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.13.tgz#bebde51339be829c17aaaaced18641deb62b39ba" + integrity sha512-XyJmZidNfofEkqFV5VC/bLabGmO5QzenPO/YOfGuEbgU+2sSwMmio3YLb4WtBgcmmdwZHyVyv8on77IUjQ5Gvg== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.12.1" - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-create-regexp-features-plugin" "^7.12.13" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-syntax-async-generators@^7.8.0": +"@babel/plugin-syntax-async-generators@^7.8.0", "@babel/plugin-syntax-async-generators@^7.8.4": version "7.8.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== @@ -635,13 +620,13 @@ "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-class-properties@^7.10.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.1.tgz#bcb297c5366e79bebadef509549cd93b04f19978" - integrity sha512-U40A76x5gTwmESz+qiqssqmeEsKvcSyvtgktrm0uzcARAmM9I1jR221f6Oq+GmHrcD+LvZDag1UTOTe2fL3TeA== + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" + integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-syntax-dynamic-import@^7.8.0": +"@babel/plugin-syntax-dynamic-import@^7.8.0", "@babel/plugin-syntax-dynamic-import@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== @@ -655,7 +640,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-syntax-json-strings@^7.8.0": +"@babel/plugin-syntax-json-strings@^7.8.0", "@babel/plugin-syntax-json-strings@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== @@ -669,7 +654,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.0": +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.0", "@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== @@ -683,21 +668,21 @@ dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-object-rest-spread@^7.8.0": +"@babel/plugin-syntax-object-rest-spread@^7.8.0", "@babel/plugin-syntax-object-rest-spread@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-optional-catch-binding@^7.8.0": +"@babel/plugin-syntax-optional-catch-binding@^7.8.0", "@babel/plugin-syntax-optional-catch-binding@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-optional-chaining@^7.8.0": +"@babel/plugin-syntax-optional-chaining@^7.8.0", "@babel/plugin-syntax-optional-chaining@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== @@ -705,209 +690,208 @@ "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-top-level-await@^7.10.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.1.tgz#dd6c0b357ac1bb142d98537450a319625d13d2a0" - integrity sha512-i7ooMZFS+a/Om0crxZodrTzNEPJHZrlMVGMTEpFAj6rYY/bKCddB0Dk/YxfPuYXOopuhKk/e1jV6h+WUU9XN3A== + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.13.tgz#c5f0fa6e249f5b739727f923540cf7a806130178" + integrity sha512-A81F9pDwyS7yM//KwbCSDqy3Uj4NMIurtplxphWxoYtNPov7cJsDkAFNNyVlIZ3jwGycVsurZ+LtOA8gZ376iQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-transform-arrow-functions@^7.10.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.12.1.tgz#8083ffc86ac8e777fbe24b5967c4b2521f3cb2b3" - integrity sha512-5QB50qyN44fzzz4/qxDPQMBCTHgxg3n0xRBLJUmBlLoU/sFvxVWGZF/ZUfMVDQuJUKXaBhbupxIzIfZ6Fwk/0A== + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.13.0.tgz#10a59bebad52d637a027afa692e8d5ceff5e3dae" + integrity sha512-96lgJagobeVmazXFaDrbmCLQxBysKu7U6Do3mLsx27gf5Dk85ezysrs2BZUpXD703U/Su1xTBDxxar2oa4jAGg== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-transform-async-to-generator@^7.10.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.12.1.tgz#3849a49cc2a22e9743cbd6b52926d30337229af1" - integrity sha512-SDtqoEcarK1DFlRJ1hHRY5HvJUj5kX4qmtpMAm2QnhOlyuMC4TMdCRgW6WXpv93rZeYNeLP22y8Aq2dbcDRM1A== + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.13.0.tgz#8e112bf6771b82bf1e974e5e26806c5c99aa516f" + integrity sha512-3j6E004Dx0K3eGmhxVJxwwI89CTJrce7lg3UrtFuDAVQ/2+SJ/h/aSFOeE6/n0WB1GsOffsJp6MnPQNQ8nmwhg== dependencies: - "@babel/helper-module-imports" "^7.12.1" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-remap-async-to-generator" "^7.12.1" + "@babel/helper-module-imports" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-remap-async-to-generator" "^7.13.0" "@babel/plugin-transform-block-scoped-functions@^7.10.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.1.tgz#f2a1a365bde2b7112e0a6ded9067fdd7c07905d9" - integrity sha512-5OpxfuYnSgPalRpo8EWGPzIYf0lHBWORCkj5M0oLBwHdlux9Ri36QqGW3/LR13RSVOAoUUMzoPI/jpE4ABcHoA== + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.13.tgz#a9bf1836f2a39b4eb6cf09967739de29ea4bf4c4" + integrity sha512-zNyFqbc3kI/fVpqwfqkg6RvBgFpC4J18aKKMmv7KdQ/1GgREapSJAykLMVNwfRGO3BtHj3YQZl8kxCXPcVMVeg== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-transform-block-scoping@^7.10.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.1.tgz#f0ee727874b42a208a48a586b84c3d222c2bbef1" - integrity sha512-zJyAC9sZdE60r1nVQHblcfCj29Dh2Y0DOvlMkcqSo0ckqjiCwNiUezUKw+RjOCwGfpLRwnAeQ2XlLpsnGkvv9w== + version "7.14.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.14.1.tgz#ac1b3a8e3d8cbb31efc6b9be2f74eb9823b74ab2" + integrity sha512-2mQXd0zBrwfp0O1moWIhPpEeTKDvxyHcnma3JATVP1l+CctWBuot6OJG8LQ4DnBj4ZZPSmlb/fm4mu47EOAnVA== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-transform-classes@^7.10.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.12.1.tgz#65e650fcaddd3d88ddce67c0f834a3d436a32db6" - integrity sha512-/74xkA7bVdzQTBeSUhLLJgYIcxw/dpEpCdRDiHgPJ3Mv6uC11UhjpOhl72CgqbBCmt1qtssCyB2xnJm1+PFjog== - dependencies: - "@babel/helper-annotate-as-pure" "^7.10.4" - "@babel/helper-define-map" "^7.10.4" - "@babel/helper-function-name" "^7.10.4" - "@babel/helper-optimise-call-expression" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-replace-supers" "^7.12.1" - "@babel/helper-split-export-declaration" "^7.10.4" + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.13.0.tgz#0265155075c42918bf4d3a4053134176ad9b533b" + integrity sha512-9BtHCPUARyVH1oXGcSJD3YpsqRLROJx5ZNP6tN5vnk17N0SVf9WCtf8Nuh1CFmgByKKAIMstitKduoCmsaDK5g== + dependencies: + "@babel/helper-annotate-as-pure" "^7.12.13" + "@babel/helper-function-name" "^7.12.13" + "@babel/helper-optimise-call-expression" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-replace-supers" "^7.13.0" + "@babel/helper-split-export-declaration" "^7.12.13" globals "^11.1.0" "@babel/plugin-transform-computed-properties@^7.10.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.12.1.tgz#d68cf6c9b7f838a8a4144badbe97541ea0904852" - integrity sha512-vVUOYpPWB7BkgUWPo4C44mUQHpTZXakEqFjbv8rQMg7TC6S6ZhGZ3otQcRH6u7+adSlE5i0sp63eMC/XGffrzg== + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.13.0.tgz#845c6e8b9bb55376b1fa0b92ef0bdc8ea06644ed" + integrity sha512-RRqTYTeZkZAz8WbieLTvKUEUxZlUTdmL5KGMyZj7FnMfLNKV4+r5549aORG/mgojRmFlQMJDUupwAMiF2Q7OUg== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-transform-destructuring@^7.10.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.12.1.tgz#b9a570fe0d0a8d460116413cb4f97e8e08b2f847" - integrity sha512-fRMYFKuzi/rSiYb2uRLiUENJOKq4Gnl+6qOv5f8z0TZXg3llUwUhsNNwrwaT/6dUhJTzNpBr+CUvEWBtfNY1cw== + version "7.13.17" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.13.17.tgz#678d96576638c19d5b36b332504d3fd6e06dea27" + integrity sha512-UAUqiLv+uRLO+xuBKKMEpC+t7YRNVRqBsWWq1yKXbBZBje/t3IXCiSinZhjn/DC3qzBfICeYd2EFGEbHsh5RLA== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-transform-dotall-regex@^7.10.4", "@babel/plugin-transform-dotall-regex@^7.4.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.1.tgz#a1d16c14862817b6409c0a678d6f9373ca9cd975" - integrity sha512-B2pXeRKoLszfEW7J4Hg9LoFaWEbr/kzo3teWHmtFCszjRNa/b40f9mfeqZsIDLLt/FjwQ6pz/Gdlwy85xNckBA== + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.13.tgz#3f1601cc29905bfcb67f53910f197aeafebb25ad" + integrity sha512-foDrozE65ZFdUC2OfgeOCrEPTxdB3yjqxpXh8CH+ipd9CHd4s/iq81kcUpyH8ACGNEPdFqbtzfgzbT/ZGlbDeQ== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.12.1" - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-create-regexp-features-plugin" "^7.12.13" + "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-transform-duplicate-keys@^7.10.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.12.1.tgz#745661baba295ac06e686822797a69fbaa2ca228" - integrity sha512-iRght0T0HztAb/CazveUpUQrZY+aGKKaWXMJ4uf9YJtqxSUe09j3wteztCUDRHs+SRAL7yMuFqUsLoAKKzgXjw== + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.12.13.tgz#6f06b87a8b803fd928e54b81c258f0a0033904de" + integrity sha512-NfADJiiHdhLBW3pulJlJI2NB0t4cci4WTZ8FtdIuNc2+8pslXdPtRRAEWqUY+m9kNOk2eRYbTAOipAxlrOcwwQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-transform-exponentiation-operator@^7.10.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.1.tgz#b0f2ed356ba1be1428ecaf128ff8a24f02830ae0" - integrity sha512-7tqwy2bv48q+c1EHbXK0Zx3KXd2RVQp6OC7PbwFNt/dPTAV3Lu5sWtWuAj8owr5wqtWnqHfl2/mJlUmqkChKug== + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.13.tgz#4d52390b9a273e651e4aba6aee49ef40e80cd0a1" + integrity sha512-fbUelkM1apvqez/yYx1/oICVnGo2KM5s63mhGylrmXUxK/IAXSIf87QIxVfZldWf4QsOafY6vV3bX8aMHSvNrA== dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.12.13" + "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-transform-for-of@^7.10.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.12.1.tgz#07640f28867ed16f9511c99c888291f560921cfa" - integrity sha512-Zaeq10naAsuHo7heQvyV0ptj4dlZJwZgNAtBYBnu5nNKJoW62m0zKcIEyVECrUKErkUkg6ajMy4ZfnVZciSBhg== + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.13.0.tgz#c799f881a8091ac26b54867a845c3e97d2696062" + integrity sha512-IHKT00mwUVYE0zzbkDgNRP6SRzvfGCYsOxIRz8KsiaaHCcT9BWIkO+H9QRJseHBLOGBZkHUdHiqj6r0POsdytg== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-transform-function-name@^7.10.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.1.tgz#2ec76258c70fe08c6d7da154003a480620eba667" - integrity sha512-JF3UgJUILoFrFMEnOJLJkRHSk6LUSXLmEFsA23aR2O5CSLUxbeUX1IZ1YQ7Sn0aXb601Ncwjx73a+FVqgcljVw== + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.13.tgz#bb024452f9aaed861d374c8e7a24252ce3a50051" + integrity sha512-6K7gZycG0cmIwwF7uMK/ZqeCikCGVBdyP2J5SKNCXO5EOHcqi+z7Jwf8AmyDNcBgxET8DrEtCt/mPKPyAzXyqQ== dependencies: - "@babel/helper-function-name" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-function-name" "^7.12.13" + "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-transform-literals@^7.10.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.1.tgz#d73b803a26b37017ddf9d3bb8f4dc58bfb806f57" - integrity sha512-+PxVGA+2Ag6uGgL0A5f+9rklOnnMccwEBzwYFL3EUaKuiyVnUipyXncFcfjSkbimLrODoqki1U9XxZzTvfN7IQ== + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.13.tgz#2ca45bafe4a820197cf315794a4d26560fe4bdb9" + integrity sha512-FW+WPjSR7hiUxMcKqyNjP05tQ2kmBCdpEpZHY1ARm96tGQCCBvXKnpjILtDplUnJ/eHZ0lALLM+d2lMFSpYJrQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-transform-member-expression-literals@^7.10.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.1.tgz#496038602daf1514a64d43d8e17cbb2755e0c3ad" - integrity sha512-1sxePl6z9ad0gFMB9KqmYofk34flq62aqMt9NqliS/7hPEpURUCMbyHXrMPlo282iY7nAvUB1aQd5mg79UD9Jg== + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.13.tgz#5ffa66cd59b9e191314c9f1f803b938e8c081e40" + integrity sha512-kxLkOsg8yir4YeEPHLuO2tXP9R/gTjpuTOjshqSpELUN3ZAg2jfDnKUvzzJxObun38sw3wm4Uu69sX/zA7iRvg== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-transform-modules-amd@^7.10.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.12.1.tgz#3154300b026185666eebb0c0ed7f8415fefcf6f9" - integrity sha512-tDW8hMkzad5oDtzsB70HIQQRBiTKrhfgwC/KkJeGsaNFTdWhKNt/BiE8c5yj19XiGyrxpbkOfH87qkNg1YGlOQ== + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.14.0.tgz#589494b5b290ff76cf7f59c798011f6d77026553" + integrity sha512-CF4c5LX4LQ03LebQxJ5JZes2OYjzBuk1TdiF7cG7d5dK4lAdw9NZmaxq5K/mouUdNeqwz3TNjnW6v01UqUNgpQ== dependencies: - "@babel/helper-module-transforms" "^7.12.1" - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-module-transforms" "^7.14.0" + "@babel/helper-plugin-utils" "^7.13.0" babel-plugin-dynamic-import-node "^2.3.3" "@babel/plugin-transform-modules-commonjs@^7.10.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.12.1.tgz#fa403124542636c786cf9b460a0ffbb48a86e648" - integrity sha512-dY789wq6l0uLY8py9c1B48V8mVL5gZh/+PQ5ZPrylPYsnAvnEMjqsUXkuoDVPeVK+0VyGar+D08107LzDQ6pag== + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.14.0.tgz#52bc199cb581e0992edba0f0f80356467587f161" + integrity sha512-EX4QePlsTaRZQmw9BsoPeyh5OCtRGIhwfLquhxGp5e32w+dyL8htOcDwamlitmNFK6xBZYlygjdye9dbd9rUlQ== dependencies: - "@babel/helper-module-transforms" "^7.12.1" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-simple-access" "^7.12.1" + "@babel/helper-module-transforms" "^7.14.0" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-simple-access" "^7.13.12" babel-plugin-dynamic-import-node "^2.3.3" "@babel/plugin-transform-modules-systemjs@^7.10.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.12.1.tgz#663fea620d593c93f214a464cd399bf6dc683086" - integrity sha512-Hn7cVvOavVh8yvW6fLwveFqSnd7rbQN3zJvoPNyNaQSvgfKmDBO9U1YL9+PCXGRlZD9tNdWTy5ACKqMuzyn32Q== - dependencies: - "@babel/helper-hoist-variables" "^7.10.4" - "@babel/helper-module-transforms" "^7.12.1" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-validator-identifier" "^7.10.4" + version "7.13.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.13.8.tgz#6d066ee2bff3c7b3d60bf28dec169ad993831ae3" + integrity sha512-hwqctPYjhM6cWvVIlOIe27jCIBgHCsdH2xCJVAYQm7V5yTMoilbVMi9f6wKg0rpQAOn6ZG4AOyvCqFF/hUh6+A== + dependencies: + "@babel/helper-hoist-variables" "^7.13.0" + "@babel/helper-module-transforms" "^7.13.0" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-validator-identifier" "^7.12.11" babel-plugin-dynamic-import-node "^2.3.3" "@babel/plugin-transform-modules-umd@^7.10.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.12.1.tgz#eb5a218d6b1c68f3d6217b8fa2cc82fec6547902" - integrity sha512-aEIubCS0KHKM0zUos5fIoQm+AZUMt1ZvMpqz0/H5qAQ7vWylr9+PLYurT+Ic7ID/bKLd4q8hDovaG3Zch2uz5Q== + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.14.0.tgz#2f8179d1bbc9263665ce4a65f305526b2ea8ac34" + integrity sha512-nPZdnWtXXeY7I87UZr9VlsWme3Y0cfFFE41Wbxz4bbaexAjNMInXPFUpRRUJ8NoMm0Cw+zxbqjdPmLhcjfazMw== dependencies: - "@babel/helper-module-transforms" "^7.12.1" - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-module-transforms" "^7.14.0" + "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-transform-named-capturing-groups-regex@^7.10.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.1.tgz#b407f5c96be0d9f5f88467497fa82b30ac3e8753" - integrity sha512-tB43uQ62RHcoDp9v2Nsf+dSM8sbNodbEicbQNA53zHz8pWUhsgHSJCGpt7daXxRydjb0KnfmB+ChXOv3oADp1Q== + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.13.tgz#2213725a5f5bbbe364b50c3ba5998c9599c5c9d9" + integrity sha512-Xsm8P2hr5hAxyYblrfACXpQKdQbx4m2df9/ZZSQ8MAhsadw06+jW7s9zsSw6he+mJZXRlVMyEnVktJo4zjk1WA== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.12.1" + "@babel/helper-create-regexp-features-plugin" "^7.12.13" "@babel/plugin-transform-new-target@^7.10.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.1.tgz#80073f02ee1bb2d365c3416490e085c95759dec0" - integrity sha512-+eW/VLcUL5L9IvJH7rT1sT0CzkdUTvPrXC2PXTn/7z7tXLBuKvezYbGdxD5WMRoyvyaujOq2fWoKl869heKjhw== + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.13.tgz#e22d8c3af24b150dd528cbd6e685e799bf1c351c" + integrity sha512-/KY2hbLxrG5GTQ9zzZSc3xWiOy379pIETEhbtzwZcw9rvuaVV4Fqy7BYGYOWZnaoXIQYbbJ0ziXLa/sKcGCYEQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-transform-object-super@^7.10.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.1.tgz#4ea08696b8d2e65841d0c7706482b048bed1066e" - integrity sha512-AvypiGJH9hsquNUn+RXVcBdeE3KHPZexWRdimhuV59cSoOt5kFBmqlByorAeUlGG2CJWd0U+4ZtNKga/TB0cAw== + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.13.tgz#b4416a2d63b8f7be314f3d349bd55a9c1b5171f7" + integrity sha512-JzYIcj3XtYspZDV8j9ulnoMPZZnF/Cj0LUxPOjR89BdBVx+zYJI9MdMIlUZjbXDX+6YVeS6I3e8op+qQ3BYBoQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-replace-supers" "^7.12.1" + "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-replace-supers" "^7.12.13" -"@babel/plugin-transform-parameters@^7.10.4", "@babel/plugin-transform-parameters@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.12.1.tgz#d2e963b038771650c922eff593799c96d853255d" - integrity sha512-xq9C5EQhdPK23ZeCdMxl8bbRnAgHFrw5EOC3KJUsSylZqdkCaFEXxGSBuTSObOpiiHHNyb82es8M1QYgfQGfNg== +"@babel/plugin-transform-parameters@^7.10.4", "@babel/plugin-transform-parameters@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.13.0.tgz#8fa7603e3097f9c0b7ca1a4821bc2fb52e9e5007" + integrity sha512-Jt8k/h/mIwE2JFEOb3lURoY5C85ETcYPnbuAJ96zRBzh1XHtQZfs62ChZ6EP22QlC8c7Xqr9q+e1SU5qttwwjw== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-transform-property-literals@^7.10.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.1.tgz#41bc81200d730abb4456ab8b3fbd5537b59adecd" - integrity sha512-6MTCR/mZ1MQS+AwZLplX4cEySjCpnIF26ToWo942nqn8hXSm7McaHQNeGx/pt7suI1TWOWMfa/NgBhiqSnX0cQ== + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.13.tgz#4e6a9e37864d8f1b3bc0e2dce7bf8857db8b1a81" + integrity sha512-nqVigwVan+lR+g8Fj8Exl0UQX2kymtjcWfMOYM1vTYEKujeyv2SkMgazf2qNcK7l4SDiKyTA/nHCPqL4e2zo1A== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-transform-regenerator@^7.10.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.12.1.tgz#5f0a28d842f6462281f06a964e88ba8d7ab49753" - integrity sha512-gYrHqs5itw6i4PflFX3OdBPMQdPbF4bj2REIUxlMRUFk0/ZOAIpDFuViuxPjUL7YC8UPnf+XG7/utJvqXdPKng== + version "7.13.15" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.13.15.tgz#e5eb28945bf8b6563e7f818945f966a8d2997f39" + integrity sha512-Bk9cOLSz8DiurcMETZ8E2YtIVJbFCPGW28DJWUakmyVWtQSm6Wsf0p4B4BfEr/eL2Nkhe/CICiUiMOCi1TPhuQ== dependencies: regenerator-transform "^0.14.2" "@babel/plugin-transform-reserved-words@^7.10.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.12.1.tgz#6fdfc8cc7edcc42b36a7c12188c6787c873adcd8" - integrity sha512-pOnUfhyPKvZpVyBHhSBoX8vfA09b7r00Pmm1sH+29ae2hMTKVmSp4Ztsr8KBKjLjx17H0eJqaRC3bR2iThM54A== + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.12.13.tgz#7d9988d4f06e0fe697ea1d9803188aa18b472695" + integrity sha512-xhUPzDXxZN1QfiOy/I5tyye+TRz6lA7z6xaT4CLOjPRMVg1ldRf0LHw0TDBpYL4vG78556WuHdyO9oi5UmzZBg== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-transform-runtime@7.11.0": version "7.11.0" @@ -920,56 +904,55 @@ semver "^5.5.1" "@babel/plugin-transform-shorthand-properties@^7.10.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.1.tgz#0bf9cac5550fce0cfdf043420f661d645fdc75e3" - integrity sha512-GFZS3c/MhX1OusqB1MZ1ct2xRzX5ppQh2JU1h2Pnfk88HtFTM+TWQqJNfwkmxtPQtb/s1tk87oENfXJlx7rSDw== + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.13.tgz#db755732b70c539d504c6390d9ce90fe64aff7ad" + integrity sha512-xpL49pqPnLtf0tVluuqvzWIgLEhuPpZzvs2yabUHSKRNlN7ScYU7aMlmavOeyXJZKgZKQRBlh8rHbKiJDraTSw== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-transform-spread@^7.11.0": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.12.1.tgz#527f9f311be4ec7fdc2b79bb89f7bf884b3e1e1e" - integrity sha512-vuLp8CP0BE18zVYjsEBZ5xoCecMK6LBMMxYzJnh01rxQRvhNhH1csMMmBfNo5tGpGO+NhdSNW2mzIvBu3K1fng== + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.13.0.tgz#84887710e273c1815ace7ae459f6f42a5d31d5fd" + integrity sha512-V6vkiXijjzYeFmQTr3dBxPtZYLPcUfY34DebOU27jIl2M/Y8Egm52Hw82CSjjPqd54GTlJs5x+CR7HeNr24ckg== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.13.0" "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" "@babel/plugin-transform-sticky-regex@^7.10.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.1.tgz#5c24cf50de396d30e99afc8d1c700e8bce0f5caf" - integrity sha512-CiUgKQ3AGVk7kveIaPEET1jNDhZZEl1RPMWdTBE1799bdz++SwqDHStmxfCtDfBhQgCl38YRiSnrMuUMZIWSUQ== + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.13.tgz#760ffd936face73f860ae646fb86ee82f3d06d1f" + integrity sha512-Jc3JSaaWT8+fr7GRvQP02fKDsYk4K/lYwWq38r/UGfaxo89ajud321NH28KRQ7xy1Ybc0VUE5Pz8psjNNDUglg== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-regex" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-transform-template-literals@^7.10.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.12.1.tgz#b43ece6ed9a79c0c71119f576d299ef09d942843" - integrity sha512-b4Zx3KHi+taXB1dVRBhVJtEPi9h1THCeKmae2qP0YdUHIFhVjtpqqNfxeVAa1xeHVhAy4SbHxEwx5cltAu5apw== + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.13.0.tgz#a36049127977ad94438dee7443598d1cefdf409d" + integrity sha512-d67umW6nlfmr1iehCcBv69eSUSySk1EsIS8aTDX4Xo9qajAh6mYtcl4kJrBkGXuxZPEgVr7RVfAvNW6YQkd4Mw== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-transform-typeof-symbol@^7.10.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.1.tgz#9ca6be343d42512fbc2e68236a82ae64bc7af78a" - integrity sha512-EPGgpGy+O5Kg5pJFNDKuxt9RdmTgj5sgrus2XVeMp/ZIbOESadgILUbm50SNpghOh3/6yrbsH+NB5+WJTmsA7Q== + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.13.tgz#785dd67a1f2ea579d9c2be722de8c84cb85f5a7f" + integrity sha512-eKv/LmUJpMnu4npgfvs3LiHhJua5fo/CysENxa45YCQXZwKnGCQKAg87bvoqSW1fFT+HA32l03Qxsm8ouTY3ZQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-transform-unicode-escapes@^7.10.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.1.tgz#5232b9f81ccb07070b7c3c36c67a1b78f1845709" - integrity sha512-I8gNHJLIc7GdApm7wkVnStWssPNbSRMPtgHdmH3sRM1zopz09UWPS4x5V4n1yz/MIWTVnJ9sp6IkuXdWM4w+2Q== + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.13.tgz#840ced3b816d3b5127dd1d12dcedc5dead1a5e74" + integrity sha512-0bHEkdwJ/sN/ikBHfSmOXPypN/beiGqjo+o4/5K+vxEFNPRPdImhviPakMKG4x96l85emoa0Z6cDflsdBusZbw== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-transform-unicode-regex@^7.10.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.1.tgz#cc9661f61390db5c65e3febaccefd5c6ac3faecb" - integrity sha512-SqH4ClNngh/zGwHZOOQMTD+e8FGWexILV+ePMyiDJttAWRh5dhDL8rcl5lSgU3Huiq6Zn6pWTMvdPAb21Dwdyg== + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.13.tgz#b52521685804e155b1202e83fc188d34bb70f5ac" + integrity sha512-mDRzSNY7/zopwisPZ5kM9XKCfhchqIYwAKRERtEnhYscZB79VRekuRSoYbN0+KVe3y8+q1h6A4svXtP7N+UoCA== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.12.1" - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-create-regexp-features-plugin" "^7.12.13" + "@babel/helper-plugin-utils" "^7.12.13" "@babel/preset-env@7.11.0": version "7.11.0" @@ -1064,13 +1047,13 @@ regenerator-runtime "^0.13.4" "@babel/runtime@^7.8.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.1.tgz#b4116a6b6711d010b2dad3b7b6e43bf1b9954740" - integrity sha512-J5AIf3vPj3UwXaAzb5j1xM4WAQDX3EMgemF8rjCP3SoW09LfRKAXQKt6CoVYl230P6iWdRcBbnLDDdnqWxZSCA== + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.0.tgz#46794bc20b612c5f75e62dd071e24dfd95f1cbe6" + integrity sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA== dependencies: regenerator-runtime "^0.13.4" -"@babel/template@7.10.4", "@babel/template@^7.10.4": +"@babel/template@7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.10.4.tgz#3251996c4200ebc71d1a8fc405fba940f36ba278" integrity sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA== @@ -1079,34 +1062,41 @@ "@babel/parser" "^7.10.4" "@babel/types" "^7.10.4" -"@babel/traverse@^7.10.4", "@babel/traverse@^7.11.0", "@babel/traverse@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.12.1.tgz#941395e0c5cc86d5d3e75caa095d3924526f0c1e" - integrity sha512-MA3WPoRt1ZHo2ZmoGKNqi20YnPt0B1S0GTZEPhhd+hw2KGUzBlHuVunj6K4sNuK+reEvyiPwtp0cpaqLzJDmAw== - dependencies: - "@babel/code-frame" "^7.10.4" - "@babel/generator" "^7.12.1" - "@babel/helper-function-name" "^7.10.4" - "@babel/helper-split-export-declaration" "^7.11.0" - "@babel/parser" "^7.12.1" - "@babel/types" "^7.12.1" +"@babel/template@^7.10.4", "@babel/template@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.12.13.tgz#530265be8a2589dbb37523844c5bcb55947fb327" + integrity sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA== + dependencies: + "@babel/code-frame" "^7.12.13" + "@babel/parser" "^7.12.13" + "@babel/types" "^7.12.13" + +"@babel/traverse@^7.11.0", "@babel/traverse@^7.13.0", "@babel/traverse@^7.13.15", "@babel/traverse@^7.14.0": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.14.0.tgz#cea0dc8ae7e2b1dec65f512f39f3483e8cc95aef" + integrity sha512-dZ/a371EE5XNhTHomvtuLTUyx6UEoJmYX+DT5zBCQN3McHemsuIaKKYqsc/fs26BEkHs/lBZy0J571LP5z9kQA== + dependencies: + "@babel/code-frame" "^7.12.13" + "@babel/generator" "^7.14.0" + "@babel/helper-function-name" "^7.12.13" + "@babel/helper-split-export-declaration" "^7.12.13" + "@babel/parser" "^7.14.0" + "@babel/types" "^7.14.0" debug "^4.1.0" globals "^11.1.0" - lodash "^4.17.19" -"@babel/types@^7.10.4", "@babel/types@^7.10.5", "@babel/types@^7.11.0", "@babel/types@^7.12.1", "@babel/types@^7.4.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.1.tgz#e109d9ab99a8de735be287ee3d6a9947a190c4ae" - integrity sha512-BzSY3NJBKM4kyatSOWh3D/JJ2O3CVzBybHWxtgxnggaxEuaSTTDqeiSb/xk9lrkw2Tbqyivw5ZU4rT+EfznQsA== +"@babel/types@^7.10.4", "@babel/types@^7.11.0", "@babel/types@^7.12.1", "@babel/types@^7.12.13", "@babel/types@^7.13.0", "@babel/types@^7.13.12", "@babel/types@^7.13.16", "@babel/types@^7.14.0", "@babel/types@^7.14.1", "@babel/types@^7.4.4": + version "7.14.1" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.14.1.tgz#095bd12f1c08ab63eff6e8f7745fa7c9cc15a9db" + integrity sha512-S13Qe85fzLs3gYRUnrpyeIrBJIMYv33qSTg1qoBwiG6nPKwUWAD9odSzWhEedpwOIzSEI6gbdQIWEMiCI42iBA== dependencies: - "@babel/helper-validator-identifier" "^7.10.4" - lodash "^4.17.19" + "@babel/helper-validator-identifier" "^7.14.0" to-fast-properties "^2.0.0" "@istanbuljs/schema@^0.1.2": - version "0.1.2" - resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.2.tgz#26520bf09abe4a5644cd5414e37125a8954241dd" - integrity sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw== + version "0.1.3" + resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" + integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== "@jsdevtools/coverage-istanbul-loader@3.0.5": version "3.0.5" @@ -1119,66 +1109,67 @@ merge-source-map "^1.1.0" schema-utils "^2.7.0" -"@ngtools/webpack@10.2.0": - version "10.2.0" - resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-10.2.0.tgz#42a9aba997a69effedd7cba75d0c69756f1b7fc4" - integrity sha512-W4SSFNQhIiC8JRhIn3c4mb1+fsFKiHp+THVMAUNo+wRZEt/rgzsCdnqv0EmQJJojZhnilUIyB/wVYJu2+S/Bxg== +"@ngtools/webpack@10.2.3": + version "10.2.3" + resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-10.2.3.tgz#e4e410d1d647b6e21a69ab20c00c110464f623ea" + integrity sha512-h7JJMMca1bHY/0Prpxu2P3bvnC6pUKmBAfqN0h0HaRN9LTU9IDWtDRTIL1Aqhs/tcTUio/DowVKnVi2CWHAOmg== dependencies: - "@angular-devkit/core" "10.2.0" + "@angular-devkit/core" "10.2.3" enhanced-resolve "4.3.0" webpack-sources "1.4.3" -"@nodelib/fs.scandir@2.1.3": - version "2.1.3" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz#3a582bdb53804c6ba6d146579c46e52130cf4a3b" - integrity sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw== +"@nodelib/fs.scandir@2.1.4": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz#d4b3549a5db5de2683e0c1071ab4f140904bbf69" + integrity sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA== dependencies: - "@nodelib/fs.stat" "2.0.3" + "@nodelib/fs.stat" "2.0.4" run-parallel "^1.1.9" -"@nodelib/fs.stat@2.0.3", "@nodelib/fs.stat@^2.0.2": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz#34dc5f4cabbc720f4e60f75a747e7ecd6c175bd3" - integrity sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA== +"@nodelib/fs.stat@2.0.4", "@nodelib/fs.stat@^2.0.2": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz#a3f2dd61bab43b8db8fa108a121cfffe4c676655" + integrity sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q== "@nodelib/fs.walk@^1.2.3": - version "1.2.4" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz#011b9202a70a6366e436ca5c065844528ab04976" - integrity sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ== + version "1.2.6" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz#cce9396b30aa5afe9e3756608f5831adcb53d063" + integrity sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow== dependencies: - "@nodelib/fs.scandir" "2.1.3" + "@nodelib/fs.scandir" "2.1.4" fastq "^1.6.0" "@npmcli/move-file@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-1.0.1.tgz#de103070dac0f48ce49cf6693c23af59c0f70464" - integrity sha512-Uv6h1sT+0DrblvIrolFtbvM1FgWm+/sy4B3pvLp67Zys+thcukzS5ekn7HsZFGpWP4Q3fYJCljbWQE/XivMRLw== + version "1.1.2" + resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-1.1.2.tgz#1a82c3e372f7cae9253eb66d72543d6b8685c674" + integrity sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg== dependencies: mkdirp "^1.0.4" + rimraf "^3.0.2" "@saritasa/tslint-config-angular@^2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@saritasa/tslint-config-angular/-/tslint-config-angular-2.0.0.tgz#9e76c98081b1bc54c260e1c27abd5cd4ef8d2525" integrity sha512-zs7nOOgxOA3WpNeRLS2Qcuu0BHU/GN/n9Kfbv//w0fzZinxeZKMaLOOnDcSlq4JGgOp6AbVJeCR8l50enwEasQ== -"@schematics/angular@10.2.0": - version "10.2.0" - resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-10.2.0.tgz#30fb6ab3500592a243b9a19398b7c724ee6b3be7" - integrity sha512-rJRTTTL8CMMFb3ebCvAVHKHxuNzRqy/HtbXhJ82l5Xo/jXcm74eV2Q0RBUrNo1yBKWFIR+FIwiXLJaGcC/R9Pw== +"@schematics/angular@10.2.3": + version "10.2.3" + resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-10.2.3.tgz#a5ea7e9bc17fbfb9b1c5f760f44bc4a7b0b18834" + integrity sha512-xcnfH5XMmGcs33VHm2cu0+4g3rkfSD+qpiKFjfg7KGC4lLoOKSED4ZnjzIYwcQ6QN4gTpAvlZKxI8zO7NkKv0A== dependencies: - "@angular-devkit/core" "10.2.0" - "@angular-devkit/schematics" "10.2.0" + "@angular-devkit/core" "10.2.3" + "@angular-devkit/schematics" "10.2.3" jsonc-parser "2.3.0" -"@schematics/update@0.1002.0": - version "0.1002.0" - resolved "https://registry.yarnpkg.com/@schematics/update/-/update-0.1002.0.tgz#ff4c134afe1796960f51308ff4e07218f70a6bbd" - integrity sha512-g2bfJSAj3x/YL0GNhnHsDSQmO6DoxSnLxoFLqNN5+ukxK5jq7OZNDwMJGxZ3X6RcSMWKEkIKL/wlq9yhj2T/kw== +"@schematics/update@0.1002.3": + version "0.1002.3" + resolved "https://registry.yarnpkg.com/@schematics/update/-/update-0.1002.3.tgz#75b016d44c98e77eaaff0be844144d867a224cd1" + integrity sha512-UnuMgRQtAOp/Pk9rSYW12medajXe9s5mW4a6foixC/B2UCFFlIAVbFBTiFpr69xbalfLlFcFx1MD+8/8njWtbQ== dependencies: - "@angular-devkit/core" "10.2.0" - "@angular-devkit/schematics" "10.2.0" + "@angular-devkit/core" "10.2.3" + "@angular-devkit/schematics" "10.2.3" "@yarnpkg/lockfile" "1.1.0" - ini "1.3.5" + ini "1.3.6" npm-package-arg "^8.0.0" pacote "9.5.12" semver "7.3.2" @@ -1193,24 +1184,24 @@ "@types/node" "*" "@types/json-schema@^7.0.5": - version "7.0.6" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.6.tgz#f4c7ec43e81b319a9815115031709f26987891f0" - integrity sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw== + version "7.0.7" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad" + integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA== "@types/minimatch@*": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" - integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.4.tgz#f0ec25dbf2f0e4b18647313ac031134ca5b24b21" + integrity sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA== "@types/node@*": - version "14.14.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.6.tgz#146d3da57b3c636cc0d1769396ce1cfa8991147f" - integrity sha512-6QlRuqsQ/Ox/aJEQWBEJG7A9+u7oSYl3mem/K8IzxXG/kAGbV1YPD9Bg9Zw3vyxC/YP+zONKwy8hGkSt1jxFMw== + version "15.0.2" + resolved "https://registry.yarnpkg.com/@types/node/-/node-15.0.2.tgz#51e9c0920d1b45936ea04341aa3e2e58d339fb67" + integrity sha512-p68+a+KoxpoB47015IeYZYRrdqMUcpbK8re/zpFB8Ld46LHC1lPEbp3EXgkEhAYEcPvjJF6ZO+869SQ0aH1dcA== "@types/node@^12.11.1": - version "12.19.3" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.19.3.tgz#a6e252973214079155f749e8bef99cc80af182fa" - integrity sha512-8Jduo8wvvwDzEVJCOvS/G6sgilOLvvhn1eMmK3TW8/T217O7u1jdrK6ImKLv80tVryaPSVeKu6sjDEiFjd4/eg== + version "12.20.12" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.12.tgz#fd9c1c2cfab536a2383ed1ef70f94adea743a226" + integrity sha512-KQZ1al2hKOONAs2MFv+yTQP1LkDWMrRJ9YCVRalXltOfXsBmH5IownLxQaiq0lnAHwAViLnh2aTYqrPcRGEbgg== "@types/q@^1.5.1": version "1.5.4" @@ -1512,11 +1503,11 @@ ansi-colors@^3.0.0: integrity sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA== ansi-escapes@^4.2.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.1.tgz#a5c47cc43181f1f38ffd7076837700d395522a61" - integrity sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA== + version "4.3.2" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" + integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== dependencies: - type-fest "^0.11.0" + type-fest "^0.21.3" ansi-html@0.0.7: version "0.0.7" @@ -1561,9 +1552,9 @@ anymatch@^2.0.0: normalize-path "^2.1.1" anymatch@~3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" - integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg== + version "3.1.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== dependencies: normalize-path "^3.0.0" picomatch "^2.0.4" @@ -1735,7 +1726,7 @@ autoprefixer@9.8.6: postcss "^7.0.32" postcss-value-parser "^4.1.0" -available-typed-arrays@^1.0.0, available-typed-arrays@^1.0.2: +available-typed-arrays@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz#6b098ca9d8039079ee3f77f7b783c4480ba513f5" integrity sha512-XWX3OX8Onv97LMk/ftVyBibpGwY5a8SmuxZPzeOxqmuEqUCOM9ZE+uIaD1VNJ5QnvU2UQusvmKbuM1FR8QWGfQ== @@ -1748,9 +1739,9 @@ aws-sign2@~0.7.0: integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= aws4@^1.8.0: - version "1.10.1" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.10.1.tgz#e1e82e4f3e999e2cfd61b161280d16a111f86428" - integrity sha512-zg7Hz2k5lI8kb7U32998pRRFin7zJlkfezGJjUc2heaD4Pw2wObakCDVzkKztTm/Ln7eiVvYsjqak0Ed4LkMDA== + version "1.11.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" + integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== axobject-query@2.0.2: version "2.0.2" @@ -1778,14 +1769,14 @@ babel-plugin-dynamic-import-node@^2.3.3: object.assign "^4.1.0" balanced-match@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== base64-js@^1.0.2: - version "1.3.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" - integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== base@^0.11.1: version "0.11.2" @@ -1823,9 +1814,9 @@ binary-extensions@^1.0.0: integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== binary-extensions@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.1.0.tgz#30fa40c9e7fe07dbc895678cd287024dea241dd9" - integrity sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ== + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== bindings@^1.5.0: version "1.5.0" @@ -1844,10 +1835,10 @@ bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.9: resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== -bn.js@^5.1.1: - version "5.1.3" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.1.3.tgz#beca005408f642ebebea80b042b4d18d2ac0ee6b" - integrity sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ== +bn.js@^5.0.0, bn.js@^5.1.1: + version "5.2.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.0.tgz#358860674396c6997771a9d051fcc1b57d4ae002" + integrity sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw== body-parser@1.19.0: version "1.19.0" @@ -1883,9 +1874,9 @@ boolbase@^1.0.0, boolbase@~1.0.0: integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= bootstrap@^4.2.1: - version "4.5.3" - resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.5.3.tgz#c6a72b355aaf323920be800246a6e4ef30997fe6" - integrity sha512-o9ppKQioXGqhw8Z7mah6KdTYpNQY//tipnkxppWhPbiSWdD+1raYsnhwEZjkTHYbGee4cVQ0Rx65EhOY/HNLcQ== + version "4.6.0" + resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.6.0.tgz#97b9f29ac98f98dfa43bf7468262d84392552fd7" + integrity sha512-Io55IuQY3kydzHtbGvQya3H+KorS/M9rSNyfCGCg9WZ4pyT/lCxIlpJgG1GXW/PswzC84Tr2fBYi+7+jFVQQBw== brace-expansion@^1.1.7: version "1.1.11" @@ -1960,11 +1951,11 @@ browserify-des@^1.0.0: safe-buffer "^5.1.2" browserify-rsa@^4.0.0, browserify-rsa@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" - integrity sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ= + version "4.1.0" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.1.0.tgz#b2fd06b5b75ae297f7ce2dc651f918f5be158c8d" + integrity sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog== dependencies: - bn.js "^4.1.0" + bn.js "^5.0.0" randombytes "^2.0.1" browserify-sign@^4.0.0: @@ -1989,15 +1980,16 @@ browserify-zlib@^0.2.0: dependencies: pako "~1.0.5" -browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.8.5, browserslist@^4.9.1: - version "4.14.5" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.14.5.tgz#1c751461a102ddc60e40993639b709be7f2c4015" - integrity sha512-Z+vsCZIvCBvqLoYkBFTwEYH3v5MCQbsAjp50ERycpOjnPmolg1Gjy4+KaWWpm8QOJt9GHkhdqAl14NpCX73CWA== +browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.16.6, browserslist@^4.9.1: + version "4.16.6" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.6.tgz#d7901277a5a88e554ed305b183ec9b0c08f66fa2" + integrity sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ== dependencies: - caniuse-lite "^1.0.30001135" - electron-to-chromium "^1.3.571" - escalade "^3.1.0" - node-releases "^1.1.61" + caniuse-lite "^1.0.30001219" + colorette "^1.2.2" + electron-to-chromium "^1.3.723" + escalade "^3.1.1" + node-releases "^1.1.71" buffer-from@^1.0.0: version "1.1.1" @@ -2048,7 +2040,7 @@ bytes@3.1.0: resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== -cacache@15.0.5, cacache@^15.0.4, cacache@^15.0.5: +cacache@15.0.5: version "15.0.5" resolved "https://registry.yarnpkg.com/cacache/-/cacache-15.0.5.tgz#69162833da29170d6732334643c60e005f5f17d0" integrity sha512-lloiL22n7sOjEEXdL8NAjTgv9a1u43xICE9/203qonkZUCj5X1UEWIdf2/Y0d6QcCtMzbKQyhrcDbdvlZTs/+A== @@ -2092,6 +2084,29 @@ cacache@^12.0.0, cacache@^12.0.2: unique-filename "^1.1.1" y18n "^4.0.0" +cacache@^15.0.4, cacache@^15.0.5: + version "15.0.6" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-15.0.6.tgz#65a8c580fda15b59150fb76bf3f3a8e45d583099" + integrity sha512-g1WYDMct/jzW+JdWEyjaX2zoBkZ6ZT9VpOyp2I/VMtDsNLffNat3kqPFfi1eDRSK9/SuKGyORDHcQMcPF8sQ/w== + dependencies: + "@npmcli/move-file" "^1.0.1" + chownr "^2.0.0" + fs-minipass "^2.0.0" + glob "^7.1.4" + infer-owner "^1.0.4" + lru-cache "^6.0.0" + minipass "^3.1.1" + minipass-collect "^1.0.2" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.2" + mkdirp "^1.0.3" + p-map "^4.0.0" + promise-inflight "^1.0.1" + rimraf "^3.0.2" + ssri "^8.0.1" + tar "^6.0.2" + unique-filename "^1.1.1" + cache-base@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" @@ -2107,6 +2122,14 @@ cache-base@^1.0.1: union-value "^1.0.0" unset-value "^1.0.0" +call-bind@^1.0.0, call-bind@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + caller-callsite@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" @@ -2132,9 +2155,9 @@ camelcase@5.3.1, camelcase@^5.0.0: integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== camelcase@^6.0.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.1.0.tgz#27dc176173725fb0adf8a48b647f4d7871944d78" - integrity sha512-WCMml9ivU60+8rEJgELlFp1gxFcEGxwYleE3bziHEDeqsqAWGHdimB7beBFGjLzVNgPGyDsfgXLQEYMpmIFnVQ== + version "6.2.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809" + integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== caniuse-api@^3.0.0: version "3.0.0" @@ -2146,10 +2169,10 @@ caniuse-api@^3.0.0: lodash.memoize "^4.1.2" lodash.uniq "^4.5.0" -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001032, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001135: - version "1.0.30001151" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001151.tgz#1ddfde5e6fff02aad7940b4edb7d3ac76b0cb00b" - integrity sha512-Zh3sHqskX6mHNrqUerh+fkf0N72cMxrmflzje/JyVImfpknscMnkeJrlFGJcqTmaa0iszdYptGpWMJCRQDkBVw== +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001032, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001219: + version "1.0.30001228" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001228.tgz#bfdc5942cd3326fa51ee0b42fbef4da9d492a7fa" + integrity sha512-QQmLOGJ3DEgokHbMSA8cj2a+geXqmnpyOFT0lhQV6P3/YOJvGDEwoedcwxEQ30gJIwIIunHIicunJ2rzK5gB2A== canonical-path@1.0.0: version "1.0.0" @@ -2170,10 +2193,10 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^4.0.0, chalk@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" - integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A== +chalk@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.1.tgz#c80b3fab28bf6371e6863325eee67e618b77e6ad" + integrity sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg== dependencies: ansi-styles "^4.1.0" supports-color "^7.1.0" @@ -2184,9 +2207,9 @@ chardet@^0.7.0: integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== "chokidar@>=2.0.0 <4.0.0", chokidar@^3.0.0, chokidar@^3.4.1: - version "3.4.3" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.4.3.tgz#c1df38231448e45ca4ac588e6c79573ba6a57d5b" - integrity sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ== + version "3.5.1" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a" + integrity sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw== dependencies: anymatch "~3.1.1" braces "~3.0.2" @@ -2196,7 +2219,7 @@ chardet@^0.7.0: normalize-path "~3.0.0" readdirp "~3.5.0" optionalDependencies: - fsevents "~2.1.2" + fsevents "~2.3.1" chokidar@^2.1.8: version "2.1.8" @@ -2228,11 +2251,9 @@ chownr@^2.0.0: integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== chrome-trace-event@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz#234090ee97c7d4ad1a2c4beae27505deffc608a4" - integrity sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ== - dependencies: - tslib "^1.9.0" + version "1.0.3" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" + integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: version "1.0.4" @@ -2270,9 +2291,9 @@ cli-cursor@^3.1.0: restore-cursor "^3.1.0" cli-spinners@^2.4.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.5.0.tgz#12763e47251bf951cb75c201dfa58ff1bcb2d047" - integrity sha512-PC+AmIuK04E6aeSs/pUccSujsTzBhu4HzC2dL+CfJB/Jcc2qTRbEwZQDfIUpt2Xl8BodYBEq8w4fc0kU2I9DjQ== + version "2.6.0" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.6.0.tgz#36c7dc98fb6a9a76bd6238ec3f77e2425627e939" + integrity sha512-t+4/y50K/+4xcCRosKkA7W4gTr1MySvLV0q+PxmG7FJ5g+66ChKurYjxBCjHggHH3HA5Hh9cy+lcUGWDqVH+4Q== cli-width@^3.0.0: version "3.0.0" @@ -2288,14 +2309,14 @@ cliui@^5.0.0: strip-ansi "^5.2.0" wrap-ansi "^5.1.0" -cliui@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1" - integrity sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ== +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== dependencies: string-width "^4.2.0" strip-ansi "^6.0.0" - wrap-ansi "^6.2.0" + wrap-ansi "^7.0.0" clone@^1.0.2: version "1.0.4" @@ -2364,9 +2385,9 @@ color-name@^1.0.0, color-name@~1.1.4: integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== color-string@^1.5.4: - version "1.5.4" - resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.4.tgz#dd51cd25cfee953d138fe4002372cc3d0e504cb6" - integrity sha512-57yF5yt8Xa3czSEW1jfQDE79Idk0+AkN/4KWad6tbdxUmAs3MvjxlWSWD4deYytcRfoZ9nhKyFl1kj5tBvidbw== + version "1.5.5" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.5.tgz#65474a8f0e7439625f3d27a6a19d89fc45223014" + integrity sha512-jgIoum0OfQfq9Whcfc2z/VhCNcmQjWbey6qBX0vqt7YICflUmBCh9E9CiQD5GSJ+Uehixm3NUwHVhqUAWRivZg== dependencies: color-name "^1.0.0" simple-swizzle "^0.2.2" @@ -2379,10 +2400,10 @@ color@^3.0.0: color-convert "^1.9.1" color-string "^1.5.4" -colorette@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.1.tgz#4d0b921325c14faf92633086a536db6e89564b1b" - integrity sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw== +colorette@^1.2.1, colorette@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94" + integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w== combined-stream@^1.0.6, combined-stream@~1.0.6: version "1.0.8" @@ -2497,6 +2518,13 @@ cookie@0.4.0: resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== +copy-anything@^2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/copy-anything/-/copy-anything-2.0.3.tgz#842407ba02466b0df844819bbe3baebbe5d45d87" + integrity sha512-GK6QUtisv4fNS+XcI7shX0Gx9ORg7QqIznyfho79JTnX1XhLiyZHfftvGiziqzRiEi/Bjhgpi+D2o7HxJFPnDQ== + dependencies: + is-what "^3.12.0" + copy-concurrently@^1.0.0: version "1.0.5" resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" @@ -2532,11 +2560,11 @@ copy-webpack-plugin@6.0.3: webpack-sources "^1.4.3" core-js-compat@^3.6.2: - version "3.6.5" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.6.5.tgz#2a51d9a4e25dfd6e690251aa81f99e3c05481f1c" - integrity sha512-7ItTKOhOZbznhXAQ2g/slGg1PJV5zDO/WdkTwi7UEOJmkvsE32PWvx6mKtDjiMpjnR2CNf6BAD6sSxIlv7ptng== + version "3.12.1" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.12.1.tgz#2c302c4708505fa7072b0adb5156d26f7801a18b" + integrity sha512-i6h5qODpw6EsHAoIdQhKoZdWn+dGBF3dSS8m5tif36RlWvW3A6+yu2S16QHUo3CrkzrnEskMAt9f8FxmY9fhWQ== dependencies: - browserslist "^4.8.5" + browserslist "^4.16.6" semver "7.0.0" core-js@3.6.4: @@ -2545,9 +2573,9 @@ core-js@3.6.4: integrity sha512-4paDGScNgZP2IXXilaffL9X7968RuvwlkK3xWtZRVqgd8SYNiVKRJvkFd1aqqEuPfN7E68ZHEp9hDj6lHj4Hyw== core-js@^3.6.4: - version "3.6.5" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.6.5.tgz#7395dc273af37fb2e50e9bd3d9fe841285231d1a" - integrity sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA== + version "3.12.1" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.12.1.tgz#6b5af4ff55616c08a44d386f1f510917ff204112" + integrity sha512-Ne9DKPHTObRuB09Dru5AjwKjY4cJHVGu+y5f7coGn1E9Grkc3p2iBwE9AI/nJzsE29mQF7oq+mhYYRqOMFN1Bw== core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" @@ -2692,12 +2720,12 @@ css-tree@1.0.0-alpha.37: mdn-data "2.0.4" source-map "^0.6.1" -css-tree@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0.tgz#21993fa270d742642a90409a2c0cb3ac0298adf6" - integrity sha512-CdVYz/Yuqw0VdKhXPBIgi8DO3NicJVYZNWeX9XcIuSp9ZoFT5IcleVRW07O5rMjdcx1mb+MEJPknTTEW7DdsYw== +css-tree@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d" + integrity sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q== dependencies: - mdn-data "2.0.12" + mdn-data "2.0.14" source-map "^0.6.1" css-what@^3.2.1: @@ -2728,9 +2756,9 @@ cssesc@^3.0.0: integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== cssnano-preset-default@^4.0.7: - version "4.0.7" - resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-4.0.7.tgz#51ec662ccfca0f88b396dcd9679cdb931be17f76" - integrity sha512-x0YHHx2h6p0fCl1zY9L9roD7rnlltugGu7zXSKQx6k2rYw0Hi3IqxcoAGF7u9Q5w1nt7vK0ulxV8Lo+EvllGsA== + version "4.0.8" + resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-4.0.8.tgz#920622b1fc1e95a34e8838203f1397a504f2d3ff" + integrity sha512-LdAyHuq+VRyeVREFmuxUZR1TXjQm8QQU/ktoo/x7bz+SdOge1YKc5eMN6pRW7YWBmyq59CqYba1dJ5cUukEjLQ== dependencies: css-declaration-sorter "^4.0.1" cssnano-util-raw-cache "^4.0.1" @@ -2760,7 +2788,7 @@ cssnano-preset-default@^4.0.7: postcss-ordered-values "^4.1.2" postcss-reduce-initial "^4.0.3" postcss-reduce-transforms "^4.0.2" - postcss-svgo "^4.0.2" + postcss-svgo "^4.0.3" postcss-unique-selectors "^4.0.1" cssnano-util-get-arguments@^4.0.0: @@ -2796,11 +2824,11 @@ cssnano@4.1.10: postcss "^7.0.0" csso@^4.0.2: - version "4.1.0" - resolved "https://registry.yarnpkg.com/csso/-/csso-4.1.0.tgz#1d31193efa99b87aa6bad6c0cef155e543d09e8b" - integrity sha512-h+6w/W1WqXaJA4tb1dk7r5tVbOm97MsKxzwnvOR04UQ6GILroryjMWu3pmCCtL2mLaEStQ0fZgeGiy99mo7iyg== + version "4.2.0" + resolved "https://registry.yarnpkg.com/csso/-/csso-4.2.0.tgz#ea3a561346e8dc9f546d6febedd50187cf389529" + integrity sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA== dependencies: - css-tree "^1.0.0" + css-tree "^1.1.2" cyclist@^1.0.1: version "1.0.1" @@ -2816,9 +2844,9 @@ d@1, d@^1.0.1: type "^1.0.1" damerau-levenshtein@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.6.tgz#143c1641cb3d85c60c32329e26899adea8701791" - integrity sha512-JVrozIeElnj3QzfUIt8tB8YMluBJom4Vw9qTPpjGYQ9fYlB3D/rb6OordUxf3xeFB35LKWs0xqcO5U6ySvBtug== + version "1.0.7" + resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.7.tgz#64368003512a1a6992593741a09a9d31a836f55d" + integrity sha512-VvdQIPGdWP0SqFXghj79Wf/5LArmreyMsGLa6FG6iC4t3j7j5s71TrwWmT/4akbDQIqjfACkLZmjXhA7g2oUZw== dashdash@^1.12.0: version "1.14.1" @@ -2858,16 +2886,16 @@ debug@4.1.1: ms "^2.1.1" debug@^3.1.0, debug@^3.1.1, debug@^3.2.5: - version "3.2.6" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" - integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== dependencies: ms "^2.1.1" debug@^4.1.0, debug@^4.1.1: - version "4.2.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.2.0.tgz#7f150f93920e94c58f5574c2fd01a3110effe7f1" - integrity sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg== + version "4.3.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" + integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== dependencies: ms "2.1.2" @@ -2899,19 +2927,20 @@ deep-equal@^1.0.1: regexp.prototype.flags "^1.2.0" deep-equal@^2.0.1: - version "2.0.4" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.0.4.tgz#6b0b407a074666033169df3acaf128e1c6f3eab6" - integrity sha512-BUfaXrVoCfgkOQY/b09QdO9L3XNoF2XH0A3aY9IQwQL/ZjLOe8FQgCNVl1wiolhsFo8kFdO9zdPViCPbmaJA5w== + version "2.0.5" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.0.5.tgz#55cd2fe326d83f9cbf7261ef0e060b3f724c5cb9" + integrity sha512-nPiRgmbAtm1a3JsnLCf6/SLfXcjyN5v8L1TXzdCmHrXJ4hx+gW/w1YCcn7z8gJtSiDArZCgYtbao3QqLm/N1Sw== dependencies: - es-abstract "^1.18.0-next.1" - es-get-iterator "^1.1.0" + call-bind "^1.0.0" + es-get-iterator "^1.1.1" + get-intrinsic "^1.0.1" is-arguments "^1.0.4" is-date-object "^1.0.2" is-regex "^1.1.1" isarray "^2.0.5" - object-is "^1.1.3" + object-is "^1.1.4" object-keys "^1.1.1" - object.assign "^4.1.1" + object.assign "^4.1.2" regexp.prototype.flags "^1.3.0" side-channel "^1.0.3" which-boxed-primitive "^1.0.1" @@ -3004,9 +3033,9 @@ destroy@~1.0.4: integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= detect-node@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c" - integrity sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw== + version "2.0.5" + resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.5.tgz#9d270aa7eaa5af0b72c4c9d9b814e7f4ce738b79" + integrity sha512-qi86tE6hRcFHy8jI1m2VG+LaPUR1LhqDa5G8tVjuUXmOrpuAgqsA1pN0+ldgr3aKUH+QLI9hCY/OcRYisERejw== dezalgo@^1.0.0: version "1.0.3" @@ -3076,9 +3105,9 @@ domelementtype@1: integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== domelementtype@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.0.2.tgz#f3b6e549201e46f588b59463dd77187131fe6971" - integrity sha512-wFwTwCVebUrMgGeAwRL/NhZtHAUyT9n9yg4IMDwf10+6iCMxSkVq9MGCVEH+QZWo1nNidy8kNvwmv4zWHDTqvA== + version "2.2.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.2.0.tgz#9a0b6c2782ed6a1c7323d42267183df9bd8b1d57" + integrity sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A== domino@^2.1.2: version "2.1.6" @@ -3123,10 +3152,10 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= -electron-to-chromium@^1.3.571: - version "1.3.584" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.584.tgz#506cf7ba5895aafa8241876ab028654b61fd9ceb" - integrity sha512-NB3DzrTzJFhWkUp+nl2KtUtoFzrfGXTir2S+BU4tXGyXH9vlluPuFpE3pTKeH7+PY460tHLjKzh6K2+TWwW+Ww== +electron-to-chromium@^1.3.723: + version "1.3.727" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.727.tgz#857e310ca00f0b75da4e1db6ff0e073cc4a91ddf" + integrity sha512-Mfz4FIB4FSvEwBpDfdipRIrwd6uo8gUDoRDF4QEYb4h4tSuI3ov594OrjU6on042UlFHouIJpClDODGkPcBSbg== elliptic@^6.5.3: version "6.5.4" @@ -3185,7 +3214,7 @@ end-of-stream@^1.0.0, end-of-stream@^1.1.0: dependencies: once "^1.4.0" -enhanced-resolve@4.3.0, enhanced-resolve@^4.3.0: +enhanced-resolve@4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.3.0.tgz#3b806f3bfafc1ec7de69551ef93cca46c1704126" integrity sha512-3e87LvavsdxyoCfGusJnrZ5G8SLPOFeHSNpZI/ATL9a5leXo2k0w6MKnbqhdBad9qTobSfB20Ld7UmgoNbAZkQ== @@ -3194,10 +3223,19 @@ enhanced-resolve@4.3.0, enhanced-resolve@^4.3.0: memory-fs "^0.5.0" tapable "^1.0.0" +enhanced-resolve@^4.3.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz#2f3cfd84dbe3b487f18f2db2ef1e064a571ca5ec" + integrity sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg== + dependencies: + graceful-fs "^4.1.2" + memory-fs "^0.5.0" + tapable "^1.0.0" + entities@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/entities/-/entities-2.1.0.tgz#992d3129cf7df6870b96c57858c249a120f8b8b5" - integrity sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w== + version "2.2.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" + integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== err-code@^1.0.0: version "1.1.2" @@ -3205,9 +3243,9 @@ err-code@^1.0.0: integrity sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA= errno@^0.1.1, errno@^0.1.3, errno@~0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" - integrity sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg== + version "0.1.8" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" + integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A== dependencies: prr "~1.0.1" @@ -3218,51 +3256,39 @@ error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" -es-abstract@^1.17.0-next.1, es-abstract@^1.17.2, es-abstract@^1.17.4, es-abstract@^1.17.5: - version "1.17.7" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.7.tgz#a4de61b2f66989fc7421676c1cb9787573ace54c" - integrity sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g== +es-abstract@^1.17.2, es-abstract@^1.18.0-next.1, es-abstract@^1.18.0-next.2: + version "1.18.0" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.0.tgz#ab80b359eecb7ede4c298000390bc5ac3ec7b5a4" + integrity sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw== dependencies: + call-bind "^1.0.2" es-to-primitive "^1.2.1" function-bind "^1.1.1" + get-intrinsic "^1.1.1" has "^1.0.3" - has-symbols "^1.0.1" - is-callable "^1.2.2" - is-regex "^1.1.1" - object-inspect "^1.8.0" - object-keys "^1.1.1" - object.assign "^4.1.1" - string.prototype.trimend "^1.0.1" - string.prototype.trimstart "^1.0.1" - -es-abstract@^1.18.0-next.0, es-abstract@^1.18.0-next.1: - version "1.18.0-next.1" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.0-next.1.tgz#6e3a0a4bda717e5023ab3b8e90bec36108d22c68" - integrity sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA== - dependencies: - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.1" - is-callable "^1.2.2" - is-negative-zero "^2.0.0" - is-regex "^1.1.1" - object-inspect "^1.8.0" + has-symbols "^1.0.2" + is-callable "^1.2.3" + is-negative-zero "^2.0.1" + is-regex "^1.1.2" + is-string "^1.0.5" + object-inspect "^1.9.0" object-keys "^1.1.1" - object.assign "^4.1.1" - string.prototype.trimend "^1.0.1" - string.prototype.trimstart "^1.0.1" + object.assign "^4.1.2" + string.prototype.trimend "^1.0.4" + string.prototype.trimstart "^1.0.4" + unbox-primitive "^1.0.0" -es-get-iterator@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.0.tgz#bb98ad9d6d63b31aacdc8f89d5d0ee57bcb5b4c8" - integrity sha512-UfrmHuWQlNMTs35e1ypnvikg6jCz3SK8v8ImvmDsh36fCVUR1MqoFDiyn0/k52C8NqO3YsO8Oe0azeesNuqSsQ== +es-get-iterator@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.2.tgz#9234c54aba713486d7ebde0220864af5e2b283f7" + integrity sha512-+DTO8GYwbMCwbywjimwZMHp8AuYXOS2JZFWoi2AlPOS3ebnII9w/NLpNZtA7A0YLaVDw+O7KFCeoIV7OPvM7hQ== dependencies: - es-abstract "^1.17.4" + call-bind "^1.0.2" + get-intrinsic "^1.1.0" has-symbols "^1.0.1" - is-arguments "^1.0.4" - is-map "^2.0.1" - is-set "^2.0.1" + is-arguments "^1.1.0" + is-map "^2.0.2" + is-set "^2.0.2" is-string "^1.0.5" isarray "^2.0.5" @@ -3313,7 +3339,7 @@ es6-symbol@^3.1.1, es6-symbol@~3.1.3: d "^1.0.1" ext "^1.1.2" -escalade@^3.1.0: +escalade@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== @@ -3374,14 +3400,14 @@ eventemitter3@^4.0.0: integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== events@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/events/-/events-3.2.0.tgz#93b87c18f8efcd4202a461aec4dfc0556b639379" - integrity sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg== + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== eventsource@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-1.0.7.tgz#8fbc72c93fcd34088090bc0a4e64f4b5cee6d8d0" - integrity sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ== + version "1.1.0" + resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-1.1.0.tgz#00e8ca7c92109e94b0ddf32dac677d841028cfaf" + integrity sha512-VSJjT5oCNrFvCS6igjzPAt5hBzQ2qPBFIbJ03zLI9SE0mxwZpMw6BfJrbFHm1a141AavMEB8JHmBhWAd66PfCg== dependencies: original "^1.0.0" @@ -3521,9 +3547,9 @@ fast-deep-equal@^3.1.1: integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== fast-glob@^3.1.1, fast-glob@^3.2.4: - version "3.2.4" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.4.tgz#d20aefbf99579383e7f3cc66529158c9b98554d3" - integrity sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ== + version "3.2.5" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.5.tgz#7939af2a656de79a4f1901903ee8adcaa7cb9661" + integrity sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg== dependencies: "@nodelib/fs.stat" "^2.0.2" "@nodelib/fs.walk" "^1.2.3" @@ -3543,9 +3569,9 @@ fastparse@^1.1.2: integrity sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ== fastq@^1.6.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.9.0.tgz#e16a72f338eaca48e91b5c23593bcc2ef66b7947" - integrity sha512-i7FVWL8HhVY+CTkwFxkN2mk3h+787ixS5S63eb78diVRc1MCssarHq3W5cj0av7YDSwmaV928RNag+U1etRQ7w== + version "1.11.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.11.0.tgz#bb9fb955a07130a918eb63c1f5161cc32a5d0858" + integrity sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g== dependencies: reusify "^1.0.4" @@ -3643,7 +3669,7 @@ find-up@^3.0.0: dependencies: locate-path "^3.0.0" -find-up@^4.0.0, find-up@^4.1.0: +find-up@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== @@ -3660,9 +3686,9 @@ flush-write-stream@^1.0.0: readable-stream "^2.3.6" follow-redirects@^1.0.0: - version "1.13.0" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.0.tgz#b42e8d93a2a7eea5ed88633676d6597bc8e384db" - integrity sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA== + version "1.14.1" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.1.tgz#d9114ded0a1cfdd334e164e6662ad02bfd91ff43" + integrity sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg== for-in@^1.0.2: version "1.0.2" @@ -3764,6 +3790,11 @@ fsevents@~2.1.2: resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== +fsevents@~2.3.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" @@ -3774,16 +3805,25 @@ genfun@^5.0.0: resolved "https://registry.yarnpkg.com/genfun/-/genfun-5.0.0.tgz#9dd9710a06900a5c4a5bf57aca5da4e52fe76537" integrity sha512-KGDOARWVga7+rnB3z9Sd2Letx515owfk0hSxHGuqjANb1M+x2bGZGqHLiozPsYMdM2OubeMni/Hpwmjq6qIUhA== -gensync@^1.0.0-beta.1: +gensync@^1.0.0-beta.1, gensync@^1.0.0-beta.2: version "1.0.0-beta.2" resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== -get-caller-file@^2.0.1: +get-caller-file@^2.0.1, get-caller-file@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== +get-intrinsic@^1.0.1, get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" + integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + get-stream@^4.0.0, get-stream@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" @@ -3812,13 +3852,13 @@ glob-parent@^3.1.0: path-dirname "^1.0.0" glob-parent@^5.1.0, glob-parent@^5.1.1, glob-parent@~5.1.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" - integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ== + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== dependencies: is-glob "^4.0.1" -glob@7.1.6, glob@^7.0.3, glob@^7.1.1, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: +glob@7.1.6: version "7.1.6" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== @@ -3830,15 +3870,27 @@ glob@7.1.6, glob@^7.0.3, glob@^7.1.1, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: once "^1.3.0" path-is-absolute "^1.0.0" +glob@^7.0.3, glob@^7.1.1, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: + version "7.1.7" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" + integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + globals@^11.1.0: version "11.12.0" resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== globby@^11.0.1: - version "11.0.1" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.1.tgz#9a2bf107a068f3ffeabc49ad702c79ede8cfd357" - integrity sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ== + version "11.0.3" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.3.tgz#9b1f0cb523e171dd1ad8c7b2a9fb4b644b9593cb" + integrity sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg== dependencies: array-union "^2.1.0" dir-glob "^3.0.1" @@ -3859,9 +3911,9 @@ globby@^6.1.0: pinkie-promise "^2.0.0" graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6: - version "4.2.4" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" - integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== + version "4.2.6" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" + integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== hammerjs@^2.0.8: version "2.0.8" @@ -3886,6 +3938,11 @@ har-validator@~5.1.3: ajv "^6.12.3" har-schema "^2.0.0" +has-bigints@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" + integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== + has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -3896,10 +3953,10 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== -has-symbols@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" - integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== +has-symbols@^1.0.1, has-symbols@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" + integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== has-value@^0.3.1: version "0.3.1" @@ -3971,14 +4028,21 @@ hmac-drbg@^1.0.1: minimalistic-crypto-utils "^1.0.1" hosted-git-info@^2.1.4, hosted-git-info@^2.7.1: - version "2.8.8" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" - integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== + version "2.8.9" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" + integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== -hosted-git-info@^3.0.2, hosted-git-info@^3.0.6: - version "3.0.7" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-3.0.7.tgz#a30727385ea85acfcee94e0aad9e368c792e036c" - integrity sha512-fWqc0IcuXs+BmE9orLDyVykAG9GJtGLGuZAAqgcckPgv5xad4AcXGIv8galtQvlwutxSlaMcdw7BUtq2EIvqCQ== +hosted-git-info@^3.0.2: + version "3.0.8" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-3.0.8.tgz#6e35d4cc87af2c5f816e4cb9ce350ba87a3f370d" + integrity sha512-aXpmwoOhRBrw6X3j0h5RloK4x1OzsxMPyxqIHyNfSe2pypkVTZFpEiRoSipPEPlMrh0HW/XsjkJ5WgnCirpNUw== + dependencies: + lru-cache "^6.0.0" + +hosted-git-info@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-4.0.2.tgz#5e425507eede4fea846b7262f0838456c4209961" + integrity sha512-c9OGXbZ3guC/xOlCg1Ci/VgWlwsqDv1yMQL1CWqXDL0hDjXuNcq0zuR4xqPSuasI3kqFDhqSyTjREz5gzq0fXg== dependencies: lru-cache "^6.0.0" @@ -4002,15 +4066,10 @@ hsla-regex@^1.0.0: resolved "https://registry.yarnpkg.com/hsla-regex/-/hsla-regex-1.0.0.tgz#c1ce7a3168c8c6614033a4b5f7877f3b225f9c38" integrity sha1-wc56MWjIxmFAM6S194d/OyJfnDg= -html-comment-regex@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.2.tgz#97d4688aeb5c81886a364faa0cad1dda14d433a7" - integrity sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ== - html-entities@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.3.1.tgz#fb9a1a4b5b14c5daba82d3e34c6ae4fe701a0e44" - integrity sha512-rhE/4Z3hIhzHAUKbW8jVcCyuT5oJCXXqhN/6mXXVCpzTmvJnoH2HL/bt3EZ6p55jbFJBeAe1ZNpL5BugLujxNA== + version "1.4.0" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.4.0.tgz#cfbd1b01d2afaf9adca1b10ae7dffab98c71d2dc" + integrity sha512-8nxjcBcd8wovbeKx7h3wTji4e6+rhaVuPNpMqwWgnHh+N9ToqsCs6XztWRBPQ+UtzsoMAdKZtUENoVzU/EMtZA== http-cache-semantics@^3.8.1: version "3.8.1" @@ -4055,9 +4114,9 @@ http-errors@~1.7.2: toidentifier "1.0.0" http-parser-js@>=0.5.1: - version "0.5.2" - resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.2.tgz#da2e31d237b393aae72ace43882dd7e270a8ff77" - integrity sha512-opCO9ASqg5Wy2FNo7A0sxy71yGbbkJJXLdgMK04Tcypw9jr2MgWbyubb0+WdmDmGnFflO7fRbqbaihh/ENDlRQ== + version "0.5.3" + resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.3.tgz#01d2709c79d41698bb01d4decc5e9da4e4a033d9" + integrity sha512-t7hjvef/5HEK7RWTdUzVUhl8zkEu+LlaE0IYzdMuvbSDipxBRpOn4Uhw8ZyECEa808iVT8XCjzo6xmYt4CiLZg== http-proxy-agent@^2.1.0: version "2.1.0" @@ -4147,9 +4206,9 @@ iferr@^0.1.5: integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE= ignore-walk@^3.0.1: - version "3.0.3" - resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.3.tgz#017e2447184bfeade7c238e4aefdd1e8f95b1e37" - integrity sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw== + version "3.0.4" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.4.tgz#c9a09f69b7c7b479a5d74ac1a3c0d4236d2a6335" + integrity sha512-PY6Ii8o1jMRA1z4F2hRkH/xN59ox43DavKvD3oDpfurRlOJyAHpifIwpbdv1n4jt4ov0jSpw3kQ4GhJnpBL6WQ== dependencies: minimatch "^3.0.4" @@ -4236,10 +4295,10 @@ inherits@2.0.3: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= -ini@1.3.5: - version "1.3.5" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" - integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== +ini@1.3.6: + version "1.3.6" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.6.tgz#f1c46a2a93a253e7b3905115e74d527cd23061a1" + integrity sha512-IZUoxEjNjubzrmvzZU4lKP7OnYmX72XRl3sqkfJhBKweKi5rnGi5+IUdlj/H1M+Ip5JQ1WzaDMOBRY90Ajc5jg== inquirer@7.3.3: version "7.3.3" @@ -4314,10 +4373,12 @@ is-accessor-descriptor@^1.0.0: dependencies: kind-of "^6.0.0" -is-arguments@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.0.4.tgz#3faf966c7cba0ff437fb31f6250082fcf0448cf3" - integrity sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA== +is-arguments@^1.0.4, is-arguments@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.0.tgz#62353031dfbee07ceb34656a6bde59efecae8dd9" + integrity sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg== + dependencies: + call-bind "^1.0.0" is-arrayish@^0.2.1: version "0.2.1" @@ -4329,10 +4390,10 @@ is-arrayish@^0.3.1: resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== -is-bigint@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.0.tgz#73da8c33208d00f130e9b5e15d23eac9215601c4" - integrity sha512-t5mGUXC/xRheCK431ylNiSkGGpBp8bHENBcENTkDT6ppwPzEVxNGZRvgvmOEfbWkFhA7D2GEuE2mmQTr78sl2g== +is-bigint@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.2.tgz#ffb381442503235ad245ea89e45b3dbff040ee5a" + integrity sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA== is-binary-path@^1.0.0: version "1.0.1" @@ -4348,20 +4409,22 @@ is-binary-path@~2.1.0: dependencies: binary-extensions "^2.0.0" -is-boolean-object@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.0.1.tgz#10edc0900dd127697a92f6f9807c7617d68ac48e" - integrity sha512-TqZuVwa/sppcrhUCAYkGBk7w0yxfQQnxq28fjkO53tnK9FQXmdwz2JS5+GjsWQ6RByES1K40nI+yDic5c9/aAQ== +is-boolean-object@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.1.tgz#3c0878f035cb821228d350d2e1e36719716a3de8" + integrity sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng== + dependencies: + call-bind "^1.0.2" is-buffer@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== -is-callable@^1.1.4, is-callable@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.2.tgz#c7c6715cd22d4ddb48d3e19970223aceabb080d9" - integrity sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA== +is-callable@^1.1.4, is-callable@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.3.tgz#8b1e0500b73a1d76c70487636f368e519de8db8e" + integrity sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ== is-color-stop@^1.0.0: version "1.1.0" @@ -4375,10 +4438,10 @@ is-color-stop@^1.0.0: rgb-regex "^1.0.1" rgba-regex "^1.0.0" -is-core-module@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.0.0.tgz#58531b70aed1db7c0e8d4eb1a0a2d1ddd64bd12d" - integrity sha512-jq1AH6C8MuteOoBPwkxHafmByhL9j5q4OaPGdbuD+ZtQJVzH+i6E3BJDQcBA09k57i2Hh2yQbEG8yObZ0jdlWw== +is-core-module@^2.2.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.4.0.tgz#8e9fc8e15027b011418026e98f0e6f4d86305cc1" + integrity sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A== dependencies: has "^1.0.3" @@ -4397,9 +4460,9 @@ is-data-descriptor@^1.0.0: kind-of "^6.0.0" is-date-object@^1.0.1, is-date-object@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" - integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.4.tgz#550cfcc03afada05eea3dd30981c7b09551f73e5" + integrity sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A== is-descriptor@^0.1.0: version "0.1.6" @@ -4425,9 +4488,9 @@ is-directory@^0.3.1: integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= is-docker@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.1.1.tgz#4125a88e44e450d384e09047ede71adc2d144156" - integrity sha512-ZOoqiXfEwtGknTiuDEy8pN2CfE3TxMHprvNer1mXiqwkOT77Rw3YVrUQ52EqAOU3QAWDQ+bQdx7HJzrv7LS2Hw== + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== is-extendable@^0.1.0, is-extendable@^0.1.1: version "0.1.1" @@ -4475,20 +4538,20 @@ is-interactive@^1.0.0: resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== -is-map@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.1.tgz#520dafc4307bb8ebc33b813de5ce7c9400d644a1" - integrity sha512-T/S49scO8plUiAOA2DBTBG3JHpn1yiw0kRp6dgiZ0v2/6twi5eiB0rHtHFH9ZIrvlWc6+4O+m4zg5+Z833aXgw== +is-map@^2.0.1, is-map@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.2.tgz#00922db8c9bf73e81b7a335827bc2a43f2b91127" + integrity sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg== -is-negative-zero@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.0.tgz#9553b121b0fac28869da9ed459e20c7543788461" - integrity sha1-lVOxIbD6wohp2p7UWeIMdUN4hGE= +is-negative-zero@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24" + integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w== -is-number-object@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.4.tgz#36ac95e741cf18b283fc1ddf5e83da798e3ec197" - integrity sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw== +is-number-object@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.5.tgz#6edfaeed7950cff19afedce9fbfca9ee6dd289eb" + integrity sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw== is-number@^3.0.0: version "3.0.0" @@ -4538,54 +4601,49 @@ is-plain-object@^2.0.3, is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" -is-regex@^1.0.4, is-regex@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.1.tgz#c6f98aacc546f6cec5468a07b7b153ab564a57b9" - integrity sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg== +is-regex@^1.0.4, is-regex@^1.1.1, is-regex@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.3.tgz#d029f9aff6448b93ebbe3f33dac71511fdcbef9f" + integrity sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ== dependencies: - has-symbols "^1.0.1" + call-bind "^1.0.2" + has-symbols "^1.0.2" is-resolvable@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg== -is-set@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.1.tgz#d1604afdab1724986d30091575f54945da7e5f43" - integrity sha512-eJEzOtVyenDs1TMzSQ3kU3K+E0GUS9sno+F0OBT97xsgcJsF9nXMBtkT9/kut5JEpM7oL7X/0qxR17K3mcwIAA== +is-set@^2.0.1, is-set@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.2.tgz#90755fa4c2562dc1c5d4024760d6119b94ca18ec" + integrity sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g== is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= -is-string@^1.0.4, is-string@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6" - integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ== - -is-svg@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-3.0.0.tgz#9321dbd29c212e5ca99c4fa9794c714bcafa2f75" - integrity sha512-gi4iHK53LR2ujhLVVj+37Ykh9GLqYHX6JOVXbLAucaG/Cqw9xwdFOjDM2qeifLs1sF1npXXFvDu0r5HNgCMrzQ== - dependencies: - html-comment-regex "^1.1.0" +is-string@^1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.6.tgz#3fe5d5992fb0d93404f32584d4b0179a71b54a5f" + integrity sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w== -is-symbol@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" - integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ== +is-symbol@^1.0.2, is-symbol@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" + integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== dependencies: - has-symbols "^1.0.1" + has-symbols "^1.0.2" is-typed-array@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.3.tgz#a4ff5a5e672e1a55f99c7f54e59597af5c1df04d" - integrity sha512-BSYUBOK/HJibQ30wWkWold5txYwMUXQct9YHAQJr8fSwvZoiglcqB0pd7vEN23+Tsi9IUEjztdOSzl4qLVYGTQ== + version "1.1.5" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.5.tgz#f32e6e096455e329eb7b423862456aa213f0eb4e" + integrity sha512-S+GRDgJlR3PyEbsX/Fobd9cqpZBuvUS+8asRqYDMLCb2qMzt1oz5m5oxQCxOgUDxiWsOVNi4yaF+/uvdlHlYug== dependencies: - available-typed-arrays "^1.0.0" - es-abstract "^1.17.4" + available-typed-arrays "^1.0.2" + call-bind "^1.0.2" + es-abstract "^1.18.0-next.2" foreach "^2.0.5" has-symbols "^1.0.1" @@ -4594,6 +4652,11 @@ is-typedarray@~1.0.0: resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= +is-unicode-supported@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" + integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== + is-weakmap@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/is-weakmap/-/is-weakmap-2.0.1.tgz#5008b59bdc43b698201d18f62b37b2ca243e8cf2" @@ -4604,6 +4667,11 @@ is-weakset@^2.0.1: resolved "https://registry.yarnpkg.com/is-weakset/-/is-weakset-2.0.1.tgz#e9a0af88dbd751589f5e50d80f4c98b780884f83" integrity sha512-pi4vhbhVHGLxohUw7PhGsueT4vRGFoXhP7+RGN0jKIv9+8PWYCQTqtADngrxOm2g46hoH0+g8uZZBzMrvVGDmw== +is-what@^3.12.0: + version "3.14.1" + resolved "https://registry.yarnpkg.com/is-what/-/is-what-3.14.1.tgz#e1222f46ddda85dead0fd1c9df131760e77755c1" + integrity sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA== + is-windows@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" @@ -4678,18 +4746,18 @@ jest-worker@26.3.0: supports-color "^7.0.0" jest-worker@^26.3.0: - version "26.6.1" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.1.tgz#c2ae8cde6802cc14056043f997469ec170d9c32a" - integrity sha512-R5IE3qSGz+QynJx8y+ICEkdI2OJ3RJjRQVEyCcFAd3yVhQSEtquziPO29Mlzgn07LOVE8u8jhJ1FqcwegiXWOw== + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" + integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ== dependencies: "@types/node" "*" merge-stream "^2.0.0" supports-color "^7.0.0" jquery@^3.5.1: - version "3.5.1" - resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.5.1.tgz#d7b4d08e1bfdb86ad2f1a3d039ea17304717abb5" - integrity sha512-XwIBPqcMn57FxfT+Go5pzySnm4KWkT1Tv7gjrpT1srtf8Weynl6R273VJ5GjkRb51IzMp5nbaPjJXMWeju2MKg== + version "3.6.0" + resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.6.0.tgz#c72a09f15c1bdce142f49dbf1170bdf8adac2470" + integrity sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw== "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" @@ -4697,9 +4765,9 @@ jquery@^3.5.1: integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== js-yaml@^3.13.1: - version "3.14.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.0.tgz#a7a34170f26a21bb162424d8adacb4113a69e482" - integrity sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A== + version "3.14.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== dependencies: argparse "^1.0.7" esprima "^4.0.0" @@ -4757,9 +4825,9 @@ json5@^1.0.1: minimist "^1.2.0" json5@^2.1.2: - version "2.1.3" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43" - integrity sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA== + version "2.2.0" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3" + integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA== dependencies: minimist "^1.2.5" @@ -4847,10 +4915,11 @@ less-loader@6.2.0: schema-utils "^2.7.0" less@^3.11.3: - version "3.12.2" - resolved "https://registry.yarnpkg.com/less/-/less-3.12.2.tgz#157e6dd32a68869df8859314ad38e70211af3ab4" - integrity sha512-+1V2PCMFkL+OIj2/HrtrvZw0BC0sYLMICJfbQjuj/K8CEnlrFX6R5cKKgzzttsZDHyxQNL1jqMREjKN3ja/E3Q== + version "3.13.1" + resolved "https://registry.yarnpkg.com/less/-/less-3.13.1.tgz#0ebc91d2a0e9c0c6735b83d496b0ab0583077909" + integrity sha512-SwA1aQXGUvp+P5XdZslUOhhLnClSLIjWvJhmd+Vgib5BFIr9lMNlQwmwUNOjXThF/A0x+MCYYPeWEfeWiLRnTw== dependencies: + copy-anything "^2.0.1" tslib "^1.10.0" optionalDependencies: errno "^0.1.1" @@ -4938,32 +5007,28 @@ lodash.memoize@^4.1.2: resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= -lodash.sortby@^4.7.0: - version "4.7.0" - resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" - integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= - lodash.uniq@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= -lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19: - version "4.17.20" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" - integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== +lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.7.0: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== log-symbols@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.0.0.tgz#69b3cc46d20f448eccdb75ea1fa733d9e821c920" - integrity sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA== + version "4.1.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" + integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== dependencies: - chalk "^4.0.0" + chalk "^4.1.0" + is-unicode-supported "^0.1.0" loglevel@^1.6.8: - version "1.7.0" - resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.7.0.tgz#728166855a740d59d38db01cf46f042caa041bb0" - integrity sha512-i2sY04nal5jDcagM3FMfG++T69GEEM8CYuOfeOIvmXzOIcwE9a/CJPR0MFM97pYMj/u10lzz7/zd7+qwhrBTqQ== + version "1.7.1" + resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.7.1.tgz#005fde2f5e6e47068f935ff28573e125ef72f197" + integrity sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw== loose-envify@^1.0.0: version "1.4.0" @@ -5051,10 +5116,10 @@ md5.js@^1.3.4: inherits "^2.0.1" safe-buffer "^5.1.2" -mdn-data@2.0.12: - version "2.0.12" - resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.12.tgz#bbb658d08b38f574bbb88f7b83703defdcc46844" - integrity sha512-ULbAlgzVb8IqZ0Hsxm6hHSlQl3Jckst2YEQS7fODu9ilNWy2LvcoSY7TRFIktABP2mdppBioc66va90T+NUs8Q== +mdn-data@2.0.14: + version "2.0.14" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50" + integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow== mdn-data@2.0.4: version "2.0.4" @@ -5129,12 +5194,12 @@ micromatch@^3.1.10, micromatch@^3.1.4: to-regex "^3.0.2" micromatch@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259" - integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q== + version "4.0.4" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" + integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== dependencies: braces "^3.0.1" - picomatch "^2.0.5" + picomatch "^2.2.3" miller-rabin@^4.0.0: version "4.0.1" @@ -5144,22 +5209,17 @@ miller-rabin@^4.0.0: bn.js "^4.0.0" brorand "^1.0.1" -mime-db@1.44.0: - version "1.44.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" - integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== - -"mime-db@>= 1.43.0 < 2": - version "1.45.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.45.0.tgz#cceeda21ccd7c3a745eba2decd55d4b73e7879ea" - integrity sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w== +mime-db@1.47.0, "mime-db@>= 1.43.0 < 2": + version "1.47.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.47.0.tgz#8cb313e59965d3c05cfbf898915a267af46a335c" + integrity sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw== mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24: - version "2.1.27" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" - integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w== + version "2.1.30" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.30.tgz#6e7be8b4c479825f85ed6326695db73f9305d62d" + integrity sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg== dependencies: - mime-db "1.44.0" + mime-db "1.47.0" mime@1.6.0, mime@^1.4.1: version "1.6.0" @@ -5167,9 +5227,9 @@ mime@1.6.0, mime@^1.4.1: integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== mime@^2.4.4: - version "2.4.6" - resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.6.tgz#e5b407c90db442f2beb5b162373d07b69affa4d1" - integrity sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA== + version "2.5.2" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.5.2.tgz#6e3dc6cc2b9510643830e5f19d5cb753da5eeabe" + integrity sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg== mimic-fn@^2.1.0: version "2.1.0" @@ -5322,11 +5382,16 @@ ms@2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== -ms@2.1.2, ms@^2.0.0, ms@^2.1.1: +ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +ms@^2.0.0, ms@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + multicast-dns-service-types@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901" @@ -5443,10 +5508,10 @@ node-libs-browser@^2.2.1: util "^0.11.0" vm-browserify "^1.0.1" -node-releases@^1.1.61: - version "1.1.64" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.64.tgz#71b4ae988e9b1dd7c1ffce58dd9e561752dfebc5" - integrity sha512-Iec8O9166/x2HRMJyLLLWkd0sFFLrFNy+Xf+JQfSQsdBJzPcHpNl3JQ9gD4j+aJxmCa25jNsIbM4bmACtSbkSg== +node-releases@^1.1.71: + version "1.1.71" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.71.tgz#cb1334b179896b1c89ecfdd4b725fb7bbdfc7dbb" + integrity sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg== normalize-package-data@^2.0.0, normalize-package-data@^2.4.0: version "2.5.0" @@ -5491,9 +5556,9 @@ normalize-url@^3.0.0: integrity sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg== npm-bundled@^1.0.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.1.1.tgz#1edd570865a94cdb1bc8220775e29466c9fb234b" - integrity sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA== + version "1.1.2" + resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.1.2.tgz#944c78789bd739035b70baa2ca5cc32b8d860bc1" + integrity sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ== dependencies: npm-normalize-package-bin "^1.0.1" @@ -5529,12 +5594,12 @@ npm-package-arg@^6.0.0, npm-package-arg@^6.1.0: validate-npm-package-name "^3.0.0" npm-package-arg@^8.0.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-8.1.0.tgz#b5f6319418c3246a1c38e1a8fbaa06231bc5308f" - integrity sha512-/ep6QDxBkm9HvOhOg0heitSd7JHA1U7y1qhhlRlteYYAi9Pdb/ZV7FW5aHpkrpM8+P+4p/jjR8zCyKPBMBjSig== + version "8.1.2" + resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-8.1.2.tgz#b868016ae7de5619e729993fbd8d11dc3c52ab62" + integrity sha512-6Eem455JsSMJY6Kpd3EyWE+n5hC+g9bSyHr9K9U2zqZb7+02+hObQ2c0+8iDk/mNF+8r1MhY44WypKJAkySIYA== dependencies: - hosted-git-info "^3.0.6" - semver "^7.0.0" + hosted-git-info "^4.0.1" + semver "^7.3.4" validate-npm-package-name "^3.0.0" npm-packlist@^1.1.12: @@ -5615,18 +5680,18 @@ object-copy@^0.1.0: define-property "^0.2.5" kind-of "^3.0.3" -object-inspect@^1.8.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.8.0.tgz#df807e5ecf53a609cc6bfe93eac3cc7be5b3a9d0" - integrity sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA== +object-inspect@^1.9.0: + version "1.10.3" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.10.3.tgz#c2aa7d2d09f50c99375704f7a0adf24c5782d369" + integrity sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw== -object-is@^1.0.1, object-is@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.3.tgz#2e3b9e65560137455ee3bd62aec4d90a2ea1cc81" - integrity sha512-teyqLvFWzLkq5B9ki8FVWA902UER2qkxmdA4nLf+wjOLAWgxzCWZNCxpDq9MvE8MmhWNr+I8w3BN49Vx36Y6Xg== +object-is@^1.0.1, object-is@^1.1.4: + version "1.1.5" + resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" + integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== dependencies: + call-bind "^1.0.2" define-properties "^1.1.3" - es-abstract "^1.18.0-next.1" object-keys@^1.0.12, object-keys@^1.1.1: version "1.1.1" @@ -5640,23 +5705,24 @@ object-visit@^1.0.0: dependencies: isobject "^3.0.0" -object.assign@^4.1.0, object.assign@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.1.tgz#303867a666cdd41936ecdedfb1f8f3e32a478cdd" - integrity sha512-VT/cxmx5yaoHSOTSyrCygIDFco+RsibY2NM0a4RdEeY/4KgqezwFtK1yr3U67xYhqJSlASm2pKhLVzPj2lr4bA== +object.assign@^4.1.0, object.assign@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" + integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== dependencies: + call-bind "^1.0.0" define-properties "^1.1.3" - es-abstract "^1.18.0-next.0" has-symbols "^1.0.1" object-keys "^1.1.1" object.getownpropertydescriptors@^2.0.3, object.getownpropertydescriptors@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz#369bf1f9592d8ab89d712dced5cb81c7c5352649" - integrity sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg== + version "2.1.2" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.2.tgz#1bd63aeacf0d5d2d2f31b5e393b03a7c601a23f7" + integrity sha512-WtxeKSzfBjlzL+F9b7M7hewDzMwy+C8NRssHd1YrNlzHzIDrXcXiNOMrezdAEM4UXixgV+vvnyBeN7Rygl2ttQ== dependencies: + call-bind "^1.0.2" define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" + es-abstract "^1.18.0-next.2" object.pick@^1.3.0: version "1.3.0" @@ -5666,13 +5732,13 @@ object.pick@^1.3.0: isobject "^3.0.1" object.values@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.1.tgz#68a99ecde356b7e9295a3c5e0ce31dc8c953de5e" - integrity sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA== + version "1.1.3" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.3.tgz#eaa8b1e17589f02f698db093f7c62ee1699742ee" + integrity sha512-nkF6PfDB9alkOUxpf1HNm/QlkeW3SReqL5WXeBLpEJJnlPSvRaDQpW3gQTksTN3fgJX4hL42RzKyOin6ff3tyw== dependencies: + call-bind "^1.0.2" define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - function-bind "^1.1.1" + es-abstract "^1.18.0-next.2" has "^1.0.3" obuf@^1.0.0, obuf@^1.1.2: @@ -5778,11 +5844,11 @@ p-limit@^2.0.0, p-limit@^2.2.0: p-try "^2.0.0" p-limit@^3.0.1, p-limit@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.0.2.tgz#1664e010af3cadc681baafd3e2a437be7b0fb5fe" - integrity sha512-iwqZSOoWIW+Ew4kAGUlN16J4M7OB3ysMLSZtnhmqx7njIHFPlxWBX8xo3lVTyFVq6mI/lL9qt2IsN1sHwaxJkg== + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== dependencies: - p-try "^2.0.0" + yocto-queue "^0.1.0" p-locate@^3.0.0: version "3.0.0" @@ -5964,9 +6030,9 @@ path-type@^4.0.0: integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== pbkdf2@^3.0.3: - version "3.1.1" - resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.1.tgz#cb8724b0fada984596856d1a6ebafd3584654b94" - integrity sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg== + version "3.1.2" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" + integrity sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA== dependencies: create-hash "^1.1.2" create-hmac "^1.1.4" @@ -5979,10 +6045,10 @@ performance-now@^2.1.0: resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= -picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.2.1: - version "2.2.2" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" - integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.3.tgz#465547f359ccc206d3c48e46a1bcb89bf7ee619d" + integrity sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg== pify@^2.0.0, pify@^2.3.0: version "2.3.0" @@ -6345,21 +6411,18 @@ postcss-selector-parser@^3.0.0: uniq "^1.0.1" postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.2: - version "6.0.4" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.4.tgz#56075a1380a04604c38b063ea7767a129af5c2b3" - integrity sha512-gjMeXBempyInaBqpp8gODmwZ52WaYsVOsfr4L4lDQ7n3ncD6mEyySiDtgzCT+NYC0mmeOLvtsF8iaEf0YT6dBw== + version "6.0.5" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.5.tgz#042d74e137db83e6f294712096cb413f5aa612c4" + integrity sha512-aFYPoYmXbZ1V6HZaSvat08M97A8HqO6Pjz+PiNpw/DhuRrC72XWAdp3hL6wusDCN31sSmcZyMGa2hZEuX+Xfhg== dependencies: cssesc "^3.0.0" - indexes-of "^1.0.1" - uniq "^1.0.1" util-deprecate "^1.0.2" -postcss-svgo@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-4.0.2.tgz#17b997bc711b333bab143aaed3b8d3d6e3d38258" - integrity sha512-C6wyjo3VwFm0QgBy+Fu7gCYOkCmgmClghO+pjcxvrcBKtiKt0uCF+hvbMO1fyv5BMImRK90SMb+dwUnfbGd+jw== +postcss-svgo@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-4.0.3.tgz#343a2cdbac9505d416243d496f724f38894c941e" + integrity sha512-NoRbrcMWTtUghzuKSoIm6XV+sJdvZ7GZSc3wdBN0W19FTtp2ko8NqLsgoh/m9CzNhU3KLPvQmjIwtaNFkaFTvw== dependencies: - is-svg "^3.0.0" postcss "^7.0.0" postcss-value-parser "^3.0.0" svgo "^1.0.0" @@ -6560,6 +6623,11 @@ querystringify@^2.1.1: resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ== +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" @@ -6685,9 +6753,9 @@ regenerate-unicode-properties@^8.2.0: regenerate "^1.4.0" regenerate@^1.4.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.1.tgz#cad92ad8e6b591773485fbe05a485caf4f457e6f" - integrity sha512-j2+C8+NtXQgEKWk49MMP5P/u2GhnahTtVkRIHr5R5lVRlbKvmQ+oS+A5aLKWp2ma5VkT8sh6v+v4hbH0YHR66A== + version "1.4.2" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" + integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== regenerator-runtime@0.13.7, regenerator-runtime@^0.13.4: version "0.13.7" @@ -6715,12 +6783,12 @@ regex-parser@^2.2.11: integrity sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q== regexp.prototype.flags@^1.2.0, regexp.prototype.flags@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz#7aba89b3c13a64509dabcf3ca8d9fbb9bdf5cb75" - integrity sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ== + version "1.3.1" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz#7ef352ae8d159e758c0eadca6f8fcb4eef07be26" + integrity sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA== dependencies: + call-bind "^1.0.2" define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" regexpu-core@^4.7.1: version "4.7.1" @@ -6740,9 +6808,9 @@ regjsgen@^0.5.1: integrity sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A== regjsparser@^0.6.4: - version "0.6.4" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.4.tgz#a769f8684308401a66e9b529d2436ff4d0666272" - integrity sha512-64O87/dPDgfk8/RQqC4gkZoGyyWFIEUTTh80CU6CWuK5vkCGyekIx+oKcEIYtP/RAxSQltCZHCNu/mdd7fqlJw== + version "0.6.9" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.9.tgz#b489eef7c9a2ce43727627011429cf833a7183e6" + integrity sha512-ZqbNRz1SNjLAiYuwY0zoXW8Ne675IX5q+YHioAGbCw4X96Mjl2+dcX9B2ciaeyYjViDAfvIjFpQjJgLttTEERQ== dependencies: jsesc "~0.5.0" @@ -6752,9 +6820,9 @@ remove-trailing-separator@^1.0.1: integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= repeat-element@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" - integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== + version "1.1.4" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.4.tgz#be681520847ab58c7568ac75fbfad28ed42d39e9" + integrity sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ== repeat-string@^1.6.1: version "1.6.1" @@ -6836,11 +6904,11 @@ resolve-url@^0.2.1: integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= resolve@^1.1.7, resolve@^1.10.0, resolve@^1.3.2, resolve@^1.8.1: - version "1.18.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.18.1.tgz#018fcb2c5b207d2a6424aee361c5a266da8f4130" - integrity sha512-lDfCPaMKfOJXjy0dPayzPdF1phampNWr3qFCjAu+rw/qbQmr5jWH5xN2hwh9QKfw9E5v4hwV7A+jrCmL8yjjqA== + version "1.20.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" + integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== dependencies: - is-core-module "^2.0.0" + is-core-module "^2.2.0" path-parse "^1.0.6" restore-cursor@^3.1.0: @@ -6929,9 +6997,11 @@ run-async@^2.4.0: integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== run-parallel@^1.1.9: - version "1.1.10" - resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.1.10.tgz#60a51b2ae836636c81377df16cb107351bcd13ef" - integrity sha512-zb/1OuZ6flOlH6tQyMPUrE3x3Ulxjlo9WIVXR4yVYi4H9UXQaeIsPbLn2R3O3vQCnDKkAl2qHiuocKKX4Tz/Sw== + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" run-queue@^1.0.0, run-queue@^1.0.3: version "1.0.3" @@ -6948,9 +7018,9 @@ rxjs@6.6.2: tslib "^1.9.0" rxjs@^6.5.2, rxjs@^6.6.0: - version "6.6.3" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.3.tgz#8ca84635c4daa900c0d3967a6ee7ac60271ee552" - integrity sha512-trsQc+xYYXZ3urjOiJOuCOa5N3jAZ3eiSpQB5hIT8zGlL2QfnHLJ2r7GMkBGuIausdJN1OneaI6gQlsqNHHmZQ== + version "6.6.7" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9" + integrity sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ== dependencies: tslib "^1.9.0" @@ -7023,9 +7093,9 @@ select-hose@^2.0.0: integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo= selfsigned@^1.10.7: - version "1.10.8" - resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.8.tgz#0d17208b7d12c33f8eac85c41835f27fc3d81a30" - integrity sha512-2P4PtieJeEwVgTU9QEcwIRDQ/mXJLX8/+I3ur+Pg16nS8oNbrGxEso9NyYWy8NAmXiNl4dlAp5MwoNeCWzON4w== + version "1.10.11" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.11.tgz#24929cd906fe0f44b6d01fb23999a739537acbe9" + integrity sha512-aVmbPOfViZqOZPgRBT0+3u4yZFHpmnIghLMlAcb5/xhp5ZtB/RVnKhz5vl2M32CLXAqR4kha9zfhNg0Lf/sxKA== dependencies: node-forge "^0.10.0" @@ -7053,7 +7123,7 @@ semver@7.0.0: resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== -semver@7.3.2, semver@^7.0.0, semver@^7.1.1, semver@^7.3.2: +semver@7.3.2: version "7.3.2" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== @@ -7063,6 +7133,13 @@ semver@^6.0.0, semver@^6.3.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== +semver@^7.0.0, semver@^7.1.1, semver@^7.3.2, semver@^7.3.4: + version "7.3.5" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" + integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== + dependencies: + lru-cache "^6.0.0" + send@0.17.1: version "0.17.1" resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" @@ -7163,12 +7240,13 @@ shebang-regex@^1.0.0: integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= side-channel@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.3.tgz#cdc46b057550bbab63706210838df5d4c19519c3" - integrity sha512-A6+ByhlLkksFoUepsGxfj5x1gTSrs+OydsRptUxeNCabQpCFUvcwIczgOigI8vhY/OJCnPnyE9rGiwgvr9cS1g== + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== dependencies: - es-abstract "^1.18.0-next.0" - object-inspect "^1.8.0" + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.3" @@ -7302,9 +7380,9 @@ source-map-support@0.5.19, source-map-support@^0.5.5, source-map-support@~0.5.12 source-map "^0.6.0" source-map-url@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" - integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= + version "0.4.1" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56" + integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw== source-map@0.6.1, source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: version "0.6.1" @@ -7348,9 +7426,9 @@ spdx-expression-parse@^3.0.0: spdx-license-ids "^3.0.0" spdx-license-ids@^3.0.0: - version "3.0.6" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.6.tgz#c80757383c28abf7296744998cbc106ae8b854ce" - integrity sha512-+orQK83kyMva3WyPf59k1+Y525csj5JejicWut55zeTWANuN17qSiSLUXWtzHeNWORSvT7GLDJ/E/XiIWoXBTw== + version "3.0.7" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz#e9c18a410e5ed7e12442a549fbd8afa767038d65" + integrity sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ== spdy-transport@^3.0.0: version "3.0.0" @@ -7421,10 +7499,10 @@ ssri@^6.0.0, ssri@^6.0.1: dependencies: figgy-pudding "^3.5.1" -ssri@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.0.tgz#79ca74e21f8ceaeddfcb4b90143c458b8d988808" - integrity sha512-aq/pz989nxVYwn16Tsbj1TqFpD5LLrQxHf5zaHuieFV+R0Bbr4y8qUsOA45hXT/N4/9UNXTarBjnjVmjSOVaAA== +ssri@^8.0.0, ssri@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.1.tgz#638e4e439e2ffbd2cd289776d5ca457c4f51a2af" + integrity sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ== dependencies: minipass "^3.1.1" @@ -7493,29 +7571,29 @@ string-width@^3.0.0, string-width@^3.1.0: strip-ansi "^5.1.0" string-width@^4.1.0, string-width@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5" - integrity sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg== + version "4.2.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5" + integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA== dependencies: emoji-regex "^8.0.0" is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.0" -string.prototype.trimend@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.2.tgz#6ddd9a8796bc714b489a3ae22246a208f37bfa46" - integrity sha512-8oAG/hi14Z4nOVP0z6mdiVZ/wqjDtWSLygMigTzAb+7aPEDTleeFf+WrF+alzecxIRkckkJVn+dTlwzJXORATw== +string.prototype.trimend@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80" + integrity sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A== dependencies: + call-bind "^1.0.2" define-properties "^1.1.3" - es-abstract "^1.18.0-next.1" -string.prototype.trimstart@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.2.tgz#22d45da81015309cd0cdd79787e8919fc5c613e7" - integrity sha512-7F6CdBTl5zyu30BJFdzSTlSlLPwODC23Od+iLoVH8X6+3fvDPPuBVVj9iaB1GOsSTSIgVfsfm27R2FGrAPznWg== +string.prototype.trimstart@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed" + integrity sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw== dependencies: + call-bind "^1.0.2" define-properties "^1.1.3" - es-abstract "^1.18.0-next.1" string_decoder@^1.0.0, string_decoder@^1.1.1: version "1.3.0" @@ -7666,9 +7744,9 @@ tar@^4.4.10: yallist "^3.0.3" tar@^6.0.2: - version "6.0.5" - resolved "https://registry.yarnpkg.com/tar/-/tar-6.0.5.tgz#bde815086e10b39f1dcd298e89d596e1535e200f" - integrity sha512-0b4HOimQHj9nXNEAA7zWwMM91Zhhba3pspja6sQbgTpynOJf+bkjBnfybNYzbpLbnwXnbyB4LOREvlyXLkCHSg== + version "6.1.0" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.0.tgz#d1724e9bcc04b977b18d5c573b333a2207229a83" + integrity sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA== dependencies: chownr "^2.0.0" fs-minipass "^2.0.0" @@ -7726,9 +7804,9 @@ terser@^4.1.2: source-map-support "~0.5.12" terser@^5.0.0: - version "5.3.8" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.3.8.tgz#991ae8ba21a3d990579b54aa9af11586197a75dd" - integrity sha512-zVotuHoIfnYjtlurOouTazciEfL7V38QMAOhGqpXDEg6yT13cF4+fEP9b0rrCEQTn+tT46uxgFsTZzhygk+CzQ== + version "5.7.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.7.0.tgz#a761eeec206bc87b605ab13029876ead938ae693" + integrity sha512-HP5/9hp2UaZt5fYkuhNBR8YyRcT8juw8+uFbAme53iN9hblvKnLUTKkmwJG6ocWpIKf8UK4DoeWG4ty0J6S6/g== dependencies: commander "^2.20.0" source-map "~0.7.2" @@ -7892,9 +7970,9 @@ tslib@^1.10.0, tslib@^1.13.0, tslib@^1.8.1, tslib@^1.9.0: integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== tslib@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.0.3.tgz#8e0741ac45fc0c226e58a17bfc3e64b9bc6ca61c" - integrity sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ== + version "2.2.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.2.0.tgz#fb2c475977e35e241311ede2693cee1ec6698f5c" + integrity sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w== tslint@~6.1.0: version "6.1.3" @@ -7939,10 +8017,10 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0: resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= -type-fest@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.11.0.tgz#97abf0872310fed88a5c466b25681576145e33f1" - integrity sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ== +type-fest@^0.21.3: + version "0.21.3" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" + integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== type-is@~1.6.17, type-is@~1.6.18: version "1.6.18" @@ -7958,9 +8036,9 @@ type@^1.0.1: integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== type@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/type/-/type-2.1.0.tgz#9bdc22c648cf8cf86dd23d32336a41cfb6475e3f" - integrity sha512-G9absDWvhAWCV2gmF1zKud3OyC61nZDwWvBL2DApaVFogI07CprggiQAOOjvp2NRjYWFzPyu7vwtDrQFq8jeSA== + version "2.5.0" + resolved "https://registry.yarnpkg.com/type/-/type-2.5.0.tgz#0a2e78c2e77907b252abe5f298c1b01c63f0db3d" + integrity sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw== typedarray@^0.0.6: version "0.0.6" @@ -7977,6 +8055,16 @@ typescript@4.0.5: resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.0.5.tgz#ae9dddfd1069f1cb5beb3ef3b2170dd7c1332389" integrity sha512-ywmr/VrTVCmNTJ6iV2LwIrfG1P+lv6luD8sUJs+2eI9NLGigaN+nUQc13iHqisq7bra9lnmUSYqbJvegraBOPQ== +unbox-primitive@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" + integrity sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw== + dependencies: + function-bind "^1.1.1" + has-bigints "^1.0.1" + has-symbols "^1.0.2" + which-boxed-primitive "^1.0.2" + unicode-canonical-property-names-ecmascript@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" @@ -8072,9 +8160,9 @@ upath@^1.1.1: integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== uri-js@^4.2.2: - version "4.4.0" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.0.tgz#aa714261de793e8a82347a7bcc9ce74e86f28602" - integrity sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g== + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== dependencies: punycode "^2.1.0" @@ -8084,9 +8172,9 @@ urix@^0.1.0: integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= url-parse@^1.4.3: - version "1.4.7" - resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.4.7.tgz#a8a83535e8c00a316e403a5db4ac1b9b853ae278" - integrity sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg== + version "1.5.1" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.1.tgz#d5fa9890af8a5e1f274a2c98376510f6425f6e3b" + integrity sha512-HOfCOUJt7iSYzEx/UqgtwKRMC6EU91NFhsCHMv9oM03VJcVo2Qrp8T8kI9D7amFf1cu+/3CEhgb3rF9zL7k85Q== dependencies: querystringify "^2.1.1" requires-port "^1.0.0" @@ -8210,23 +8298,23 @@ vm-browserify@^1.0.1: resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== -watchpack-chokidar2@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.0.tgz#9948a1866cbbd6cb824dea13a7ed691f6c8ddff0" - integrity sha512-9TyfOyN/zLUbA288wZ8IsMZ+6cbzvsNyEzSBp6e/zkifi6xxbl8SmQ/CxQq32k8NNqrdVEVUVSEf56L4rQ/ZxA== +watchpack-chokidar2@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz#38500072ee6ece66f3769936950ea1771be1c957" + integrity sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww== dependencies: chokidar "^2.1.8" watchpack@^1.7.4: - version "1.7.4" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.7.4.tgz#6e9da53b3c80bb2d6508188f5b200410866cd30b" - integrity sha512-aWAgTW4MoSJzZPAicljkO1hsi1oKj/RRq/OJQh2PKI2UKL04c2Bs+MBOB+BBABHTXJpf9mCwHN7ANCvYsvY2sg== + version "1.7.5" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.7.5.tgz#1267e6c55e0b9b5be44c2023aed5437a2c26c453" + integrity sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ== dependencies: graceful-fs "^4.1.2" neo-async "^2.5.0" optionalDependencies: chokidar "^3.4.1" - watchpack-chokidar2 "^2.0.0" + watchpack-chokidar2 "^2.0.1" wbuf@^1.1.0, wbuf@^1.7.3: version "1.7.3" @@ -8247,7 +8335,7 @@ webidl-conversions@^6.1.0: resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514" integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w== -webpack-dev-middleware@3.7.2, webpack-dev-middleware@^3.7.2: +webpack-dev-middleware@3.7.2: version "3.7.2" resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.7.2.tgz#0019c3db716e3fa5cecbf64f2ab88a74bab331f3" integrity sha512-1xC42LxbYoqLNAhV6YzTYacicgMZQTqRd27Sim9wn5hJrX3I5nxYy1SxSd4+gjUFsz1dQFj+yEe6zEVmSkeJjw== @@ -8258,6 +8346,17 @@ webpack-dev-middleware@3.7.2, webpack-dev-middleware@^3.7.2: range-parser "^1.2.1" webpack-log "^2.0.0" +webpack-dev-middleware@^3.7.2: + version "3.7.3" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.7.3.tgz#0639372b143262e2b84ab95d3b91a7597061c2c5" + integrity sha512-djelc/zGiz9nZj/U7PTBi2ViorGJXEWo/3ltkPbDyxCXhhEXkW0ce99falaok4TPj+AsxLiXJR0EBOb0zh9fKQ== + dependencies: + memory-fs "^0.4.1" + mime "^2.4.4" + mkdirp "^0.5.1" + range-parser "^1.2.1" + webpack-log "^2.0.0" + webpack-dev-server@3.11.0: version "3.11.0" resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.11.0.tgz#8f154a3bce1bcfd1cc618ef4e703278855e7ff8c" @@ -8383,11 +8482,11 @@ whatwg-mimetype@^2.3.0: integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== whatwg-url@^8.0.0: - version "8.4.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.4.0.tgz#50fb9615b05469591d2b2bd6dfaed2942ed72837" - integrity sha512-vwTUFf6V4zhcPkWp/4CQPr1TW9Ml6SF4lVyaIMBdJw5i6qUUJ1QWM4Z6YYVkfka0OUIzVo/0aNtGVGk256IKWw== + version "8.5.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.5.0.tgz#7752b8464fc0903fec89aa9846fc9efe07351fd3" + integrity sha512-fy+R77xWv0AiqfLl4nuGUlQ3/6b5uNfQ4WAbGQVMYshCTCCPK9psC1nWh3XHuxGVCtlcDDQPQW1csmmIQo+fwg== dependencies: - lodash.sortby "^4.7.0" + lodash "^4.7.0" tr46 "^2.0.2" webidl-conversions "^6.1.0" @@ -8396,16 +8495,16 @@ when@~3.6.x: resolved "https://registry.yarnpkg.com/when/-/when-3.6.4.tgz#473b517ec159e2b85005497a13983f095412e34e" integrity sha1-RztRfsFZ4rhQBUl6E5g/CVQS404= -which-boxed-primitive@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.1.tgz#cbe8f838ebe91ba2471bb69e9edbda67ab5a5ec1" - integrity sha512-7BT4TwISdDGBgaemWU0N0OU7FeAEJ9Oo2P1PHRm/FCWoEi2VLWC9b6xvxAA3C/NMpxg3HXVgi0sMmGbNUbNepQ== +which-boxed-primitive@^1.0.1, which-boxed-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" + integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== dependencies: - is-bigint "^1.0.0" - is-boolean-object "^1.0.0" - is-number-object "^1.0.3" - is-string "^1.0.4" - is-symbol "^1.0.2" + is-bigint "^1.0.1" + is-boolean-object "^1.1.0" + is-number-object "^1.0.4" + is-string "^1.0.5" + is-symbol "^1.0.3" which-collection@^1.0.1: version "1.0.1" @@ -8423,12 +8522,13 @@ which-module@^2.0.0: integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= which-typed-array@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.2.tgz#e5f98e56bda93e3dac196b01d47c1156679c00b2" - integrity sha512-KT6okrd1tE6JdZAy3o2VhMoYPh3+J6EMZLyrxBQsZflI1QCZIxMrIYLkosd8Twf+YfknVIHmYQPgJt238p8dnQ== + version "1.1.4" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.4.tgz#8fcb7d3ee5adf2d771066fba7cf37e32fe8711ff" + integrity sha512-49E0SpUe90cjpoc7BOJwyPHRqSAd12c10Qm2amdEZrJPCY2NDxaW01zHITrem+rnETY3dwrbH3UUrUwagfCYDA== dependencies: available-typed-arrays "^1.0.2" - es-abstract "^1.17.5" + call-bind "^1.0.0" + es-abstract "^1.18.0-next.1" foreach "^2.0.5" function-bind "^1.1.1" has-symbols "^1.0.1" @@ -8464,10 +8564,10 @@ wrap-ansi@^5.1.0: string-width "^3.0.0" strip-ansi "^5.0.0" -wrap-ansi@^6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" - integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== dependencies: ansi-styles "^4.0.0" string-width "^4.1.0" @@ -8486,9 +8586,9 @@ ws@^6.2.1: async-limiter "~1.0.0" xhr2@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/xhr2/-/xhr2-0.2.0.tgz#eddeff782f3b7551061b8d75645085269396e521" - integrity sha512-BDtiD0i2iKPK/S8OAZfpk6tyzEDnKKSjxWHcMBVmh+LuqJ8A32qXTyOx+TVOg2dKvq6zGBq2sgKPkEeRs1qTRA== + version "0.2.1" + resolved "https://registry.yarnpkg.com/xhr2/-/xhr2-0.2.1.tgz#4e73adc4f9cfec9cbd2157f73efdce3a5f108a93" + integrity sha512-sID0rrVCqkVNUn8t6xuv9+6FViXjUVXq8H5rWOH2rz9fDNQEd4g0EA2XlcEdJXRz5BMEn4O1pJFdT+z4YHhoWw== xtend@^4.0.0, xtend@~4.0.1: version "4.0.2" @@ -8496,9 +8596,14 @@ xtend@^4.0.0, xtend@~4.0.1: integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== y18n@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.1.tgz#8db2b83c31c5d75099bb890b23f3094891e247d4" - integrity sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ== + version "4.0.3" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" + integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ== + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== yallist@^3.0.0, yallist@^3.0.2, yallist@^3.0.3: version "3.1.1" @@ -8518,30 +8623,10 @@ yargs-parser@^13.1.2: camelcase "^5.0.0" decamelize "^1.2.0" -yargs-parser@^18.1.0: - version "18.1.3" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0" - integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ== - dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" - -yargs@15.3.0: - version "15.3.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.3.0.tgz#403af6edc75b3ae04bf66c94202228ba119f0976" - integrity sha512-g/QCnmjgOl1YJjGsnUg2SatC7NUYEiLXJqxNOQU9qSpjzGtGXda9b+OKccr1kLTy8BN9yqEyqfq5lxlwdc13TA== - dependencies: - cliui "^6.0.0" - decamelize "^1.2.0" - find-up "^4.1.0" - get-caller-file "^2.0.1" - require-directory "^2.1.1" - require-main-filename "^2.0.0" - set-blocking "^2.0.0" - string-width "^4.2.0" - which-module "^2.0.0" - y18n "^4.0.0" - yargs-parser "^18.1.0" +yargs-parser@^20.2.2: + version "20.2.7" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.7.tgz#61df85c113edfb5a7a4e36eb8aa60ef423cbc90a" + integrity sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw== yargs@^13.3.2: version "13.3.2" @@ -8559,6 +8644,24 @@ yargs@^13.3.2: y18n "^4.0.0" yargs-parser "^13.1.2" +yargs@^16.1.1: + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== + zone.js@~0.10.2: version "0.10.3" resolved "https://registry.yarnpkg.com/zone.js/-/zone.js-0.10.3.tgz#3e5e4da03c607c9dcd92e37dd35687a14a140c16" From 5114191940efd2ff5ab300ef040c203abe9db925 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Tue, 11 May 2021 11:29:46 +0200 Subject: [PATCH 34/54] Updated to Angular 11, eslint --- ids-webconsole/build.gradle.kts | 4 +- .../src/main/angular/.eslintrc.json | 104 + ids-webconsole/src/main/angular/angular.json | 14 +- ids-webconsole/src/main/angular/package.json | 49 +- .../src/app/_interceptors/jwt.interceptor.ts | 15 +- .../src/main/angular/src/app/app.component.ts | 3 +- .../src/main/angular/src/app/app.routing.ts | 4 +- .../app/application-http-client.service.ts | 12 +- .../src/app/apps/app-card.component.ts | 2 +- .../apps/app-search-result-card.component.ts | 2 +- .../src/app/apps/apps-search.component.ts | 10 +- .../angular/src/app/apps/apps.component.ts | 2 +- .../src/main/angular/src/app/apps/cml.ts | 2 +- .../src/app/confirm/confirm.component.ts | 64 +- .../connection-configuration.component.ts | 2 +- .../connection-configuration.service.ts | 2 +- .../dataflowpolicies.component.ts | 2 +- .../dataflowpoliciesnew.component.html | 8 +- .../dataflowpoliciesnew.component.ts | 10 +- .../app/dataflowpolicies/policy.interface.ts | 4 +- .../app/dataflowpolicies/policy.service.ts | 4 +- .../keycerts/certificate-card.component.ts | 4 +- .../src/app/keycerts/identitynew.component.ts | 4 +- .../src/app/keycerts/keycerts.component.ts | 11 +- .../home-layout/home-layout.component.ts | 2 +- .../login-layout/login-layout.component.ts | 2 +- .../angular/src/app/login/login.component.ts | 2 +- .../src/app/mdl-upgrade-element-directive.ts | 2 +- .../angular/src/app/prettify-json.pipe.ts | 2 +- .../src/main/angular/src/app/result.ts | 2 - .../angular/src/app/routes/route.service.ts | 4 +- .../routeeditor/routeeditor.component.ts | 10 +- .../src/app/routes/routes.component.ts | 2 +- .../app/routes/zoom-viz/zoom-viz.component.ts | 14 +- .../src/main/angular/src/app/values.pipe.ts | 2 +- ids-webconsole/src/main/angular/src/main.ts | 2 +- ids-webconsole/src/main/angular/tslint.json | 30 - ids-webconsole/src/main/angular/yarn.lock | 3931 ++++++++++------- runWebconsole.sh | 4 +- 39 files changed, 2491 insertions(+), 1858 deletions(-) create mode 100644 ids-webconsole/src/main/angular/.eslintrc.json delete mode 100644 ids-webconsole/src/main/angular/tslint.json diff --git a/ids-webconsole/build.gradle.kts b/ids-webconsole/build.gradle.kts index 53ae5e960..6e35a39d8 100644 --- a/ids-webconsole/build.gradle.kts +++ b/ids-webconsole/build.gradle.kts @@ -135,13 +135,13 @@ val yarnInstall by tasks.registering(YarnTask::class) { val yarnLint by tasks.registering(YarnTask::class) { inputs.file("src/main/angular/package.json").withPathSensitivity(PathSensitivity.RELATIVE) inputs.file("src/main/angular/yarn.lock").withPathSensitivity(PathSensitivity.RELATIVE) - inputs.file("src/main/angular/tslint.json").withPathSensitivity(PathSensitivity.RELATIVE) + inputs.file("src/main/angular/.eslintrc.json").withPathSensitivity(PathSensitivity.RELATIVE) inputs.dir("src/main/angular/src").withPathSensitivity(PathSensitivity.RELATIVE) outputs.upToDateWhen { true } outputs.cacheIf { true } workingDir.set(file("src/main/angular")) - yarnCommand.set(listOf("lint")) + yarnCommand.set(listOf("ng", "lint")) onlyIf { !rootProject.hasProperty("skipAngular") } } diff --git a/ids-webconsole/src/main/angular/.eslintrc.json b/ids-webconsole/src/main/angular/.eslintrc.json new file mode 100644 index 000000000..c6bae92c2 --- /dev/null +++ b/ids-webconsole/src/main/angular/.eslintrc.json @@ -0,0 +1,104 @@ +{ + "root": true, + "ignorePatterns": [ + "projects/**/*" + ], + "overrides": [ + { + "files": [ + "*.ts" + ], + "parserOptions": { + "project": "src/tsconfig.json", + "createDefaultProgram": true + }, + "extends": [ + "plugin:@angular-eslint/ng-cli-compat", + "plugin:@angular-eslint/ng-cli-compat--formatting-add-on", + "plugin:@angular-eslint/template/process-inline-templates" + ], + "rules": { + "@angular-eslint/component-selector": "off", + "@typescript-eslint/array-type": [ + "error", + { + "default": "array" + } + ], + "@typescript-eslint/naming-convention": [ + "error", + { + "selector": "default", + "format": ["camelCase"] + }, + { + "selector": "variable", + "format": ["camelCase"] + }, + { + "selector": "variable", + "modifiers": ["const"], + "format": ["camelCase", "UPPER_CASE"] + }, + { + "selector": "parameter", + "format": ["camelCase"], + "leadingUnderscore": "allow" + }, + { + "selector": "memberLike", + "modifiers": ["private"], + "format": ["camelCase"], + "leadingUnderscore": "allow" + }, + { + "selector": "typeLike", + "format": ["PascalCase"] + }, + { + "selector": "enumMember", + "format": ["UPPER_CASE"] + }, + { + "selector": "objectLiteralProperty", + "format": null + } + ], + "@typescript-eslint/no-empty-function": "error", + "@typescript-eslint/no-var-requires": "error", + "comma-dangle": "error", + "import/no-unassigned-import": "off", + "max-classes-per-file": [ + "error", + 1 + ], + "no-empty": "error", + "no-fallthrough": "off", + "prefer-template": "off", + "no-underscore-dangle": "off", + "no-unused-vars": [ + "error", + { + "vars": "all", + "args": "after-used", + "ignoreRestSiblings": false, + "argsIgnorePattern": "ignored|^_", + "varsIgnorePattern": "ignored|^_" + } + ] + } + }, + { + "files": [ + "*.html" + ], + "extends": [ + "plugin:@angular-eslint/template/recommended" + ], + "rules": { + "@angular-eslint/template/cyclomatic-complexity": "off", + "@angular-eslint/template/i18n": "off" + } + } + ] +} diff --git a/ids-webconsole/src/main/angular/angular.json b/ids-webconsole/src/main/angular/angular.json index a06581aac..66b299035 100644 --- a/ids-webconsole/src/main/angular/angular.json +++ b/ids-webconsole/src/main/angular/angular.json @@ -51,7 +51,6 @@ "optimization": true, "outputHashing": "all", "sourceMap": false, - "extractCss": true, "namedChunks": false, "aot": true, "extractLicenses": true, @@ -85,13 +84,11 @@ } }, "lint": { - "builder": "@angular-devkit/build-angular:tslint", + "builder": "@angular-eslint/builder:lint", "options": { - "tsConfig": [ - "src/tsconfig.json" - ], - "exclude": [ - "**/node_modules/**" + "lintFilePatterns": [ + "src/**/*.ts", + "src/**/*.html" ] } } @@ -112,5 +109,8 @@ "@schematics/angular:directive": { "prefix": "app" } + }, + "cli": { + "defaultCollection": "@angular-eslint/schematics" } } diff --git a/ids-webconsole/src/main/angular/package.json b/ids-webconsole/src/main/angular/package.json index 28af59942..dcc1489ea 100644 --- a/ids-webconsole/src/main/angular/package.json +++ b/ids-webconsole/src/main/angular/package.json @@ -4,21 +4,18 @@ "license": "SEE LICENSE IN license.txt", "angular-cli": {}, "scripts": { - "ng": "ng", - "start": "ng serve", - "bundle": "ng build --prod --no-progress --output-path=\"../../../build/resources/main/www\"", - "lint": "ng lint" + "bundle": "ng build --prod --no-progress --output-path=\"../../../build/resources/main/www\"" }, "private": true, "dependencies": { - "@angular/animations": "~10.2.0", - "@angular/common": "~10.2.0", - "@angular/core": "~10.2.0", - "@angular/forms": "~10.2.0", - "@angular/platform-browser": "~10.2.0", - "@angular/platform-browser-dynamic": "~10.2.0", - "@angular/platform-server": "~10.2.0", - "@angular/router": "~10.2.0", + "@angular/animations": "~11.2.13", + "@angular/common": "~11.2.13", + "@angular/core": "~11.2.13", + "@angular/forms": "~11.2.13", + "@angular/platform-browser": "~11.2.13", + "@angular/platform-browser-dynamic": "~11.2.13", + "@angular/platform-server": "~11.2.13", + "@angular/router": "~11.2.13", "bootstrap": "^4.2.1", "core-js": "^3.6.4", "deep-equal": "^2.0.1", @@ -31,19 +28,27 @@ "topojson": "^3.0.2", "tslib": "^2.0.0", "viz.js": "^2.1.1", - "zone.js": "~0.10.2" + "zone.js": "^0.11.4" }, "devDependencies": { - "@angular-devkit/build-angular": "~0.1002.0", - "@angular/cli": "~10.2.0", - "@angular/compiler": "~10.2.0", - "@angular/compiler-cli": "~10.2.0", - "@saritasa/tslint-config-angular": "^2.0.0", - "@types/node": "^12.11.1", + "@angular-devkit/build-angular": "~0.1102.12", + "@angular-eslint/builder": "4.2.0", + "@angular-eslint/eslint-plugin": "4.2.0", + "@angular-eslint/eslint-plugin-template": "4.2.0", + "@angular-eslint/schematics": "4.2.0", + "@angular-eslint/template-parser": "4.2.0", + "@angular/cli": "~11.2.12", + "@angular/compiler": "~11.2.13", + "@angular/compiler-cli": "~11.2.13", + "@types/node": "^15.0.2", "@types/vis": "^4.21.9", - "codelyzer": "^5.1.2", - "tslint": "~6.1.0", + "@typescript-eslint/eslint-plugin": "4.16.1", + "@typescript-eslint/parser": "4.16.1", + "eslint": "^7.6.0", + "eslint-plugin-import": "latest", + "eslint-plugin-jsdoc": "latest", + "eslint-plugin-prefer-arrow": "latest", "typescript": "4.0.5", "vis": "^4.20.0" } -} +} \ No newline at end of file diff --git a/ids-webconsole/src/main/angular/src/app/_interceptors/jwt.interceptor.ts b/ids-webconsole/src/main/angular/src/app/_interceptors/jwt.interceptor.ts index e81f5bf5d..65d32be98 100644 --- a/ids-webconsole/src/main/angular/src/app/_interceptors/jwt.interceptor.ts +++ b/ids-webconsole/src/main/angular/src/app/_interceptors/jwt.interceptor.ts @@ -1,7 +1,6 @@ -import { HttpRequest, HttpHandler, HttpErrorResponse, HttpEvent, HttpInterceptor, HttpResponse } from '@angular/common/http'; +import { HttpRequest, HttpHandler, HttpErrorResponse, HttpEvent, HttpInterceptor } from '@angular/common/http'; import { Injectable } from '@angular/core'; -import { Observable } from 'rxjs'; -import { throwError, of } from 'rxjs'; +import { Observable, throwError } from 'rxjs'; import { catchError } from 'rxjs/operators'; import { LoginService } from '../login/login.service'; @@ -20,6 +19,7 @@ export class JwtInterceptor implements HttpInterceptor { if (currentUser) { request = request.clone({ setHeaders: { + /* eslint-disable @typescript-eslint/naming-convention */ Authorization: `Bearer ${currentUser}` } }); @@ -27,10 +27,9 @@ export class JwtInterceptor implements HttpInterceptor { // If we receive 401 (or other error), log out the user immediately. return next.handle(request).pipe( - catchError((err: HttpErrorResponse) => { - this.loginService.logout(); - return throwError(err); - })); - + catchError((err: HttpErrorResponse) => { + this.loginService.logout(); + return throwError(err); + })); } } diff --git a/ids-webconsole/src/main/angular/src/app/app.component.ts b/ids-webconsole/src/main/angular/src/app/app.component.ts index 83d8cc6b3..8624d46da 100644 --- a/ids-webconsole/src/main/angular/src/app/app.component.ts +++ b/ids-webconsole/src/main/angular/src/app/app.component.ts @@ -1,10 +1,9 @@ import { AfterViewInit, Component, OnInit } from '@angular/core'; import { Title } from '@angular/platform-browser'; -import { Observable } from 'rxjs'; import { LoginService } from './login/login.service'; -declare var componentHandler: any; +declare let componentHandler: any; @Component({ selector: 'iot-connector', diff --git a/ids-webconsole/src/main/angular/src/app/app.routing.ts b/ids-webconsole/src/main/angular/src/app/app.routing.ts index c61ccdebc..09ef22685 100644 --- a/ids-webconsole/src/main/angular/src/app/app.routing.ts +++ b/ids-webconsole/src/main/angular/src/app/app.routing.ts @@ -21,7 +21,7 @@ const appRoutes: Routes = [ // Pages using the "home" layout (with sidebar and topnav) { path: '', component: HomeLayoutComponent, canActivate: [AuthGuard], children: [ - { path: '', redirectTo: 'dashboard', pathMatch: 'full', canActivate: [AuthGuard] }, + { path: '', redirectTo: 'dashboard', pathMatch: 'full' }, { path: 'dashboard', component: DashboardComponent, data: { title: 'Dashboard' }, canActivate: [AuthGuard] }, { path: 'apps', component: AppsComponent, canActivate: [AuthGuard] }, { path: 'appsearch', component: AppsSearchComponent, canActivate: [AuthGuard] }, @@ -45,4 +45,4 @@ const appRoutes: Routes = [ } ]; -export const routing = RouterModule.forRoot(appRoutes, { useHash: true }); +export const routing = RouterModule.forRoot(appRoutes, { useHash: true, relativeLinkResolution: 'legacy' }); diff --git a/ids-webconsole/src/main/angular/src/app/application-http-client.service.ts b/ids-webconsole/src/main/angular/src/app/application-http-client.service.ts index 2d04b6f92..bac277c3f 100644 --- a/ids-webconsole/src/main/angular/src/app/application-http-client.service.ts +++ b/ids-webconsole/src/main/angular/src/app/application-http-client.service.ts @@ -31,6 +31,7 @@ export interface RequestOptionsCached extends RequestOptions { export interface ApplicationHttpClient { /** * GET request + * * @param endPoint The endpoint, starting with a slash * @param options Options of the request like headers, body, etc. */ @@ -38,6 +39,7 @@ export interface ApplicationHttpClient { /** * POST request + * * @param endPoint The endpoint at the API, starting with a slash * @param body Body of the request * @param options Options of the request like headers, body, etc. @@ -47,14 +49,16 @@ export interface ApplicationHttpClient { /** * PUT request + * * @param endPoint The endpoint at the API, starting with a slash * @param params Body of the request * @param options Options of the request like headers, body, etc. */ - put(endPoint: string, params: object, options?: RequestOptions): Observable; + put(endPoint: string, params: Record, options?: RequestOptions): Observable; /** * DELETE request + * * @param endPoint The endpoint at the API, starting with a slash * @param options Options of the request like headers, body, etc. */ @@ -69,6 +73,7 @@ export class ApplicationHttpClientImpl implements ApplicationHttpClient { /** * GET request + * * @param endPoint The endpoint, starting with a slash * @param options Options of the request like headers, body, etc. */ @@ -91,6 +96,7 @@ export class ApplicationHttpClientImpl implements ApplicationHttpClient { /** * POST request + * * @param endPoint The endpoint at the API, starting with a slash * @param body Body of the request * @param options Options of the request like headers, body, etc. @@ -101,16 +107,18 @@ export class ApplicationHttpClientImpl implements ApplicationHttpClient { /** * PUT request + * * @param endPoint The endpoint at the API, starting with a slash * @param params Body of the request * @param options Options of the request like headers, body, etc. */ - public put(endPoint: string, params: object, options?: any): any { + public put(endPoint: string, params: Record, options?: any): any { return this.http.put(environment.apiURL + endPoint, params, options); } /** * DELETE request + * * @param endPoint The endpoint at the API, starting with a slash * @param options Options of the request like headers, body, etc. */ diff --git a/ids-webconsole/src/main/angular/src/app/apps/app-card.component.ts b/ids-webconsole/src/main/angular/src/app/apps/app-card.component.ts index 64d80b8f6..4bce9931a 100644 --- a/ids-webconsole/src/main/angular/src/app/apps/app-card.component.ts +++ b/ids-webconsole/src/main/angular/src/app/apps/app-card.component.ts @@ -61,7 +61,7 @@ export class AppCardComponent implements OnInit { public onDeleteBtnClick(containerId: string): void { this.appService.wipeApp(containerId) - .subscribe(result => undefined); + .subscribe(_result => undefined); const index = this.appsComponent.apps.indexOf(this.app); this.appsComponent.apps.splice(index, 1) ; } diff --git a/ids-webconsole/src/main/angular/src/app/apps/app-search-result-card.component.ts b/ids-webconsole/src/main/angular/src/app/apps/app-search-result-card.component.ts index 6274dd572..292b3b1d7 100644 --- a/ids-webconsole/src/main/angular/src/app/apps/app-search-result-card.component.ts +++ b/ids-webconsole/src/main/angular/src/app/apps/app-search-result-card.component.ts @@ -3,7 +3,7 @@ import { AfterViewInit, Component, Input } from '@angular/core'; import { App } from './app'; import { AppService } from './app.service'; -declare var componentHandler: any; +declare let componentHandler: any; @Component({ selector: 'app-search-result-card', diff --git a/ids-webconsole/src/main/angular/src/app/apps/apps-search.component.ts b/ids-webconsole/src/main/angular/src/app/apps/apps-search.component.ts index 3d5c56d24..b3454344d 100644 --- a/ids-webconsole/src/main/angular/src/app/apps/apps-search.component.ts +++ b/ids-webconsole/src/main/angular/src/app/apps/apps-search.component.ts @@ -4,7 +4,7 @@ import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { App } from './app'; import { AppService } from './app.service'; -declare var componentHandler: any; +declare let componentHandler: any; @Component({ templateUrl: './apps-search.component.html', @@ -16,14 +16,14 @@ export class AppsSearchComponent implements OnInit, AfterViewInit { public saved: boolean; public searchResults: App[] = []; - constructor(private readonly _fb: FormBuilder, private readonly _appService: AppService) { + constructor(private readonly fb: FormBuilder, private readonly appService: AppService) { this.saved = true; this.submitted = false; } public ngOnInit(): void { // the short way - this.myForm = this._fb.group({ + this.myForm = this.fb.group({ apps_search: ['', [Validators.required as any, Validators.minLength(3) as any]] }); } @@ -32,9 +32,9 @@ export class AppsSearchComponent implements OnInit, AfterViewInit { componentHandler.upgradeAllRegistered(); } - public save(model: any, isValid: boolean): void { + public save(model: any, _isValid: boolean): void { this.submitted = true; - this._appService + this.appService .searchApps(model.apps_search) .subscribe(res => { this.searchResults = res; }); } diff --git a/ids-webconsole/src/main/angular/src/app/apps/apps.component.ts b/ids-webconsole/src/main/angular/src/app/apps/apps.component.ts index d389fe062..1b9489a47 100644 --- a/ids-webconsole/src/main/angular/src/app/apps/apps.component.ts +++ b/ids-webconsole/src/main/angular/src/app/apps/apps.component.ts @@ -4,7 +4,7 @@ import { Title } from '@angular/platform-browser'; import { App } from './app'; import { AppService } from './app.service'; -declare var componentHandler: any; +declare let componentHandler: any; @Component({ templateUrl: './apps.component.html', diff --git a/ids-webconsole/src/main/angular/src/app/apps/cml.ts b/ids-webconsole/src/main/angular/src/app/apps/cml.ts index 88a613aa0..15415fd3d 100644 --- a/ids-webconsole/src/main/angular/src/app/apps/cml.ts +++ b/ids-webconsole/src/main/angular/src/app/apps/cml.ts @@ -1,4 +1,4 @@ export class Cml { - // tslint:disable-next-line:variable-name + // eslint-disable-next-line @typescript-eslint/naming-convention, no-underscore-dangle, id-blacklist, id-match public cml_version: string; } diff --git a/ids-webconsole/src/main/angular/src/app/confirm/confirm.component.ts b/ids-webconsole/src/main/angular/src/app/confirm/confirm.component.ts index 85427caea..455f94e18 100644 --- a/ids-webconsole/src/main/angular/src/app/confirm/confirm.component.ts +++ b/ids-webconsole/src/main/angular/src/app/confirm/confirm.component.ts @@ -16,89 +16,89 @@ export class ConfirmComponent implements OnInit { public okText: string; public cancelText: string; - private readonly _defaults = { + private readonly defaultTexts = { title: 'Confirmation', message: 'Do you want to cancel your changes?', - cancelText: 'Cancel', - okText: 'OK' + okText: 'OK', + cancelText: 'Cancel' }; - private _confirmElement: any; - private _cancelButton: any; - private _okButton: any; + private confirmElement: any; + private cancelButton: any; + private okButton: any; constructor(confirmService: ConfirmService) { confirmService.activate = this.activate.bind(this); } public ngOnInit(): void { - this._confirmElement = document.getElementById('confirmationModal'); - this._cancelButton = document.getElementById('cancelButton'); - this._okButton = document.getElementById('okButton'); + this.confirmElement = document.getElementById('confirmationModal'); + this.cancelButton = document.getElementById('cancelButton'); + this.okButton = document.getElementById('okButton'); } - public _setLabels(message: string = this._defaults.message, title: string = this._defaults.title): void { + public setLabels(message: string = this.defaultTexts.message, title: string = this.defaultTexts.title): void { this.title = title; this.message = message; - this.okText = this._defaults.okText; - this.cancelText = this._defaults.cancelText; + this.okText = this.defaultTexts.okText; + this.cancelText = this.defaultTexts.cancelText; } - public async activate(message: string = this._defaults.message, title: string = this._defaults.title): Promise { - this._setLabels(message, title); + public async activate(message: string = this.defaultTexts.message, title: string = this.defaultTexts.title): Promise { + this.setLabels(message, title); return new Promise(resolve => { - this._show(resolve); + this.show(resolve); }); } - private _show(resolve: ((b: boolean) => any)): void { + private show(resolve: ((b: boolean) => any)): void { document.onkeyup = undefined; - const negativeOnClick = (e: any) => resolve(false); - const positiveOnClick = (e: any) => resolve(true); + const negativeOnClick = (_e: any) => resolve(false); + const positiveOnClick = (_e: any) => resolve(true); - if (!this._confirmElement || !this._cancelButton || !this._okButton) { + if (!this.confirmElement || !this.cancelButton || !this.okButton) { return; } - this._confirmElement.style.opacity = 0; - this._confirmElement.style.zIndex = 9999; + this.confirmElement.style.opacity = 0; + this.confirmElement.style.zIndex = 9999; - this._cancelButton.onclick = ((e: any) => { + this.cancelButton.onclick = ((e: any) => { e.preventDefault(); if (!negativeOnClick(e)) { - this._hideDialog(); + this.hideDialog(); } }); - this._okButton.onclick = ((e: any) => { + this.okButton.onclick = ((e: any) => { e.preventDefault(); if (!positiveOnClick(e)) { - this._hideDialog(); + this.hideDialog(); } }); - this._confirmElement.onclick = () => { - this._hideDialog(); + this.confirmElement.onclick = () => { + this.hideDialog(); return negativeOnClick(undefined); }; document.onkeyup = (e: any) => { if (e.which === KEY_ESC) { - this._hideDialog(); + this.hideDialog(); return negativeOnClick(undefined); } }; - this._confirmElement.style.opacity = 1; + this.confirmElement.style.opacity = 1; } - private _hideDialog(): void { + private hideDialog(): void { document.onkeyup = undefined; - this._confirmElement.style.opacity = 0; - window.setTimeout(() => this._confirmElement.style.zIndex = -1, 400); + this.confirmElement.style.opacity = 0; + window.setTimeout(() => this.confirmElement.style.zIndex = -1, 400); } } diff --git a/ids-webconsole/src/main/angular/src/app/connection-configuration/connection-configuration.component.ts b/ids-webconsole/src/main/angular/src/app/connection-configuration/connection-configuration.component.ts index 44c8189fc..9948f8afd 100644 --- a/ids-webconsole/src/main/angular/src/app/connection-configuration/connection-configuration.component.ts +++ b/ids-webconsole/src/main/angular/src/app/connection-configuration/connection-configuration.component.ts @@ -30,7 +30,7 @@ export class ConnectionConfigurationComponent implements OnInit { }); } - public trackModels(index: number, item: Configuration): string { + public trackModels(_index: number, item: Configuration): string { return item.connection; } diff --git a/ids-webconsole/src/main/angular/src/app/connection-configuration/connection-configuration.service.ts b/ids-webconsole/src/main/angular/src/app/connection-configuration/connection-configuration.service.ts index d1504b34f..ae86d65cb 100644 --- a/ids-webconsole/src/main/angular/src/app/connection-configuration/connection-configuration.service.ts +++ b/ids-webconsole/src/main/angular/src/app/connection-configuration/connection-configuration.service.ts @@ -26,7 +26,7 @@ export class ConnectionConfigurationService { } public getAllConfiguration(): Observable { - return this.http.get(environment.apiURL + '/config/connectionConfigs') + return this.http.get>(environment.apiURL + '/config/connectionConfigs') .pipe(map(configMap => Object.keys(configMap) .map(key => new Configuration(key, configMap[key])))); } diff --git a/ids-webconsole/src/main/angular/src/app/dataflowpolicies/dataflowpolicies.component.ts b/ids-webconsole/src/main/angular/src/app/dataflowpolicies/dataflowpolicies.component.ts index 26f3db884..39cf414cd 100644 --- a/ids-webconsole/src/main/angular/src/app/dataflowpolicies/dataflowpolicies.component.ts +++ b/ids-webconsole/src/main/angular/src/app/dataflowpolicies/dataflowpolicies.component.ts @@ -3,7 +3,7 @@ import { Title } from '@angular/platform-browser'; import { PolicyService } from './policy.service'; -declare var componentHandler: any; +declare let componentHandler: any; @Component({ templateUrl: './dataflowpolicies.component.html' diff --git a/ids-webconsole/src/main/angular/src/app/dataflowpolicies/dataflowpoliciesnew.component.html b/ids-webconsole/src/main/angular/src/app/dataflowpolicies/dataflowpoliciesnew.component.html index c1c11768a..a4d875ecf 100644 --- a/ids-webconsole/src/main/angular/src/app/dataflowpolicies/dataflowpoliciesnew.component.html +++ b/ids-webconsole/src/main/angular/src/app/dataflowpolicies/dataflowpoliciesnew.component.html @@ -10,14 +10,14 @@

Create Data Usage Control Policy

@@ -25,7 +25,7 @@

Create Data Usage Control Policy

diff --git a/ids-webconsole/src/main/angular/src/app/dataflowpolicies/dataflowpoliciesnew.component.ts b/ids-webconsole/src/main/angular/src/app/dataflowpolicies/dataflowpoliciesnew.component.ts index cf0560753..91b6161ff 100644 --- a/ids-webconsole/src/main/angular/src/app/dataflowpolicies/dataflowpoliciesnew.component.ts +++ b/ids-webconsole/src/main/angular/src/app/dataflowpolicies/dataflowpoliciesnew.component.ts @@ -17,20 +17,20 @@ export class NewDataflowPolicyComponent implements OnInit { public multiple: false; public fileUpload: AbstractControl; - constructor(private readonly _fb: FormBuilder, private readonly titleService: Title, private readonly policyService: PolicyService) { + constructor(private readonly fb: FormBuilder, private readonly titleService: Title, private readonly policyService: PolicyService) { this.titleService.setTitle('New Policy'); } public ngOnInit(): void { // the short way to create a FormGroup - this.myForm = this._fb.group({ - policy_file: ['', Validators.required as any] + this.myForm = this.fb.group({ + policyFile: ['', Validators.required] }); - this.fileUpload = this.myForm.get('policy_file'); + this.fileUpload = this.myForm.get('policyFile'); } - public save(policy: Policy, fileInputElement: any, isValid: boolean): void { + public save(policy: Policy, fileInputElement: any, _isValid: boolean): void { // console.log(policy, fileInputElement, isValid); // console.log(fileInputElement.files[0]); diff --git a/ids-webconsole/src/main/angular/src/app/dataflowpolicies/policy.interface.ts b/ids-webconsole/src/main/angular/src/app/dataflowpolicies/policy.interface.ts index df25b1737..3331989f9 100644 --- a/ids-webconsole/src/main/angular/src/app/dataflowpolicies/policy.interface.ts +++ b/ids-webconsole/src/main/angular/src/app/dataflowpolicies/policy.interface.ts @@ -1,4 +1,4 @@ export interface Policy { - policy_name: string; - policy_description: string; + policyName: string; + policyDescription: string; } diff --git a/ids-webconsole/src/main/angular/src/app/dataflowpolicies/policy.service.ts b/ids-webconsole/src/main/angular/src/app/dataflowpolicies/policy.service.ts index 2bf044a5d..fecb42686 100644 --- a/ids-webconsole/src/main/angular/src/app/dataflowpolicies/policy.service.ts +++ b/ids-webconsole/src/main/angular/src/app/dataflowpolicies/policy.service.ts @@ -19,8 +19,8 @@ export class PolicyService { public install(policy: Policy, policyFile: any): Observable { const headers = new HttpHeaders({ 'Content-Type': 'multipart/form-data' }); const model = new FormData(); - model.append('policy_name', policy.policy_name); - model.append('policy_description', policy.policy_description); + model.append('policy_name', policy.policyName); + model.append('policy_description', policy.policyDescription); model.append('policy_file', policyFile); return this.http.post(environment.apiURL + '/policies/install', model, { headers }) diff --git a/ids-webconsole/src/main/angular/src/app/keycerts/certificate-card.component.ts b/ids-webconsole/src/main/angular/src/app/keycerts/certificate-card.component.ts index 881f8b913..8a6c6b806 100644 --- a/ids-webconsole/src/main/angular/src/app/keycerts/certificate-card.component.ts +++ b/ids-webconsole/src/main/angular/src/app/keycerts/certificate-card.component.ts @@ -4,7 +4,7 @@ import { ConfirmService } from '../confirm/confirm.service'; import { Certificate } from './certificate'; -declare var componentHandler: any; +declare let componentHandler: any; @Component({ selector: 'certificate-card', @@ -15,8 +15,8 @@ declare var componentHandler: any; export class CertificateCardComponent implements OnInit { @Input() public certificates: Certificate[]; @Input() public trusts: Certificate[]; - public result: string; @Input() private readonly onDeleteCallback: (alias: string) => void; + public result: string; constructor(private readonly confirmService: ConfirmService) { } diff --git a/ids-webconsole/src/main/angular/src/app/keycerts/identitynew.component.ts b/ids-webconsole/src/main/angular/src/app/keycerts/identitynew.component.ts index 0df157a5d..b651393aa 100644 --- a/ids-webconsole/src/main/angular/src/app/keycerts/identitynew.component.ts +++ b/ids-webconsole/src/main/angular/src/app/keycerts/identitynew.component.ts @@ -15,14 +15,14 @@ export class NewIdentityComponent implements OnInit { public data: Identity; public events: any[] = []; - constructor(private readonly _fb: FormBuilder, private readonly titleService: Title, private readonly certService: CertificateService, + constructor(private readonly fb: FormBuilder, private readonly titleService: Title, private readonly certService: CertificateService, private readonly router: Router) { this.titleService.setTitle('New Identity'); } public ngOnInit(): void { // the short way to create a FormGroup - this.myForm = this._fb.group({ + this.myForm = this.fb.group({ s: ['', Validators.required as any], cn: ['', Validators.required as any], o: '', diff --git a/ids-webconsole/src/main/angular/src/app/keycerts/keycerts.component.ts b/ids-webconsole/src/main/angular/src/app/keycerts/keycerts.component.ts index 70a179ece..b7d235ecc 100755 --- a/ids-webconsole/src/main/angular/src/app/keycerts/keycerts.component.ts +++ b/ids-webconsole/src/main/angular/src/app/keycerts/keycerts.component.ts @@ -1,4 +1,4 @@ -import { Component, EventEmitter, OnInit, Output, ViewContainerRef } from '@angular/core'; +import { Component, EventEmitter, OnInit, Output } from '@angular/core'; import { Title } from '@angular/platform-browser'; import { Certificate } from './certificate'; @@ -9,13 +9,12 @@ import { CertificateService } from './keycert.service'; templateUrl: './keycerts.component.html' }) export class KeycertsComponent implements OnInit { + @Output() public readonly changeTitle = new EventEmitter(); public title = 'Current Certificates'; public identities: Certificate[]; public certificates: Certificate[]; - @Output() public readonly changeTitle = new EventEmitter(); - - constructor(private readonly titleService: Title, private readonly certificateService: CertificateService, vcRef: ViewContainerRef) { + constructor(private readonly titleService: Title, private readonly certificateService: CertificateService) { this.titleService.setTitle('Identities'); this.certificateService.getIdentities() @@ -35,7 +34,7 @@ export class KeycertsComponent implements OnInit { public deleteCert(alias: string): void { this.certificateService.deleteCert(alias) - .subscribe(result => { + .subscribe(_result => { // this.result = result; // if(result.toString() === "true") { // location.reload(); @@ -45,7 +44,7 @@ export class KeycertsComponent implements OnInit { public deleteIdentity(alias: string): void { this.certificateService.deleteIdentity(alias) - .subscribe(result => { + .subscribe(_result => { // this.result = result; // if(result.toString() === "true") { // location.reload(); diff --git a/ids-webconsole/src/main/angular/src/app/layouts/home-layout/home-layout.component.ts b/ids-webconsole/src/main/angular/src/app/layouts/home-layout/home-layout.component.ts index 18509ab22..648021d93 100644 --- a/ids-webconsole/src/main/angular/src/app/layouts/home-layout/home-layout.component.ts +++ b/ids-webconsole/src/main/angular/src/app/layouts/home-layout/home-layout.component.ts @@ -4,7 +4,7 @@ import { Router } from '@angular/router'; import { LoginService } from '../../login/login.service'; -declare var componentHandler: any; +declare let componentHandler: any; @Component({ selector: 'app-home-layout', diff --git a/ids-webconsole/src/main/angular/src/app/layouts/login-layout/login-layout.component.ts b/ids-webconsole/src/main/angular/src/app/layouts/login-layout/login-layout.component.ts index 7e69cbaa0..8f591ef21 100644 --- a/ids-webconsole/src/main/angular/src/app/layouts/login-layout/login-layout.component.ts +++ b/ids-webconsole/src/main/angular/src/app/layouts/login-layout/login-layout.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, AfterViewInit } from '@angular/core'; +import { Component, OnInit } from '@angular/core'; import { Title } from '@angular/platform-browser'; import { LoginService } from '../../login/login.service'; diff --git a/ids-webconsole/src/main/angular/src/app/login/login.component.ts b/ids-webconsole/src/main/angular/src/app/login/login.component.ts index b0c0cf55c..d0007f1e8 100644 --- a/ids-webconsole/src/main/angular/src/app/login/login.component.ts +++ b/ids-webconsole/src/main/angular/src/app/login/login.component.ts @@ -1,5 +1,5 @@ import { Component } from '@angular/core'; -import { FormBuilder, Validators, FormGroup } from '@angular/forms'; +import { FormBuilder, FormGroup } from '@angular/forms'; import { Router } from '@angular/router'; import { LoginService } from './login.service'; diff --git a/ids-webconsole/src/main/angular/src/app/mdl-upgrade-element-directive.ts b/ids-webconsole/src/main/angular/src/app/mdl-upgrade-element-directive.ts index 0b9dd8f91..dc54032dc 100644 --- a/ids-webconsole/src/main/angular/src/app/mdl-upgrade-element-directive.ts +++ b/ids-webconsole/src/main/angular/src/app/mdl-upgrade-element-directive.ts @@ -1,5 +1,5 @@ import { AfterViewChecked, Directive } from '@angular/core'; -declare var componentHandler: { +declare let componentHandler: { upgradeAllRegistered(): void; }; diff --git a/ids-webconsole/src/main/angular/src/app/prettify-json.pipe.ts b/ids-webconsole/src/main/angular/src/app/prettify-json.pipe.ts index 28261eef8..9adcd5ca3 100644 --- a/ids-webconsole/src/main/angular/src/app/prettify-json.pipe.ts +++ b/ids-webconsole/src/main/angular/src/app/prettify-json.pipe.ts @@ -4,7 +4,7 @@ import { Pipe, PipeTransform } from '@angular/core'; name: 'prettify' }) export class PrettifyPipe implements PipeTransform { - public transform(val: any): object { + public transform(val: any): Record { const obj = JSON.stringify(val) .replace('\n', '
') .replace(/&/g, '&') diff --git a/ids-webconsole/src/main/angular/src/app/result.ts b/ids-webconsole/src/main/angular/src/app/result.ts index 892bb560b..1387a18fd 100644 --- a/ids-webconsole/src/main/angular/src/app/result.ts +++ b/ids-webconsole/src/main/angular/src/app/result.ts @@ -1,5 +1,3 @@ -import { Route } from './routes/route'; - export class Result { public successful: boolean; public message: string; diff --git a/ids-webconsole/src/main/angular/src/app/routes/route.service.ts b/ids-webconsole/src/main/angular/src/app/routes/route.service.ts index 0b682f3fa..a8715c929 100644 --- a/ids-webconsole/src/main/angular/src/app/routes/route.service.ts +++ b/ids-webconsole/src/main/angular/src/app/routes/route.service.ts @@ -46,7 +46,7 @@ export class RouteService { public saveRoute(routeId: string, routeString: string): Observable { // Update Camel route - const headers = new HttpHeaders().set('Content-Type', 'text/plain; charset=utf-8'); + const headers = new HttpHeaders({ 'Content-Type': 'text/plain; charset=utf-8' }); // console.log('Sending Update: ' + routeString); return this.httpClient.post(environment.apiURL + '/routes/save/' + routeId, @@ -55,7 +55,7 @@ export class RouteService { public addRoute(routeString: string): Observable { // Save new Camel route - const headers = new HttpHeaders().set('Content-Type', 'text/plain; charset=utf-8'); + const headers = new HttpHeaders({ 'Content-Type': 'text/plain; charset=utf-8' }); // console.log('Sending New: ' + routeString); return this.httpClient.put(environment.apiURL + '/routes/add', diff --git a/ids-webconsole/src/main/angular/src/app/routes/routeeditor/routeeditor.component.ts b/ids-webconsole/src/main/angular/src/app/routes/routeeditor/routeeditor.component.ts index e597d90ae..83d51f41b 100644 --- a/ids-webconsole/src/main/angular/src/app/routes/routeeditor/routeeditor.component.ts +++ b/ids-webconsole/src/main/angular/src/app/routes/routeeditor/routeeditor.component.ts @@ -27,7 +27,7 @@ export class RouteeditorComponent implements OnInit { private statusIcon: string; private readonly _dotSubject: ReplaySubject = new ReplaySubject(1); - constructor(private readonly titleService: Title, private readonly _fb: FormBuilder, private readonly router: Router, + constructor(private readonly titleService: Title, private readonly fb: FormBuilder, private readonly router: Router, private readonly navRoute: ActivatedRoute, private readonly routeService: RouteService) { this.titleService.setTitle('Edit Message Route'); } @@ -107,7 +107,7 @@ export class RouteeditorComponent implements OnInit { }); }); - this.myForm = this._fb.group({ + this.myForm = this.fb.group({ txtRepresentation: ['', [Validators.required as any, Validators.minLength(5) as any]] }); } @@ -178,9 +178,6 @@ export class RouteeditorComponent implements OnInit { this._validationInfo = validationInfo; }); } - }, - error => { - // console.log(error); } ); } else { @@ -194,9 +191,6 @@ export class RouteeditorComponent implements OnInit { // console.log('Route editor: Created route(s)'); return this.router.navigate(['routes']); } - }, - error => { - // console.log(error); } ); } diff --git a/ids-webconsole/src/main/angular/src/app/routes/routes.component.ts b/ids-webconsole/src/main/angular/src/app/routes/routes.component.ts index ffca43da0..224ff79c9 100644 --- a/ids-webconsole/src/main/angular/src/app/routes/routes.component.ts +++ b/ids-webconsole/src/main/angular/src/app/routes/routes.component.ts @@ -14,8 +14,8 @@ import { RouteService } from './route.service'; }) export class RoutesComponent implements OnInit, OnDestroy { - public title = 'Current Routes'; @Output() public readonly changeTitle = new EventEmitter(); + public title = 'Current Routes'; public routes: Route[]; public selectedRoute: Route; public routemetrics: RouteMetrics = new RouteMetrics(); diff --git a/ids-webconsole/src/main/angular/src/app/routes/zoom-viz/zoom-viz.component.ts b/ids-webconsole/src/main/angular/src/app/routes/zoom-viz/zoom-viz.component.ts index 1bfe63f78..220f63705 100644 --- a/ids-webconsole/src/main/angular/src/app/routes/zoom-viz/zoom-viz.component.ts +++ b/ids-webconsole/src/main/angular/src/app/routes/zoom-viz/zoom-viz.component.ts @@ -3,6 +3,7 @@ import { from, Subject } from 'rxjs'; import { switchMap } from 'rxjs/operators'; import 'svg-pan-zoom'; +/* eslint-disable @typescript-eslint/naming-convention */ declare const Viz: any; @Component({ @@ -15,15 +16,10 @@ export class ZoomVizComponent implements OnInit { @ViewChild('vizCanvas', { static: true }) private readonly vizCanvasRef: ElementRef; private zoom?: SvgPanZoom.Instance; private isLocked = false; - private removeMoveListener: () => void = (() => undefined); private isInitialized = false; constructor(private readonly renderer: Renderer2) {} - get locked(): boolean { - return this.isLocked; - } - public ngOnInit(): void { const viz = new Viz(); const vizCanvas = this.vizCanvasRef.nativeElement; @@ -41,7 +37,7 @@ export class ZoomVizComponent implements OnInit { if (someNode !== null) { zoomFactor = 50 / (someNode as HTMLElement).getBoundingClientRect().height; } - // tslint:disable-next-line:curly + // eslint-disable-next-line curly if (zoomFactor > 1) { // lazy init on first mouseenter event const mouseEnterListener = this.renderer.listen(vizCanvas, 'mouseenter', () => { @@ -91,4 +87,10 @@ export class ZoomVizComponent implements OnInit { }); } + private removeMoveListener: () => void = (() => undefined); + + get locked(): boolean { + return this.isLocked; + } + } diff --git a/ids-webconsole/src/main/angular/src/app/values.pipe.ts b/ids-webconsole/src/main/angular/src/app/values.pipe.ts index 15b3d3c56..e9c2ba5ff 100644 --- a/ids-webconsole/src/main/angular/src/app/values.pipe.ts +++ b/ids-webconsole/src/main/angular/src/app/values.pipe.ts @@ -2,7 +2,7 @@ import { Pipe, PipeTransform } from '@angular/core'; @Pipe({ name: 'values' }) export class ValuesPipe implements PipeTransform { - public transform(value: any, args?: any[]): any { + public transform(value: any, _args?: any[]): any { return Object.keys(value) .map(key => value[key]); } diff --git a/ids-webconsole/src/main/angular/src/main.ts b/ids-webconsole/src/main/angular/src/main.ts index 2cc579ada..06d7a9da0 100644 --- a/ids-webconsole/src/main/angular/src/main.ts +++ b/ids-webconsole/src/main/angular/src/main.ts @@ -1,4 +1,4 @@ -// tslint:disable:no-floating-promises +/* eslint-disable @typescript-eslint/no-floating-promises */ import { enableProdMode } from '@angular/core'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; diff --git a/ids-webconsole/src/main/angular/tslint.json b/ids-webconsole/src/main/angular/tslint.json deleted file mode 100644 index 1b056630f..000000000 --- a/ids-webconsole/src/main/angular/tslint.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "rulesDirectory": [ - "node_modules/codelyzer" - ], - "extends": [ - "tslint:recommended" - ], - "rules": { - "curly": true, - "comment-format": false, - "component-selector": false, - "completed-docs": false, - "deprecation": { - "severity": "warning" - }, - "whitespace": false, - "trailing-comma": [ - true, - { - "multiline": "never", - "singleline": "never" - } - ], - "template-i18n": false, - "no-unused-css": false, - "prefer-template": false, - "no-import-side-effect": false, - "template-cyclomatic-complexity": false - } -} \ No newline at end of file diff --git a/ids-webconsole/src/main/angular/yarn.lock b/ids-webconsole/src/main/angular/yarn.lock index 4b32c178b..cd691cadf 100644 --- a/ids-webconsole/src/main/angular/yarn.lock +++ b/ids-webconsole/src/main/angular/yarn.lock @@ -2,170 +2,221 @@ # yarn lockfile v1 -"@angular-devkit/architect@0.1002.3": - version "0.1002.3" - resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.1002.3.tgz#fe8f3209ee6686efa0306410de27820b6606df52" - integrity sha512-7ainXRNO1njZ6bBbJXGpMzCh0OYrzuIRe/+zRj0ncV1YfEsJb2yWBuiza0+y2Ljco7hdd4wr+7eJm7cfn+NvAw== - dependencies: - "@angular-devkit/core" "10.2.3" - rxjs "6.6.2" - -"@angular-devkit/build-angular@~0.1002.0": - version "0.1002.3" - resolved "https://registry.yarnpkg.com/@angular-devkit/build-angular/-/build-angular-0.1002.3.tgz#f23c872dd953d1a3ba623e132d2abeab0635649f" - integrity sha512-NjM8H2AUpLjcf+3mKYd99VbFgN4kwT++IBmR9BRQkqOZ4fD63g8jLPzC0KTsWGIVkZtR9Qc88YW/5sC8C3SVFQ== - dependencies: - "@angular-devkit/architect" "0.1002.3" - "@angular-devkit/build-optimizer" "0.1002.3" - "@angular-devkit/build-webpack" "0.1002.3" - "@angular-devkit/core" "10.2.3" - "@babel/core" "7.11.1" - "@babel/generator" "7.11.0" - "@babel/plugin-transform-runtime" "7.11.0" - "@babel/preset-env" "7.11.0" - "@babel/runtime" "7.11.2" - "@babel/template" "7.10.4" +"@angular-devkit/architect@0.1102.12": + version "0.1102.12" + resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.1102.12.tgz#ef03c39ccce8969a36a4844cf796ecf48f579cbc" + integrity sha512-6qnI3NXpHzSlNG6jSLNdQazx7SILSpE3YD9l9n0tjHF3yeFnzPuVVWbQSjI9Us5EQi86lVGT3mTJbivRRRUYUQ== + dependencies: + "@angular-devkit/core" "11.2.12" + rxjs "6.6.3" + +"@angular-devkit/build-angular@~0.1102.12": + version "0.1102.12" + resolved "https://registry.yarnpkg.com/@angular-devkit/build-angular/-/build-angular-0.1102.12.tgz#c540f9352a61cd50b725e5aa2a36db39860e00c1" + integrity sha512-mX8UqIR+Ev6p37zXLtZghdCNta3Pi5bG6o0PCXUGcDRY63kp2jiWH0RgvoBjJBlAt358tIO9GEkR8kuqZt8x4w== + dependencies: + "@angular-devkit/architect" "0.1102.12" + "@angular-devkit/build-optimizer" "0.1102.12" + "@angular-devkit/build-webpack" "0.1102.12" + "@angular-devkit/core" "11.2.12" + "@babel/core" "7.12.10" + "@babel/generator" "7.12.11" + "@babel/plugin-transform-async-to-generator" "7.12.1" + "@babel/plugin-transform-runtime" "7.12.10" + "@babel/preset-env" "7.12.11" + "@babel/runtime" "7.12.5" + "@babel/template" "7.12.7" + "@discoveryjs/json-ext" "0.5.2" "@jsdevtools/coverage-istanbul-loader" "3.0.5" - "@ngtools/webpack" "10.2.3" - autoprefixer "9.8.6" - babel-loader "8.1.0" + "@ngtools/webpack" "11.2.12" + ansi-colors "4.1.1" + autoprefixer "10.2.4" + babel-loader "8.2.2" browserslist "^4.9.1" cacache "15.0.5" caniuse-lite "^1.0.30001032" - circular-dependency-plugin "5.2.0" - copy-webpack-plugin "6.0.3" - core-js "3.6.4" - css-loader "4.2.2" - cssnano "4.1.10" - file-loader "6.0.0" + circular-dependency-plugin "5.2.2" + copy-webpack-plugin "6.3.2" + core-js "3.8.3" + critters "0.0.7" + css-loader "5.0.1" + cssnano "5.0.1" + file-loader "6.2.0" find-cache-dir "3.3.1" glob "7.1.6" - jest-worker "26.3.0" + https-proxy-agent "5.0.0" + inquirer "7.3.3" + jest-worker "26.6.2" karma-source-map-support "1.4.0" - less-loader "6.2.0" - license-webpack-plugin "2.3.0" + less "4.1.1" + less-loader "7.3.0" + license-webpack-plugin "2.3.11" loader-utils "2.0.0" - mini-css-extract-plugin "0.10.0" + mini-css-extract-plugin "1.3.5" minimatch "3.0.4" - open "7.2.0" - parse5 "6.0.1" - parse5-htmlparser2-tree-adapter "6.0.1" + open "7.4.0" + ora "5.3.0" + parse5-html-rewriting-stream "6.0.1" pnp-webpack-plugin "1.6.4" - postcss "7.0.32" - postcss-import "12.0.1" - postcss-loader "3.0.0" - raw-loader "4.0.1" + postcss "8.2.13" + postcss-import "14.0.0" + postcss-loader "4.2.0" + raw-loader "4.0.2" regenerator-runtime "0.13.7" resolve-url-loader "3.1.2" rimraf "3.0.2" - rollup "2.26.5" - rxjs "6.6.2" - sass "1.26.10" - sass-loader "10.0.1" - semver "7.3.2" + rollup "2.38.4" + rxjs "6.6.3" + sass "1.32.6" + sass-loader "10.1.1" + semver "7.3.4" source-map "0.7.3" - source-map-loader "1.0.2" + source-map-loader "1.1.3" source-map-support "0.5.19" - speed-measure-webpack-plugin "1.3.3" - style-loader "1.2.1" + speed-measure-webpack-plugin "1.4.2" + style-loader "2.0.0" stylus "0.54.8" - stylus-loader "3.0.2" - terser "5.3.0" - terser-webpack-plugin "4.1.0" + stylus-loader "4.3.3" + terser "5.5.1" + terser-webpack-plugin "4.2.3" + text-table "0.2.0" tree-kill "1.2.2" - webpack "4.44.1" + webpack "4.44.2" webpack-dev-middleware "3.7.2" - webpack-dev-server "3.11.0" - webpack-merge "4.2.2" - webpack-sources "1.4.3" - webpack-subresource-integrity "1.4.1" + webpack-dev-server "3.11.2" + webpack-merge "5.7.3" + webpack-sources "2.2.0" + webpack-subresource-integrity "1.5.2" worker-plugin "5.0.0" -"@angular-devkit/build-optimizer@0.1002.3": - version "0.1002.3" - resolved "https://registry.yarnpkg.com/@angular-devkit/build-optimizer/-/build-optimizer-0.1002.3.tgz#797822cdde3e0e9892670ac515c6f4a7caa0854b" - integrity sha512-/0KbxVmmvt3S7ghk5zUH8/PWjW8ki0uSmPsnjopY8jRgAxuXN/7PXZbqswItNlUBoEj34hj2UADBUJVic7fcnQ== +"@angular-devkit/build-optimizer@0.1102.12": + version "0.1102.12" + resolved "https://registry.yarnpkg.com/@angular-devkit/build-optimizer/-/build-optimizer-0.1102.12.tgz#4d5c164ba7152db223ddcecdbb5a270a73b5cc14" + integrity sha512-4aQ4t7iDagrsNrF5JDS3bZw+uIn4z0llyau7GQQwZm1OmpRcl33hXOIHSFUJoRPP6pI5liNVuffF3lrAoC6sZA== dependencies: loader-utils "2.0.0" source-map "0.7.3" - tslib "2.0.1" - typescript "4.0.2" - webpack-sources "1.4.3" + tslib "2.1.0" + typescript "4.1.5" + webpack-sources "2.2.0" -"@angular-devkit/build-webpack@0.1002.3": - version "0.1002.3" - resolved "https://registry.yarnpkg.com/@angular-devkit/build-webpack/-/build-webpack-0.1002.3.tgz#763ae9c4c4b0854679e7bf1b4d0f467dd2b31c61" - integrity sha512-ngvPPA3VuYGYV275PM6X0pVI0Nl/uWx4eu2S6SUFe6mniN4BQkUHAyeCUMIbM3hkau/NAcF9xUs5AvZ9GDpvPw== +"@angular-devkit/build-webpack@0.1102.12": + version "0.1102.12" + resolved "https://registry.yarnpkg.com/@angular-devkit/build-webpack/-/build-webpack-0.1102.12.tgz#589936b611b919f276bf6ecbb4c30090fb30daa7" + integrity sha512-AoqnveSLhkQznI3SBX7/uoOEs93EOi8/u1sdOU8QBicM53n/IcUPIjilwHL+CY8J0YKcxg4ESsN3LAFQCzYT6g== dependencies: - "@angular-devkit/architect" "0.1002.3" - "@angular-devkit/core" "10.2.3" - rxjs "6.6.2" + "@angular-devkit/architect" "0.1102.12" + "@angular-devkit/core" "11.2.12" + rxjs "6.6.3" -"@angular-devkit/core@10.2.3": - version "10.2.3" - resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-10.2.3.tgz#499978929e58532f6f0caab8bd860c882d926eea" - integrity sha512-pMM1v9Xjqx6YLOQxQYs0D+03H6XPDZLS8cyEtoQX2iYdh8qlKHZVbJa2WsfzwMoIPtgcXfQAXn113VEgrQPLFA== +"@angular-devkit/core@11.2.12": + version "11.2.12" + resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-11.2.12.tgz#b80843d2ff9ac934ae4f31ed22dbc1d4b803bd95" + integrity sha512-VMRMmRj6ZX32cWpuA6vD4KSmji17yC4EtbXsiqrHZ8zAho4ifu8xImCC5PugTQnHa+RlIadOXwXX89aujUEwRw== dependencies: - ajv "6.12.4" + ajv "6.12.6" fast-json-stable-stringify "2.1.0" magic-string "0.25.7" - rxjs "6.6.2" + rxjs "6.6.3" source-map "0.7.3" -"@angular-devkit/schematics@10.2.3": - version "10.2.3" - resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-10.2.3.tgz#1f384eb9db6f02e3e867e442e3569628e0eb6de5" - integrity sha512-uCNeq5qH4QEiftgOud+EhTVvdriYQVBrYmX4f4BjVHkjnFhm73h30nfAgs6YuStIp8oxSI8jUGE9DAy331xvmA== +"@angular-devkit/schematics@11.2.12": + version "11.2.12" + resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-11.2.12.tgz#a2b7b02f6677a2fa9f4f6716f0aaa87347d41509" + integrity sha512-d1fxxkLPtP87iwAFZ0iUNWMlqULm05bbnRc5g5vrFxdtpwwybC15+NS64d3gzX0vAvnCa+cDQkjeD92bJJNjLw== + dependencies: + "@angular-devkit/core" "11.2.12" + ora "5.3.0" + rxjs "6.6.3" + +"@angular-eslint/builder@4.2.0": + version "4.2.0" + resolved "https://registry.yarnpkg.com/@angular-eslint/builder/-/builder-4.2.0.tgz#3a00adf8384cdc983c73e959e919486c0d1175d9" + integrity sha512-qM4hpweuQ14ul8CU6LKpUWFZs6POUE7HZKdTllUrYuoZMrTpNB1XGelR0pweYzbfo4XRnUaO1NVgWhWOWiD5MA== + +"@angular-eslint/eslint-plugin-template@4.2.0": + version "4.2.0" + resolved "https://registry.yarnpkg.com/@angular-eslint/eslint-plugin-template/-/eslint-plugin-template-4.2.0.tgz#2716583530bf2b20069076994816630e299ab67c" + integrity sha512-LC8qqqqVmA/OJAsUt6fQCXLmWP5BL30XFvVsPtrORdxMFt0HI1gvkuz5EVak7PeAXEmerdVarNZr5zmCXIWf3g== + dependencies: + "@typescript-eslint/experimental-utils" "4.16.1" + aria-query "^4.2.2" + axobject-query "^2.2.0" + +"@angular-eslint/eslint-plugin@4.2.0": + version "4.2.0" + resolved "https://registry.yarnpkg.com/@angular-eslint/eslint-plugin/-/eslint-plugin-4.2.0.tgz#134203c3ac340ae4ae76703434f636dc0a110d7d" + integrity sha512-G8D8Pso6GcHW8vFkUSvgoKPIOtGTqO+eb5aytGtpogMgzxBRyr0juU/9Uz5dAhO6TOERIj1gPpJQ61R/n/Aaew== + dependencies: + "@typescript-eslint/experimental-utils" "4.16.1" + +"@angular-eslint/schematics@4.2.0": + version "4.2.0" + resolved "https://registry.yarnpkg.com/@angular-eslint/schematics/-/schematics-4.2.0.tgz#28bb9c67f0cc6c03219cf92220f74c171a613897" + integrity sha512-aohGcfYUqN2hFLWaZoOqkLDyYVDFoLC3LwgIknoaDqWkvFG/RUTg1X1pCFjddLQYP5ist8+OppHH+gnYMbftEw== + dependencies: + "@angular-eslint/eslint-plugin" "4.2.0" + "@angular-eslint/eslint-plugin-template" "4.2.0" + ignore "5.1.8" + strip-json-comments "3.1.1" + tmp "0.2.1" + +"@angular-eslint/template-parser@4.2.0": + version "4.2.0" + resolved "https://registry.yarnpkg.com/@angular-eslint/template-parser/-/template-parser-4.2.0.tgz#02f98c72692880b81cd6b4cc137306b346c0b193" + integrity sha512-77lJ9MDNWmW4ik9l3g149iO9SGRx3qLGZvfSTwmbPxpCgNripWerla9Ia1X+gLkitI8CLpcpiZybxH3EWxj/qQ== dependencies: - "@angular-devkit/core" "10.2.3" - ora "5.0.0" - rxjs "6.6.2" + eslint-scope "^5.1.0" -"@angular/animations@~10.2.0": - version "10.2.5" - resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-10.2.5.tgz#9b4aaa2a2f88f848decb5a03f2ddaa2aed37642d" - integrity sha512-lIMwjY1pAqpCM4Ayndf2RsvOWRUc5QV7W82XNou6pIBv2T1i1XV6H72I5Sk9Z4sxxBYCWncEaEub+C6NcS8QRg== +"@angular/animations@~11.2.13": + version "11.2.13" + resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-11.2.13.tgz#f2020f129a0aa2fef2e2d82a7c728e7202d049d8" + integrity sha512-+TcJbMmKZI4kbSLp7TCJzOYkm90qe54OLWcNH6bi2NC9S0QsXaPo73yRP8sERjg/DjRj+wBf3LY63FvHZmqcTA== dependencies: tslib "^2.0.0" -"@angular/cli@~10.2.0": - version "10.2.3" - resolved "https://registry.yarnpkg.com/@angular/cli/-/cli-10.2.3.tgz#71f0b84f40197a3aa28b0d5f3bbff2354c127d1b" - integrity sha512-LLt0AUgLpmaoWA1R7tnUxbJDNs37+WogjNCbNLfvf4YHI04PwKx3OXgx0d8IYNtjHEaGmGp9AQRynvQ2qfXkaA== +"@angular/cli@~11.2.12": + version "11.2.12" + resolved "https://registry.yarnpkg.com/@angular/cli/-/cli-11.2.12.tgz#f5162667f5f3b950440f202645a26d870d5a3570" + integrity sha512-4VkHfHO4QuTkGFw5Tx7khZxsNHp60VKk8JzmPF6KIjkrDUVWVNwKOFOnJtbz9cXvayiUNNSEWqo9Oq3513zz4g== dependencies: - "@angular-devkit/architect" "0.1002.3" - "@angular-devkit/core" "10.2.3" - "@angular-devkit/schematics" "10.2.3" - "@schematics/angular" "10.2.3" - "@schematics/update" "0.1002.3" + "@angular-devkit/architect" "0.1102.12" + "@angular-devkit/core" "11.2.12" + "@angular-devkit/schematics" "11.2.12" + "@schematics/angular" "11.2.12" + "@schematics/update" "0.1102.12" "@yarnpkg/lockfile" "1.1.0" ansi-colors "4.1.1" - debug "4.1.1" - ini "1.3.6" + debug "4.3.1" + ini "2.0.0" inquirer "7.3.3" - npm-package-arg "8.0.1" + jsonc-parser "3.0.0" + npm-package-arg "8.1.0" npm-pick-manifest "6.1.0" - open "7.2.0" - pacote "9.5.12" - read-package-tree "5.3.1" + open "7.4.0" + ora "5.3.0" + pacote "11.2.4" + resolve "1.19.0" rimraf "3.0.2" - semver "7.3.2" - symbol-observable "1.2.0" + semver "7.3.4" + symbol-observable "3.0.0" universal-analytics "0.4.23" - uuid "8.3.0" + uuid "8.3.2" -"@angular/common@~10.2.0": - version "10.2.5" - resolved "https://registry.yarnpkg.com/@angular/common/-/common-10.2.5.tgz#5313f530446998e2f7af2dc43611addcfa6fd1c1" - integrity sha512-553yf6ZUHNqT4XpOqbW7EKKMfX56u/8DkwYXuSv8MAKdl4/AW6gliFOEJGYo04JcKF7Knq3VPvGSCO9kupf0hg== +"@angular/common@~11.2.13": + version "11.2.13" + resolved "https://registry.yarnpkg.com/@angular/common/-/common-11.2.13.tgz#fedd5eda9c2c5340d8d7310bdbd4606636eb7a41" + integrity sha512-96iZ4wlZado78yG6eY/ZmY6+H2X2hJi2XsK7iXKzc5h3oeILEkt+ulfBNkCNjMm8xPYBmLrSBueG96/T4/Bi5w== dependencies: tslib "^2.0.0" -"@angular/compiler-cli@~10.2.0": - version "10.2.5" - resolved "https://registry.yarnpkg.com/@angular/compiler-cli/-/compiler-cli-10.2.5.tgz#adb65bb9ecea14762a501226fde7760b73c3ab1e" - integrity sha512-xddSpKudoPidEebIW3x1CvQdx69WEmnFg4DneeQi/tit7mtAKYTJemzYZmP6abdSYhtxovL0bPX5LxYlrtuxIw== +"@angular/compiler-cli@~11.2.13": + version "11.2.13" + resolved "https://registry.yarnpkg.com/@angular/compiler-cli/-/compiler-cli-11.2.13.tgz#7e624ff5fb78c5427c8001e920946973d77ce71e" + integrity sha512-AaIip0gdeNTcXAhxsGAudybdmaSwQ0BoxsdPIZRb9jokHAP4pCKx9aFJFbvTHB99kbKV7zEmGMCbsoRkRhxnJw== dependencies: + "@babel/core" "^7.8.6" + "@babel/types" "^7.8.6" canonical-path "1.0.0" chokidar "^3.0.0" convert-source-map "^1.5.1" @@ -178,59 +229,66 @@ source-map "^0.6.1" sourcemap-codec "^1.4.8" tslib "^2.0.0" - yargs "^16.1.1" + yargs "^16.2.0" -"@angular/compiler@~10.2.0": - version "10.2.5" - resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-10.2.5.tgz#1ff8514fdd2c07ff3c265b960dc49af6376071c9" - integrity sha512-ddJiTPCoVBIGjFDYoYWDpmq3Zs8UKoWpzaeW4u+p17gWW54HwyT5XTxrgtbeUmaxIuRdL4/KT1lGHs9/9bwbCA== +"@angular/compiler@~11.2.13": + version "11.2.13" + resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-11.2.13.tgz#3f41c1a18b62959db3a314b1a809ace607a68c81" + integrity sha512-HI7gfVozFW/rQoab0zVyYpU8PRHNWMk+pLc+q3ukVuByCmnBZ6kTAEQX2jnXVY8QGMmdptBgrsW/OsFaws98Zw== dependencies: tslib "^2.0.0" -"@angular/core@~10.2.0": - version "10.2.5" - resolved "https://registry.yarnpkg.com/@angular/core/-/core-10.2.5.tgz#2050b0dbb180aa98c2ec46bba6d4827565ba2a2d" - integrity sha512-krhOKNTj5XE92Rk9ASX5KmgTF72j7qT2PLVxrGEVjuUKjBY2XaK3TV0Kotq9zI3qa9WgeCrP/Njn6jlKQCCAEQ== +"@angular/core@~11.2.13": + version "11.2.13" + resolved "https://registry.yarnpkg.com/@angular/core/-/core-11.2.13.tgz#34649d2c5fee416192e90a4187233b338e3d354d" + integrity sha512-xMKskq/Sbf8dkX/vx4WCwXMpDTJJ77rGlP8fVTB8az8QeOa14i6AdpmSXaJ8sl68R3v8Y1Pa9yBQytbKuxShqQ== dependencies: tslib "^2.0.0" -"@angular/forms@~10.2.0": - version "10.2.5" - resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-10.2.5.tgz#12bb297118d22be351fba7176d213bb5aad2932d" - integrity sha512-EnycBx8q+DGmPaX4oSjPejJxx9u0TLb5+tpGxYitdOq/eBpQAAYyWKQGKXb1JB46rPVwJr34MmTltHgAN0zUSQ== +"@angular/forms@~11.2.13": + version "11.2.13" + resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-11.2.13.tgz#9cfe516d7186e4d6e75b8729910c23b7a3833aeb" + integrity sha512-Q5vNHycS+II2xYOE/HJB4NoYg/Ngg6hPF+0KXdCA7L4kfrwx5Fsi4oZ6gRRnSpzSGedISpSU4VE5wPiq7zJ3+A== dependencies: tslib "^2.0.0" -"@angular/platform-browser-dynamic@~10.2.0": - version "10.2.5" - resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-10.2.5.tgz#c9eea9e076a9fc8f80d7c041ba9766465613bb96" - integrity sha512-7z443I80K2CeqzczlSJ8BlABj0uRgnHUrABE8yLlU2BgifJrriBawzSXEV7UMEN7k7ezbc6NhpOn6Q6BrCKEOA== +"@angular/platform-browser-dynamic@~11.2.13": + version "11.2.13" + resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-11.2.13.tgz#95e8390da4005cda594643a55cb7a80a41784059" + integrity sha512-EHCG8fhnurhHUq+XKyKL3bYEcQThRYyzIJTJig28ulgvQd4TAKAbw8osL9rpjNUnCM1HjDXOqnCcPnsQIPIzMg== dependencies: tslib "^2.0.0" -"@angular/platform-browser@~10.2.0": - version "10.2.5" - resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-10.2.5.tgz#40dd88c937af7af56e3fb246608c7001e4ac09c7" - integrity sha512-3JDFRGNxr0IUkjSdGK2Q1BvqnSDpy9YWo0DJP+TEpgW578R84m4X7/wI3jJmFSC2yyouMWrHsot2vcBPAQj89g== +"@angular/platform-browser@~11.2.13": + version "11.2.13" + resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-11.2.13.tgz#39bea0d6f9e7803f22082d3c8f0fb7ed4b68c43d" + integrity sha512-V70Pf3jJPbeXsiy9mtVMctVBIIoqiDhsoI+6lCehf/LaJR33oUizj+RS1wlpgOECIj9oD5EqzdvxEukR0PpnoQ== dependencies: tslib "^2.0.0" -"@angular/platform-server@~10.2.0": - version "10.2.5" - resolved "https://registry.yarnpkg.com/@angular/platform-server/-/platform-server-10.2.5.tgz#c4f7dee6c2986f37f48c423ca84d59cb79ed108f" - integrity sha512-T8DDvSp9s6iNQ9UE+ELsoeNUWqMkAl2LcChTYvJsqTEo4pbN/8m9JItN4Trc8nzfkWFEg8hPTAODGQKFHczNGw== +"@angular/platform-server@~11.2.13": + version "11.2.13" + resolved "https://registry.yarnpkg.com/@angular/platform-server/-/platform-server-11.2.13.tgz#e7552e3f429fb3f3506b4c45489aec9abf4d00e2" + integrity sha512-9WEIK0GHbbUwT9HNa2VCYLMrSxgsCMGkQ7XHQISLcVeHHb3yz/I0D0GRJfOVulpCOfwsgepQ/GJgeXMeuz2vTg== dependencies: domino "^2.1.2" tslib "^2.0.0" xhr2 "^0.2.0" -"@angular/router@~10.2.0": - version "10.2.5" - resolved "https://registry.yarnpkg.com/@angular/router/-/router-10.2.5.tgz#acc75a29ab0b54c8ebad7d2a896986a59d7d99ec" - integrity sha512-AtSMB/d4V+pw/FL4G/mWWoiJJtZ/075TqsGW7uEFKgxS6Gh2kalv6BTMlXVG5GO+2oU0lsuDvguq5E7Atbak3Q== +"@angular/router@~11.2.13": + version "11.2.13" + resolved "https://registry.yarnpkg.com/@angular/router/-/router-11.2.13.tgz#aab59dbc24f5be3ff6b5252e0bd8e57212d1604e" + integrity sha512-Fae/ViC4Ho2rGF5wQLrnJcucuhVGx29QqZs2K0C6sj4UUNRUzYWZknnGWqRj3Z9ft7XIi38Q2yCkSc76iS1aqQ== dependencies: tslib "^2.0.0" +"@babel/code-frame@7.12.11": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" + integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== + dependencies: + "@babel/highlight" "^7.10.4" + "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.13.tgz#dcfc826beef65e75c50e21d3837d7d95798dd658" @@ -238,34 +296,33 @@ dependencies: "@babel/highlight" "^7.12.13" -"@babel/compat-data@^7.11.0", "@babel/compat-data@^7.13.15", "@babel/compat-data@^7.13.8": +"@babel/compat-data@^7.12.7", "@babel/compat-data@^7.13.15", "@babel/compat-data@^7.13.8": version "7.14.0" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.14.0.tgz#a901128bce2ad02565df95e6ecbf195cf9465919" integrity sha512-vu9V3uMM/1o5Hl5OekMUowo3FqXLJSw+s+66nt0fSWVWTtmosdzn45JHOB3cPtZoe6CTBDzvSw0RdOY85Q37+Q== -"@babel/core@7.11.1": - version "7.11.1" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.11.1.tgz#2c55b604e73a40dc21b0e52650b11c65cf276643" - integrity sha512-XqF7F6FWQdKGGWAzGELL+aCO1p+lRY5Tj5/tbT3St1G8NaH70jhhDIKknIZaDans0OQBG5wRAldROLHSt44BgQ== +"@babel/core@7.12.10": + version "7.12.10" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.12.10.tgz#b79a2e1b9f70ed3d84bbfb6d8c4ef825f606bccd" + integrity sha512-eTAlQKq65zHfkHZV0sIVODCPGVgoo1HdBlbSLi9CqOzuZanMv2ihzY+4paiKr1mH+XmYESMAmJ/dpZ68eN6d8w== dependencies: "@babel/code-frame" "^7.10.4" - "@babel/generator" "^7.11.0" - "@babel/helper-module-transforms" "^7.11.0" - "@babel/helpers" "^7.10.4" - "@babel/parser" "^7.11.1" - "@babel/template" "^7.10.4" - "@babel/traverse" "^7.11.0" - "@babel/types" "^7.11.0" + "@babel/generator" "^7.12.10" + "@babel/helper-module-transforms" "^7.12.1" + "@babel/helpers" "^7.12.5" + "@babel/parser" "^7.12.10" + "@babel/template" "^7.12.7" + "@babel/traverse" "^7.12.10" + "@babel/types" "^7.12.10" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.1" json5 "^2.1.2" lodash "^4.17.19" - resolve "^1.3.2" semver "^5.4.1" source-map "^0.5.0" -"@babel/core@^7.7.5": +"@babel/core@^7.7.5", "@babel/core@^7.8.6": version "7.14.0" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.14.0.tgz#47299ff3ec8d111b493f1a9d04bf88c04e728d88" integrity sha512-8YqpRig5NmIHlMLw09zMlPTvUVMILjqCOtVgu+TVNWEBvy9b5I3RRyhqnrV4hjgEK7n8P9OqvkWJAFmEL6Wwfw== @@ -286,16 +343,16 @@ semver "^6.3.0" source-map "^0.5.0" -"@babel/generator@7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.11.0.tgz#4b90c78d8c12825024568cbe83ee6c9af193585c" - integrity sha512-fEm3Uzw7Mc9Xi//qU20cBKatTfs2aOtKqmvy/Vm7RkJEGFQ4xc9myCfbXxqK//ZS8MR/ciOHw6meGASJuKmDfQ== +"@babel/generator@7.12.11": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.12.11.tgz#98a7df7b8c358c9a37ab07a24056853016aba3af" + integrity sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA== dependencies: - "@babel/types" "^7.11.0" + "@babel/types" "^7.12.11" jsesc "^2.5.1" source-map "^0.5.0" -"@babel/generator@^7.11.0", "@babel/generator@^7.14.0": +"@babel/generator@^7.12.10", "@babel/generator@^7.14.0": version "7.14.1" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.14.1.tgz#1f99331babd65700183628da186f36f63d615c93" integrity sha512-TMGhsXMXCP/O1WtQmZjpEYDhCYC9vFhayWZPJSZCGkPJgUqX0rF0wwtrYvnzVxIjcF80tkUertXVk5cwqi5cAQ== @@ -319,7 +376,7 @@ "@babel/helper-explode-assignable-expression" "^7.12.13" "@babel/types" "^7.12.13" -"@babel/helper-compilation-targets@^7.10.4", "@babel/helper-compilation-targets@^7.13.16", "@babel/helper-compilation-targets@^7.13.8": +"@babel/helper-compilation-targets@^7.12.5", "@babel/helper-compilation-targets@^7.13.16", "@babel/helper-compilation-targets@^7.13.8": version "7.13.16" resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.16.tgz#6e91dccf15e3f43e5556dffe32d860109887563c" integrity sha512-3gmkYIrpqsLlieFwjkGgLaSHmhnvlAYzZLlYVjlW+QwI+1zE17kGxuJGmIqDQdYp56XdmGeD+Bswx0UTyG18xA== @@ -387,14 +444,14 @@ dependencies: "@babel/types" "^7.13.12" -"@babel/helper-module-imports@^7.10.4", "@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.13.12": +"@babel/helper-module-imports@^7.12.1", "@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.12.5", "@babel/helper-module-imports@^7.13.12": version "7.13.12" resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz#c6a369a6f3621cb25da014078684da9196b61977" integrity sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA== dependencies: "@babel/types" "^7.13.12" -"@babel/helper-module-transforms@^7.11.0", "@babel/helper-module-transforms@^7.13.0", "@babel/helper-module-transforms@^7.14.0": +"@babel/helper-module-transforms@^7.12.1", "@babel/helper-module-transforms@^7.13.0", "@babel/helper-module-transforms@^7.14.0": version "7.14.0" resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.14.0.tgz#8fcf78be220156f22633ee204ea81f73f826a8ad" integrity sha512-L40t9bxIuGOfpIGA3HNkJhU9qYrf4y5A5LUSw7rGMSn+pcG8dfJ0g6Zval6YJGd2nEjI7oP00fRdnhLKndx6bw== @@ -420,7 +477,7 @@ resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz#806526ce125aed03373bc416a828321e3a6a33af" integrity sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ== -"@babel/helper-remap-async-to-generator@^7.13.0": +"@babel/helper-remap-async-to-generator@^7.12.1", "@babel/helper-remap-async-to-generator@^7.13.0": version "7.13.0" resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.13.0.tgz#376a760d9f7b4b2077a9dd05aa9c3927cadb2209" integrity sha512-pUQpFBE9JvC9lrQbpX0TmeNIy5s7GnZjna2lhhcHC7DzgBs6fWn722Y5cfwgrtrqc7NAJwMvOa0mKhq6XaE4jg== @@ -465,7 +522,7 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz#d26cad8a47c65286b15df1547319a5d0bcf27288" integrity sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A== -"@babel/helper-validator-option@^7.12.17": +"@babel/helper-validator-option@^7.12.11", "@babel/helper-validator-option@^7.12.17": version "7.12.17" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz#d1fbf012e1a79b7eebbfdc6d270baaf8d9eb9831" integrity sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw== @@ -480,7 +537,7 @@ "@babel/traverse" "^7.13.0" "@babel/types" "^7.13.0" -"@babel/helpers@^7.10.4", "@babel/helpers@^7.14.0": +"@babel/helpers@^7.12.5", "@babel/helpers@^7.14.0": version "7.14.0" resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.14.0.tgz#ea9b6be9478a13d6f961dbb5f36bf75e2f3b8f62" integrity sha512-+ufuXprtQ1D1iZTO/K9+EBRn+qPWMJjZSw/S0KlFrxCw4tkrzv9grgpDHkY9MeQTjTY8i2sp7Jep8DfU6tN9Mg== @@ -489,7 +546,7 @@ "@babel/traverse" "^7.14.0" "@babel/types" "^7.14.0" -"@babel/highlight@^7.12.13": +"@babel/highlight@^7.10.4", "@babel/highlight@^7.12.13": version "7.14.0" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.0.tgz#3197e375711ef6bf834e67d0daec88e4f46113cf" integrity sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg== @@ -498,12 +555,12 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.10.4", "@babel/parser@^7.11.1", "@babel/parser@^7.12.13", "@babel/parser@^7.14.0": +"@babel/parser@^7.12.10", "@babel/parser@^7.12.13", "@babel/parser@^7.12.7", "@babel/parser@^7.14.0": version "7.14.1" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.1.tgz#1bd644b5db3f5797c4479d89ec1817fe02b84c47" integrity sha512-muUGEKu8E/ftMTPlNp+mc6zL3E9zKWmF5sDHZ5MSsoTP9Wyz64AhEf9kD08xYJ7w6Hdcu8H550ircnPyWSIF0Q== -"@babel/plugin-proposal-async-generator-functions@^7.10.4": +"@babel/plugin-proposal-async-generator-functions@^7.12.1": version "7.13.15" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.13.15.tgz#80e549df273a3b3050431b148c892491df1bcc5b" integrity sha512-VapibkWzFeoa6ubXy/NgV5U2U4MVnUlvnx6wo1XhlsaTrLYWE0UFpDQsVrmn22q5CzeloqJ8gEMHSKxuee6ZdA== @@ -512,7 +569,7 @@ "@babel/helper-remap-async-to-generator" "^7.13.0" "@babel/plugin-syntax-async-generators" "^7.8.4" -"@babel/plugin-proposal-class-properties@^7.10.4": +"@babel/plugin-proposal-class-properties@^7.12.1": version "7.13.0" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.13.0.tgz#146376000b94efd001e57a40a88a525afaab9f37" integrity sha512-KnTDjFNC1g+45ka0myZNvSBFLhNCLN+GeGYLDEA8Oq7MZ6yMgfLoIRh86GRT0FjtJhZw8JyUskP9uvj5pHM9Zg== @@ -520,7 +577,7 @@ "@babel/helper-create-class-features-plugin" "^7.13.0" "@babel/helper-plugin-utils" "^7.13.0" -"@babel/plugin-proposal-dynamic-import@^7.10.4": +"@babel/plugin-proposal-dynamic-import@^7.12.1": version "7.13.8" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.13.8.tgz#876a1f6966e1dec332e8c9451afda3bebcdf2e1d" integrity sha512-ONWKj0H6+wIRCkZi9zSbZtE/r73uOhMVHh256ys0UzfM7I3d4n+spZNWjOnJv2gzopumP2Wxi186vI8N0Y2JyQ== @@ -528,7 +585,7 @@ "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-syntax-dynamic-import" "^7.8.3" -"@babel/plugin-proposal-export-namespace-from@^7.10.4": +"@babel/plugin-proposal-export-namespace-from@^7.12.1": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.12.13.tgz#393be47a4acd03fa2af6e3cde9b06e33de1b446d" integrity sha512-INAgtFo4OnLN3Y/j0VwAgw3HDXcDtX+C/erMvWzuV9v71r7urb6iyMXu7eM9IgLr1ElLlOkaHjJ0SbCmdOQ3Iw== @@ -536,7 +593,7 @@ "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-syntax-export-namespace-from" "^7.8.3" -"@babel/plugin-proposal-json-strings@^7.10.4": +"@babel/plugin-proposal-json-strings@^7.12.1": version "7.13.8" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.13.8.tgz#bf1fb362547075afda3634ed31571c5901afef7b" integrity sha512-w4zOPKUFPX1mgvTmL/fcEqy34hrQ1CRcGxdphBc6snDnnqJ47EZDIyop6IwXzAC8G916hsIuXB2ZMBCExC5k7Q== @@ -544,7 +601,7 @@ "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-syntax-json-strings" "^7.8.3" -"@babel/plugin-proposal-logical-assignment-operators@^7.11.0": +"@babel/plugin-proposal-logical-assignment-operators@^7.12.1": version "7.13.8" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.13.8.tgz#93fa78d63857c40ce3c8c3315220fd00bfbb4e1a" integrity sha512-aul6znYB4N4HGweImqKn59Su9RS8lbUIqxtXTOcAGtNIDczoEFv+l1EhmX8rUBp3G1jMjKJm8m0jXVp63ZpS4A== @@ -552,7 +609,7 @@ "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" -"@babel/plugin-proposal-nullish-coalescing-operator@^7.10.4": +"@babel/plugin-proposal-nullish-coalescing-operator@^7.12.1": version "7.13.8" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.13.8.tgz#3730a31dafd3c10d8ccd10648ed80a2ac5472ef3" integrity sha512-iePlDPBn//UhxExyS9KyeYU7RM9WScAG+D3Hhno0PLJebAEpDZMocbDe64eqynhNAnwz/vZoL/q/QB2T1OH39A== @@ -560,7 +617,7 @@ "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" -"@babel/plugin-proposal-numeric-separator@^7.10.4": +"@babel/plugin-proposal-numeric-separator@^7.12.7": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.13.tgz#bd9da3188e787b5120b4f9d465a8261ce67ed1db" integrity sha512-O1jFia9R8BUCl3ZGB7eitaAPu62TXJRHn7rh+ojNERCFyqRwJMTmhz+tJ+k0CwI6CLjX/ee4qW74FSqlq9I35w== @@ -568,7 +625,7 @@ "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-syntax-numeric-separator" "^7.10.4" -"@babel/plugin-proposal-object-rest-spread@^7.11.0": +"@babel/plugin-proposal-object-rest-spread@^7.12.1": version "7.13.8" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.13.8.tgz#5d210a4d727d6ce3b18f9de82cc99a3964eed60a" integrity sha512-DhB2EuB1Ih7S3/IRX5AFVgZ16k3EzfRbq97CxAVI1KSYcW+lexV8VZb7G7L8zuPVSdQMRn0kiBpf/Yzu9ZKH0g== @@ -579,7 +636,7 @@ "@babel/plugin-syntax-object-rest-spread" "^7.8.3" "@babel/plugin-transform-parameters" "^7.13.0" -"@babel/plugin-proposal-optional-catch-binding@^7.10.4": +"@babel/plugin-proposal-optional-catch-binding@^7.12.1": version "7.13.8" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.13.8.tgz#3ad6bd5901506ea996fc31bdcf3ccfa2bed71107" integrity sha512-0wS/4DUF1CuTmGo+NiaHfHcVSeSLj5S3e6RivPTg/2k3wOv3jO35tZ6/ZWsQhQMvdgI7CwphjQa/ccarLymHVA== @@ -587,7 +644,7 @@ "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" -"@babel/plugin-proposal-optional-chaining@^7.11.0": +"@babel/plugin-proposal-optional-chaining@^7.12.7": version "7.13.12" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.13.12.tgz#ba9feb601d422e0adea6760c2bd6bbb7bfec4866" integrity sha512-fcEdKOkIB7Tf4IxrgEVeFC4zeJSTr78no9wTdBuZZbqF64kzllU0ybo2zrzm7gUQfxGhBgq4E39oRs8Zx/RMYQ== @@ -596,7 +653,7 @@ "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" "@babel/plugin-syntax-optional-chaining" "^7.8.3" -"@babel/plugin-proposal-private-methods@^7.10.4": +"@babel/plugin-proposal-private-methods@^7.12.1": version "7.13.0" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.13.0.tgz#04bd4c6d40f6e6bbfa2f57e2d8094bad900ef787" integrity sha512-MXyyKQd9inhx1kDYPkFRVOBXQ20ES8Pto3T7UZ92xj2mY0EVD8oAVzeyYuVfy/mxAdTSIayOvg+aVzcHV2bn6Q== @@ -604,7 +661,7 @@ "@babel/helper-create-class-features-plugin" "^7.13.0" "@babel/helper-plugin-utils" "^7.13.0" -"@babel/plugin-proposal-unicode-property-regex@^7.10.4", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": +"@babel/plugin-proposal-unicode-property-regex@^7.12.1", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.13.tgz#bebde51339be829c17aaaaced18641deb62b39ba" integrity sha512-XyJmZidNfofEkqFV5VC/bLabGmO5QzenPO/YOfGuEbgU+2sSwMmio3YLb4WtBgcmmdwZHyVyv8on77IUjQ5Gvg== @@ -619,7 +676,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-class-properties@^7.10.4": +"@babel/plugin-syntax-class-properties@^7.12.1": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== @@ -689,21 +746,30 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-top-level-await@^7.10.4": +"@babel/plugin-syntax-top-level-await@^7.12.1": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.13.tgz#c5f0fa6e249f5b739727f923540cf7a806130178" integrity sha512-A81F9pDwyS7yM//KwbCSDqy3Uj4NMIurtplxphWxoYtNPov7cJsDkAFNNyVlIZ3jwGycVsurZ+LtOA8gZ376iQ== dependencies: "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-arrow-functions@^7.10.4": +"@babel/plugin-transform-arrow-functions@^7.12.1": version "7.13.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.13.0.tgz#10a59bebad52d637a027afa692e8d5ceff5e3dae" integrity sha512-96lgJagobeVmazXFaDrbmCLQxBysKu7U6Do3mLsx27gf5Dk85ezysrs2BZUpXD703U/Su1xTBDxxar2oa4jAGg== dependencies: "@babel/helper-plugin-utils" "^7.13.0" -"@babel/plugin-transform-async-to-generator@^7.10.4": +"@babel/plugin-transform-async-to-generator@7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.12.1.tgz#3849a49cc2a22e9743cbd6b52926d30337229af1" + integrity sha512-SDtqoEcarK1DFlRJ1hHRY5HvJUj5kX4qmtpMAm2QnhOlyuMC4TMdCRgW6WXpv93rZeYNeLP22y8Aq2dbcDRM1A== + dependencies: + "@babel/helper-module-imports" "^7.12.1" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-remap-async-to-generator" "^7.12.1" + +"@babel/plugin-transform-async-to-generator@^7.12.1": version "7.13.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.13.0.tgz#8e112bf6771b82bf1e974e5e26806c5c99aa516f" integrity sha512-3j6E004Dx0K3eGmhxVJxwwI89CTJrce7lg3UrtFuDAVQ/2+SJ/h/aSFOeE6/n0WB1GsOffsJp6MnPQNQ8nmwhg== @@ -712,21 +778,21 @@ "@babel/helper-plugin-utils" "^7.13.0" "@babel/helper-remap-async-to-generator" "^7.13.0" -"@babel/plugin-transform-block-scoped-functions@^7.10.4": +"@babel/plugin-transform-block-scoped-functions@^7.12.1": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.13.tgz#a9bf1836f2a39b4eb6cf09967739de29ea4bf4c4" integrity sha512-zNyFqbc3kI/fVpqwfqkg6RvBgFpC4J18aKKMmv7KdQ/1GgREapSJAykLMVNwfRGO3BtHj3YQZl8kxCXPcVMVeg== dependencies: "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-block-scoping@^7.10.4": +"@babel/plugin-transform-block-scoping@^7.12.11": version "7.14.1" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.14.1.tgz#ac1b3a8e3d8cbb31efc6b9be2f74eb9823b74ab2" integrity sha512-2mQXd0zBrwfp0O1moWIhPpEeTKDvxyHcnma3JATVP1l+CctWBuot6OJG8LQ4DnBj4ZZPSmlb/fm4mu47EOAnVA== dependencies: "@babel/helper-plugin-utils" "^7.13.0" -"@babel/plugin-transform-classes@^7.10.4": +"@babel/plugin-transform-classes@^7.12.1": version "7.13.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.13.0.tgz#0265155075c42918bf4d3a4053134176ad9b533b" integrity sha512-9BtHCPUARyVH1oXGcSJD3YpsqRLROJx5ZNP6tN5vnk17N0SVf9WCtf8Nuh1CFmgByKKAIMstitKduoCmsaDK5g== @@ -739,21 +805,21 @@ "@babel/helper-split-export-declaration" "^7.12.13" globals "^11.1.0" -"@babel/plugin-transform-computed-properties@^7.10.4": +"@babel/plugin-transform-computed-properties@^7.12.1": version "7.13.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.13.0.tgz#845c6e8b9bb55376b1fa0b92ef0bdc8ea06644ed" integrity sha512-RRqTYTeZkZAz8WbieLTvKUEUxZlUTdmL5KGMyZj7FnMfLNKV4+r5549aORG/mgojRmFlQMJDUupwAMiF2Q7OUg== dependencies: "@babel/helper-plugin-utils" "^7.13.0" -"@babel/plugin-transform-destructuring@^7.10.4": +"@babel/plugin-transform-destructuring@^7.12.1": version "7.13.17" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.13.17.tgz#678d96576638c19d5b36b332504d3fd6e06dea27" integrity sha512-UAUqiLv+uRLO+xuBKKMEpC+t7YRNVRqBsWWq1yKXbBZBje/t3IXCiSinZhjn/DC3qzBfICeYd2EFGEbHsh5RLA== dependencies: "@babel/helper-plugin-utils" "^7.13.0" -"@babel/plugin-transform-dotall-regex@^7.10.4", "@babel/plugin-transform-dotall-regex@^7.4.4": +"@babel/plugin-transform-dotall-regex@^7.12.1", "@babel/plugin-transform-dotall-regex@^7.4.4": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.13.tgz#3f1601cc29905bfcb67f53910f197aeafebb25ad" integrity sha512-foDrozE65ZFdUC2OfgeOCrEPTxdB3yjqxpXh8CH+ipd9CHd4s/iq81kcUpyH8ACGNEPdFqbtzfgzbT/ZGlbDeQ== @@ -761,14 +827,14 @@ "@babel/helper-create-regexp-features-plugin" "^7.12.13" "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-duplicate-keys@^7.10.4": +"@babel/plugin-transform-duplicate-keys@^7.12.1": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.12.13.tgz#6f06b87a8b803fd928e54b81c258f0a0033904de" integrity sha512-NfADJiiHdhLBW3pulJlJI2NB0t4cci4WTZ8FtdIuNc2+8pslXdPtRRAEWqUY+m9kNOk2eRYbTAOipAxlrOcwwQ== dependencies: "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-exponentiation-operator@^7.10.4": +"@babel/plugin-transform-exponentiation-operator@^7.12.1": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.13.tgz#4d52390b9a273e651e4aba6aee49ef40e80cd0a1" integrity sha512-fbUelkM1apvqez/yYx1/oICVnGo2KM5s63mhGylrmXUxK/IAXSIf87QIxVfZldWf4QsOafY6vV3bX8aMHSvNrA== @@ -776,14 +842,14 @@ "@babel/helper-builder-binary-assignment-operator-visitor" "^7.12.13" "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-for-of@^7.10.4": +"@babel/plugin-transform-for-of@^7.12.1": version "7.13.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.13.0.tgz#c799f881a8091ac26b54867a845c3e97d2696062" integrity sha512-IHKT00mwUVYE0zzbkDgNRP6SRzvfGCYsOxIRz8KsiaaHCcT9BWIkO+H9QRJseHBLOGBZkHUdHiqj6r0POsdytg== dependencies: "@babel/helper-plugin-utils" "^7.13.0" -"@babel/plugin-transform-function-name@^7.10.4": +"@babel/plugin-transform-function-name@^7.12.1": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.13.tgz#bb024452f9aaed861d374c8e7a24252ce3a50051" integrity sha512-6K7gZycG0cmIwwF7uMK/ZqeCikCGVBdyP2J5SKNCXO5EOHcqi+z7Jwf8AmyDNcBgxET8DrEtCt/mPKPyAzXyqQ== @@ -791,21 +857,21 @@ "@babel/helper-function-name" "^7.12.13" "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-literals@^7.10.4": +"@babel/plugin-transform-literals@^7.12.1": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.13.tgz#2ca45bafe4a820197cf315794a4d26560fe4bdb9" integrity sha512-FW+WPjSR7hiUxMcKqyNjP05tQ2kmBCdpEpZHY1ARm96tGQCCBvXKnpjILtDplUnJ/eHZ0lALLM+d2lMFSpYJrQ== dependencies: "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-member-expression-literals@^7.10.4": +"@babel/plugin-transform-member-expression-literals@^7.12.1": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.13.tgz#5ffa66cd59b9e191314c9f1f803b938e8c081e40" integrity sha512-kxLkOsg8yir4YeEPHLuO2tXP9R/gTjpuTOjshqSpELUN3ZAg2jfDnKUvzzJxObun38sw3wm4Uu69sX/zA7iRvg== dependencies: "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-modules-amd@^7.10.4": +"@babel/plugin-transform-modules-amd@^7.12.1": version "7.14.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.14.0.tgz#589494b5b290ff76cf7f59c798011f6d77026553" integrity sha512-CF4c5LX4LQ03LebQxJ5JZes2OYjzBuk1TdiF7cG7d5dK4lAdw9NZmaxq5K/mouUdNeqwz3TNjnW6v01UqUNgpQ== @@ -814,7 +880,7 @@ "@babel/helper-plugin-utils" "^7.13.0" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-commonjs@^7.10.4": +"@babel/plugin-transform-modules-commonjs@^7.12.1": version "7.14.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.14.0.tgz#52bc199cb581e0992edba0f0f80356467587f161" integrity sha512-EX4QePlsTaRZQmw9BsoPeyh5OCtRGIhwfLquhxGp5e32w+dyL8htOcDwamlitmNFK6xBZYlygjdye9dbd9rUlQ== @@ -824,7 +890,7 @@ "@babel/helper-simple-access" "^7.13.12" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-systemjs@^7.10.4": +"@babel/plugin-transform-modules-systemjs@^7.12.1": version "7.13.8" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.13.8.tgz#6d066ee2bff3c7b3d60bf28dec169ad993831ae3" integrity sha512-hwqctPYjhM6cWvVIlOIe27jCIBgHCsdH2xCJVAYQm7V5yTMoilbVMi9f6wKg0rpQAOn6ZG4AOyvCqFF/hUh6+A== @@ -835,7 +901,7 @@ "@babel/helper-validator-identifier" "^7.12.11" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-umd@^7.10.4": +"@babel/plugin-transform-modules-umd@^7.12.1": version "7.14.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.14.0.tgz#2f8179d1bbc9263665ce4a65f305526b2ea8ac34" integrity sha512-nPZdnWtXXeY7I87UZr9VlsWme3Y0cfFFE41Wbxz4bbaexAjNMInXPFUpRRUJ8NoMm0Cw+zxbqjdPmLhcjfazMw== @@ -843,21 +909,21 @@ "@babel/helper-module-transforms" "^7.14.0" "@babel/helper-plugin-utils" "^7.13.0" -"@babel/plugin-transform-named-capturing-groups-regex@^7.10.4": +"@babel/plugin-transform-named-capturing-groups-regex@^7.12.1": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.13.tgz#2213725a5f5bbbe364b50c3ba5998c9599c5c9d9" integrity sha512-Xsm8P2hr5hAxyYblrfACXpQKdQbx4m2df9/ZZSQ8MAhsadw06+jW7s9zsSw6he+mJZXRlVMyEnVktJo4zjk1WA== dependencies: "@babel/helper-create-regexp-features-plugin" "^7.12.13" -"@babel/plugin-transform-new-target@^7.10.4": +"@babel/plugin-transform-new-target@^7.12.1": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.13.tgz#e22d8c3af24b150dd528cbd6e685e799bf1c351c" integrity sha512-/KY2hbLxrG5GTQ9zzZSc3xWiOy379pIETEhbtzwZcw9rvuaVV4Fqy7BYGYOWZnaoXIQYbbJ0ziXLa/sKcGCYEQ== dependencies: "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-object-super@^7.10.4": +"@babel/plugin-transform-object-super@^7.12.1": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.13.tgz#b4416a2d63b8f7be314f3d349bd55a9c1b5171f7" integrity sha512-JzYIcj3XtYspZDV8j9ulnoMPZZnF/Cj0LUxPOjR89BdBVx+zYJI9MdMIlUZjbXDX+6YVeS6I3e8op+qQ3BYBoQ== @@ -865,52 +931,51 @@ "@babel/helper-plugin-utils" "^7.12.13" "@babel/helper-replace-supers" "^7.12.13" -"@babel/plugin-transform-parameters@^7.10.4", "@babel/plugin-transform-parameters@^7.13.0": +"@babel/plugin-transform-parameters@^7.12.1", "@babel/plugin-transform-parameters@^7.13.0": version "7.13.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.13.0.tgz#8fa7603e3097f9c0b7ca1a4821bc2fb52e9e5007" integrity sha512-Jt8k/h/mIwE2JFEOb3lURoY5C85ETcYPnbuAJ96zRBzh1XHtQZfs62ChZ6EP22QlC8c7Xqr9q+e1SU5qttwwjw== dependencies: "@babel/helper-plugin-utils" "^7.13.0" -"@babel/plugin-transform-property-literals@^7.10.4": +"@babel/plugin-transform-property-literals@^7.12.1": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.13.tgz#4e6a9e37864d8f1b3bc0e2dce7bf8857db8b1a81" integrity sha512-nqVigwVan+lR+g8Fj8Exl0UQX2kymtjcWfMOYM1vTYEKujeyv2SkMgazf2qNcK7l4SDiKyTA/nHCPqL4e2zo1A== dependencies: "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-regenerator@^7.10.4": +"@babel/plugin-transform-regenerator@^7.12.1": version "7.13.15" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.13.15.tgz#e5eb28945bf8b6563e7f818945f966a8d2997f39" integrity sha512-Bk9cOLSz8DiurcMETZ8E2YtIVJbFCPGW28DJWUakmyVWtQSm6Wsf0p4B4BfEr/eL2Nkhe/CICiUiMOCi1TPhuQ== dependencies: regenerator-transform "^0.14.2" -"@babel/plugin-transform-reserved-words@^7.10.4": +"@babel/plugin-transform-reserved-words@^7.12.1": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.12.13.tgz#7d9988d4f06e0fe697ea1d9803188aa18b472695" integrity sha512-xhUPzDXxZN1QfiOy/I5tyye+TRz6lA7z6xaT4CLOjPRMVg1ldRf0LHw0TDBpYL4vG78556WuHdyO9oi5UmzZBg== dependencies: "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-runtime@7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.11.0.tgz#e27f78eb36f19448636e05c33c90fd9ad9b8bccf" - integrity sha512-LFEsP+t3wkYBlis8w6/kmnd6Kb1dxTd+wGJ8MlxTGzQo//ehtqlVL4S9DNUa53+dtPSQobN2CXx4d81FqC58cw== +"@babel/plugin-transform-runtime@7.12.10": + version "7.12.10" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.12.10.tgz#af0fded4e846c4b37078e8e5d06deac6cd848562" + integrity sha512-xOrUfzPxw7+WDm9igMgQCbO3cJKymX7dFdsgRr1eu9n3KjjyU4pptIXbXPseQDquw+W+RuJEJMHKHNsPNNm3CA== dependencies: - "@babel/helper-module-imports" "^7.10.4" + "@babel/helper-module-imports" "^7.12.5" "@babel/helper-plugin-utils" "^7.10.4" - resolve "^1.8.1" semver "^5.5.1" -"@babel/plugin-transform-shorthand-properties@^7.10.4": +"@babel/plugin-transform-shorthand-properties@^7.12.1": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.13.tgz#db755732b70c539d504c6390d9ce90fe64aff7ad" integrity sha512-xpL49pqPnLtf0tVluuqvzWIgLEhuPpZzvs2yabUHSKRNlN7ScYU7aMlmavOeyXJZKgZKQRBlh8rHbKiJDraTSw== dependencies: "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-spread@^7.11.0": +"@babel/plugin-transform-spread@^7.12.1": version "7.13.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.13.0.tgz#84887710e273c1815ace7ae459f6f42a5d31d5fd" integrity sha512-V6vkiXijjzYeFmQTr3dBxPtZYLPcUfY34DebOU27jIl2M/Y8Egm52Hw82CSjjPqd54GTlJs5x+CR7HeNr24ckg== @@ -918,35 +983,35 @@ "@babel/helper-plugin-utils" "^7.13.0" "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" -"@babel/plugin-transform-sticky-regex@^7.10.4": +"@babel/plugin-transform-sticky-regex@^7.12.7": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.13.tgz#760ffd936face73f860ae646fb86ee82f3d06d1f" integrity sha512-Jc3JSaaWT8+fr7GRvQP02fKDsYk4K/lYwWq38r/UGfaxo89ajud321NH28KRQ7xy1Ybc0VUE5Pz8psjNNDUglg== dependencies: "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-template-literals@^7.10.4": +"@babel/plugin-transform-template-literals@^7.12.1": version "7.13.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.13.0.tgz#a36049127977ad94438dee7443598d1cefdf409d" integrity sha512-d67umW6nlfmr1iehCcBv69eSUSySk1EsIS8aTDX4Xo9qajAh6mYtcl4kJrBkGXuxZPEgVr7RVfAvNW6YQkd4Mw== dependencies: "@babel/helper-plugin-utils" "^7.13.0" -"@babel/plugin-transform-typeof-symbol@^7.10.4": +"@babel/plugin-transform-typeof-symbol@^7.12.10": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.13.tgz#785dd67a1f2ea579d9c2be722de8c84cb85f5a7f" integrity sha512-eKv/LmUJpMnu4npgfvs3LiHhJua5fo/CysENxa45YCQXZwKnGCQKAg87bvoqSW1fFT+HA32l03Qxsm8ouTY3ZQ== dependencies: "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-unicode-escapes@^7.10.4": +"@babel/plugin-transform-unicode-escapes@^7.12.1": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.13.tgz#840ced3b816d3b5127dd1d12dcedc5dead1a5e74" integrity sha512-0bHEkdwJ/sN/ikBHfSmOXPypN/beiGqjo+o4/5K+vxEFNPRPdImhviPakMKG4x96l85emoa0Z6cDflsdBusZbw== dependencies: "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-unicode-regex@^7.10.4": +"@babel/plugin-transform-unicode-regex@^7.12.1": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.13.tgz#b52521685804e155b1202e83fc188d34bb70f5ac" integrity sha512-mDRzSNY7/zopwisPZ5kM9XKCfhchqIYwAKRERtEnhYscZB79VRekuRSoYbN0+KVe3y8+q1h6A4svXtP7N+UoCA== @@ -954,30 +1019,31 @@ "@babel/helper-create-regexp-features-plugin" "^7.12.13" "@babel/helper-plugin-utils" "^7.12.13" -"@babel/preset-env@7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.11.0.tgz#860ee38f2ce17ad60480c2021ba9689393efb796" - integrity sha512-2u1/k7rG/gTh02dylX2kL3S0IJNF+J6bfDSp4DI2Ma8QN6Y9x9pmAax59fsCk6QUQG0yqH47yJWA+u1I1LccAg== +"@babel/preset-env@7.12.11": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.12.11.tgz#55d5f7981487365c93dbbc84507b1c7215e857f9" + integrity sha512-j8Tb+KKIXKYlDBQyIOy4BLxzv1NUOwlHfZ74rvW+Z0Gp4/cI2IMDPBWAgWceGcE7aep9oL/0K9mlzlMGxA8yNw== dependencies: - "@babel/compat-data" "^7.11.0" - "@babel/helper-compilation-targets" "^7.10.4" - "@babel/helper-module-imports" "^7.10.4" + "@babel/compat-data" "^7.12.7" + "@babel/helper-compilation-targets" "^7.12.5" + "@babel/helper-module-imports" "^7.12.5" "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-proposal-async-generator-functions" "^7.10.4" - "@babel/plugin-proposal-class-properties" "^7.10.4" - "@babel/plugin-proposal-dynamic-import" "^7.10.4" - "@babel/plugin-proposal-export-namespace-from" "^7.10.4" - "@babel/plugin-proposal-json-strings" "^7.10.4" - "@babel/plugin-proposal-logical-assignment-operators" "^7.11.0" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.10.4" - "@babel/plugin-proposal-numeric-separator" "^7.10.4" - "@babel/plugin-proposal-object-rest-spread" "^7.11.0" - "@babel/plugin-proposal-optional-catch-binding" "^7.10.4" - "@babel/plugin-proposal-optional-chaining" "^7.11.0" - "@babel/plugin-proposal-private-methods" "^7.10.4" - "@babel/plugin-proposal-unicode-property-regex" "^7.10.4" + "@babel/helper-validator-option" "^7.12.11" + "@babel/plugin-proposal-async-generator-functions" "^7.12.1" + "@babel/plugin-proposal-class-properties" "^7.12.1" + "@babel/plugin-proposal-dynamic-import" "^7.12.1" + "@babel/plugin-proposal-export-namespace-from" "^7.12.1" + "@babel/plugin-proposal-json-strings" "^7.12.1" + "@babel/plugin-proposal-logical-assignment-operators" "^7.12.1" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.12.1" + "@babel/plugin-proposal-numeric-separator" "^7.12.7" + "@babel/plugin-proposal-object-rest-spread" "^7.12.1" + "@babel/plugin-proposal-optional-catch-binding" "^7.12.1" + "@babel/plugin-proposal-optional-chaining" "^7.12.7" + "@babel/plugin-proposal-private-methods" "^7.12.1" + "@babel/plugin-proposal-unicode-property-regex" "^7.12.1" "@babel/plugin-syntax-async-generators" "^7.8.0" - "@babel/plugin-syntax-class-properties" "^7.10.4" + "@babel/plugin-syntax-class-properties" "^7.12.1" "@babel/plugin-syntax-dynamic-import" "^7.8.0" "@babel/plugin-syntax-export-namespace-from" "^7.8.3" "@babel/plugin-syntax-json-strings" "^7.8.0" @@ -987,45 +1053,42 @@ "@babel/plugin-syntax-object-rest-spread" "^7.8.0" "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" "@babel/plugin-syntax-optional-chaining" "^7.8.0" - "@babel/plugin-syntax-top-level-await" "^7.10.4" - "@babel/plugin-transform-arrow-functions" "^7.10.4" - "@babel/plugin-transform-async-to-generator" "^7.10.4" - "@babel/plugin-transform-block-scoped-functions" "^7.10.4" - "@babel/plugin-transform-block-scoping" "^7.10.4" - "@babel/plugin-transform-classes" "^7.10.4" - "@babel/plugin-transform-computed-properties" "^7.10.4" - "@babel/plugin-transform-destructuring" "^7.10.4" - "@babel/plugin-transform-dotall-regex" "^7.10.4" - "@babel/plugin-transform-duplicate-keys" "^7.10.4" - "@babel/plugin-transform-exponentiation-operator" "^7.10.4" - "@babel/plugin-transform-for-of" "^7.10.4" - "@babel/plugin-transform-function-name" "^7.10.4" - "@babel/plugin-transform-literals" "^7.10.4" - "@babel/plugin-transform-member-expression-literals" "^7.10.4" - "@babel/plugin-transform-modules-amd" "^7.10.4" - "@babel/plugin-transform-modules-commonjs" "^7.10.4" - "@babel/plugin-transform-modules-systemjs" "^7.10.4" - "@babel/plugin-transform-modules-umd" "^7.10.4" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.10.4" - "@babel/plugin-transform-new-target" "^7.10.4" - "@babel/plugin-transform-object-super" "^7.10.4" - "@babel/plugin-transform-parameters" "^7.10.4" - "@babel/plugin-transform-property-literals" "^7.10.4" - "@babel/plugin-transform-regenerator" "^7.10.4" - "@babel/plugin-transform-reserved-words" "^7.10.4" - "@babel/plugin-transform-shorthand-properties" "^7.10.4" - "@babel/plugin-transform-spread" "^7.11.0" - "@babel/plugin-transform-sticky-regex" "^7.10.4" - "@babel/plugin-transform-template-literals" "^7.10.4" - "@babel/plugin-transform-typeof-symbol" "^7.10.4" - "@babel/plugin-transform-unicode-escapes" "^7.10.4" - "@babel/plugin-transform-unicode-regex" "^7.10.4" + "@babel/plugin-syntax-top-level-await" "^7.12.1" + "@babel/plugin-transform-arrow-functions" "^7.12.1" + "@babel/plugin-transform-async-to-generator" "^7.12.1" + "@babel/plugin-transform-block-scoped-functions" "^7.12.1" + "@babel/plugin-transform-block-scoping" "^7.12.11" + "@babel/plugin-transform-classes" "^7.12.1" + "@babel/plugin-transform-computed-properties" "^7.12.1" + "@babel/plugin-transform-destructuring" "^7.12.1" + "@babel/plugin-transform-dotall-regex" "^7.12.1" + "@babel/plugin-transform-duplicate-keys" "^7.12.1" + "@babel/plugin-transform-exponentiation-operator" "^7.12.1" + "@babel/plugin-transform-for-of" "^7.12.1" + "@babel/plugin-transform-function-name" "^7.12.1" + "@babel/plugin-transform-literals" "^7.12.1" + "@babel/plugin-transform-member-expression-literals" "^7.12.1" + "@babel/plugin-transform-modules-amd" "^7.12.1" + "@babel/plugin-transform-modules-commonjs" "^7.12.1" + "@babel/plugin-transform-modules-systemjs" "^7.12.1" + "@babel/plugin-transform-modules-umd" "^7.12.1" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.12.1" + "@babel/plugin-transform-new-target" "^7.12.1" + "@babel/plugin-transform-object-super" "^7.12.1" + "@babel/plugin-transform-parameters" "^7.12.1" + "@babel/plugin-transform-property-literals" "^7.12.1" + "@babel/plugin-transform-regenerator" "^7.12.1" + "@babel/plugin-transform-reserved-words" "^7.12.1" + "@babel/plugin-transform-shorthand-properties" "^7.12.1" + "@babel/plugin-transform-spread" "^7.12.1" + "@babel/plugin-transform-sticky-regex" "^7.12.7" + "@babel/plugin-transform-template-literals" "^7.12.1" + "@babel/plugin-transform-typeof-symbol" "^7.12.10" + "@babel/plugin-transform-unicode-escapes" "^7.12.1" + "@babel/plugin-transform-unicode-regex" "^7.12.1" "@babel/preset-modules" "^0.1.3" - "@babel/types" "^7.11.0" - browserslist "^4.12.0" - core-js-compat "^3.6.2" - invariant "^2.2.2" - levenary "^1.1.1" + "@babel/types" "^7.12.11" + core-js-compat "^3.8.0" semver "^5.5.0" "@babel/preset-modules@^0.1.3": @@ -1039,30 +1102,38 @@ "@babel/types" "^7.4.4" esutils "^2.0.2" -"@babel/runtime@7.11.2": - version "7.11.2" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.11.2.tgz#f549c13c754cc40b87644b9fa9f09a6a95fe0736" - integrity sha512-TeWkU52so0mPtDcaCTxNBI/IHiz0pZgr8VEFqXFtZWpYD08ZB6FaSwVAS8MKRQAP3bYKiVjwysOJgMFY28o6Tw== +"@babel/runtime-corejs3@^7.10.2": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.14.0.tgz#6bf5fbc0b961f8e3202888cb2cd0fb7a0a9a3f66" + integrity sha512-0R0HTZWHLk6G8jIk0FtoX+AatCtKnswS98VhXwGImFc759PJRp4Tru0PQYZofyijTFUr+gT8Mu7sgXVJLQ0ceg== + dependencies: + core-js-pure "^3.0.0" + regenerator-runtime "^0.13.4" + +"@babel/runtime@7.12.5": + version "7.12.5" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.5.tgz#410e7e487441e1b360c29be715d870d9b985882e" + integrity sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg== dependencies: regenerator-runtime "^0.13.4" -"@babel/runtime@^7.8.4": +"@babel/runtime@^7.10.2", "@babel/runtime@^7.8.4": version "7.14.0" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.0.tgz#46794bc20b612c5f75e62dd071e24dfd95f1cbe6" integrity sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA== dependencies: regenerator-runtime "^0.13.4" -"@babel/template@7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.10.4.tgz#3251996c4200ebc71d1a8fc405fba940f36ba278" - integrity sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA== +"@babel/template@7.12.7": + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.12.7.tgz#c817233696018e39fbb6c491d2fb684e05ed43bc" + integrity sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow== dependencies: "@babel/code-frame" "^7.10.4" - "@babel/parser" "^7.10.4" - "@babel/types" "^7.10.4" + "@babel/parser" "^7.12.7" + "@babel/types" "^7.12.7" -"@babel/template@^7.10.4", "@babel/template@^7.12.13": +"@babel/template@^7.12.13", "@babel/template@^7.12.7": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.12.13.tgz#530265be8a2589dbb37523844c5bcb55947fb327" integrity sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA== @@ -1071,7 +1142,7 @@ "@babel/parser" "^7.12.13" "@babel/types" "^7.12.13" -"@babel/traverse@^7.11.0", "@babel/traverse@^7.13.0", "@babel/traverse@^7.13.15", "@babel/traverse@^7.14.0": +"@babel/traverse@^7.12.10", "@babel/traverse@^7.13.0", "@babel/traverse@^7.13.15", "@babel/traverse@^7.14.0": version "7.14.0" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.14.0.tgz#cea0dc8ae7e2b1dec65f512f39f3483e8cc95aef" integrity sha512-dZ/a371EE5XNhTHomvtuLTUyx6UEoJmYX+DT5zBCQN3McHemsuIaKKYqsc/fs26BEkHs/lBZy0J571LP5z9kQA== @@ -1085,7 +1156,7 @@ debug "^4.1.0" globals "^11.1.0" -"@babel/types@^7.10.4", "@babel/types@^7.11.0", "@babel/types@^7.12.1", "@babel/types@^7.12.13", "@babel/types@^7.13.0", "@babel/types@^7.13.12", "@babel/types@^7.13.16", "@babel/types@^7.14.0", "@babel/types@^7.14.1", "@babel/types@^7.4.4": +"@babel/types@^7.12.1", "@babel/types@^7.12.10", "@babel/types@^7.12.11", "@babel/types@^7.12.13", "@babel/types@^7.12.7", "@babel/types@^7.13.0", "@babel/types@^7.13.12", "@babel/types@^7.13.16", "@babel/types@^7.14.0", "@babel/types@^7.14.1", "@babel/types@^7.4.4", "@babel/types@^7.8.6": version "7.14.1" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.14.1.tgz#095bd12f1c08ab63eff6e8f7745fa7c9cc15a9db" integrity sha512-S13Qe85fzLs3gYRUnrpyeIrBJIMYv33qSTg1qoBwiG6nPKwUWAD9odSzWhEedpwOIzSEI6gbdQIWEMiCI42iBA== @@ -1093,6 +1164,35 @@ "@babel/helper-validator-identifier" "^7.14.0" to-fast-properties "^2.0.0" +"@discoveryjs/json-ext@0.5.2": + version "0.5.2" + resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.2.tgz#8f03a22a04de437254e8ce8cc84ba39689288752" + integrity sha512-HyYEUDeIj5rRQU2Hk5HTB2uHsbRQpF70nvMhVzi+VJR0X+xNEhjPui4/kBf3VeH/wqD28PT4sVOm8qqLjBrSZg== + +"@es-joy/jsdoccomment@^0.4.4": + version "0.4.4" + resolved "https://registry.yarnpkg.com/@es-joy/jsdoccomment/-/jsdoccomment-0.4.4.tgz#8a25154156edbfc29e310943ebb17ee29122c9df" + integrity sha512-ua4qDt9dQb4qt5OI38eCZcQZYE5Bq3P0GzgvDARdT8Lt0mAUpxKTPy8JGGqEvF77tG1irKDZ3WreeezEa3P43w== + dependencies: + comment-parser "^1.1.5" + esquery "^1.4.0" + jsdoctypeparser "^9.0.0" + +"@eslint/eslintrc@^0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.1.tgz#442763b88cecbe3ee0ec7ca6d6dd6168550cbf14" + integrity sha512-5v7TDE9plVhvxQeWLXDTvFvJBdH6pEsdnl2g/dAptmuFEPedQ4Erq5rsDsX+mvAM610IhNaO2W5V1dOOnDKxkQ== + dependencies: + ajv "^6.12.4" + debug "^4.1.1" + espree "^7.3.0" + globals "^12.1.0" + ignore "^4.0.6" + import-fresh "^3.2.1" + js-yaml "^3.13.1" + minimatch "^3.0.4" + strip-json-comments "^3.1.1" + "@istanbuljs/schema@^0.1.2": version "0.1.3" resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" @@ -1109,14 +1209,14 @@ merge-source-map "^1.1.0" schema-utils "^2.7.0" -"@ngtools/webpack@10.2.3": - version "10.2.3" - resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-10.2.3.tgz#e4e410d1d647b6e21a69ab20c00c110464f623ea" - integrity sha512-h7JJMMca1bHY/0Prpxu2P3bvnC6pUKmBAfqN0h0HaRN9LTU9IDWtDRTIL1Aqhs/tcTUio/DowVKnVi2CWHAOmg== +"@ngtools/webpack@11.2.12": + version "11.2.12" + resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-11.2.12.tgz#c01f4bf2ebf71f239aaca1e2b473fa6071c63f5e" + integrity sha512-YgzgJ72oGLvYVQH1c+pqJQRO5OE8axPt8HwPdueL/1g3rEwJgbeUrnIqw/eri7iTgFZflQRcePAA7dIz2uHwcw== dependencies: - "@angular-devkit/core" "10.2.3" - enhanced-resolve "4.3.0" - webpack-sources "1.4.3" + "@angular-devkit/core" "11.2.12" + enhanced-resolve "5.7.0" + webpack-sources "2.2.0" "@nodelib/fs.scandir@2.1.4": version "2.1.4" @@ -1139,6 +1239,33 @@ "@nodelib/fs.scandir" "2.1.4" fastq "^1.6.0" +"@npmcli/ci-detect@^1.0.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@npmcli/ci-detect/-/ci-detect-1.3.0.tgz#6c1d2c625fb6ef1b9dea85ad0a5afcbef85ef22a" + integrity sha512-oN3y7FAROHhrAt7Rr7PnTSwrHrZVRTS2ZbyxeQwSSYD0ifwM3YNgQqbaRmjcWoPyq77MjchusjJDspbzMmip1Q== + +"@npmcli/git@^2.0.1": + version "2.0.9" + resolved "https://registry.yarnpkg.com/@npmcli/git/-/git-2.0.9.tgz#915bbfe66300e67b4da5ef765a4475ffb2ca5b6b" + integrity sha512-hTMbMryvOqGLwnmMBKs5usbPsJtyEsMsgXwJbmNrsEuQQh1LAIMDU77IoOrwkCg+NgQWl+ySlarJASwM3SutCA== + dependencies: + "@npmcli/promise-spawn" "^1.3.2" + lru-cache "^6.0.0" + mkdirp "^1.0.4" + npm-pick-manifest "^6.1.1" + promise-inflight "^1.0.1" + promise-retry "^2.0.1" + semver "^7.3.5" + which "^2.0.2" + +"@npmcli/installed-package-contents@^1.0.5": + version "1.0.7" + resolved "https://registry.yarnpkg.com/@npmcli/installed-package-contents/-/installed-package-contents-1.0.7.tgz#ab7408c6147911b970a8abe261ce512232a3f4fa" + integrity sha512-9rufe0wnJusCQoLpV9ZPKIVP55itrM5BxOXs10DmdbRfgWtHy1LDyskbwRnBghuB0PrF7pNPOqREVtpz4HqzKw== + dependencies: + npm-bundled "^1.1.1" + npm-normalize-package-bin "^1.0.1" + "@npmcli/move-file@^1.0.1": version "1.1.2" resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-1.1.2.tgz#1a82c3e372f7cae9253eb66d72543d6b8685c674" @@ -1147,34 +1274,62 @@ mkdirp "^1.0.4" rimraf "^3.0.2" -"@saritasa/tslint-config-angular@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@saritasa/tslint-config-angular/-/tslint-config-angular-2.0.0.tgz#9e76c98081b1bc54c260e1c27abd5cd4ef8d2525" - integrity sha512-zs7nOOgxOA3WpNeRLS2Qcuu0BHU/GN/n9Kfbv//w0fzZinxeZKMaLOOnDcSlq4JGgOp6AbVJeCR8l50enwEasQ== +"@npmcli/node-gyp@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@npmcli/node-gyp/-/node-gyp-1.0.2.tgz#3cdc1f30e9736dbc417373ed803b42b1a0a29ede" + integrity sha512-yrJUe6reVMpktcvagumoqD9r08fH1iRo01gn1u0zoCApa9lnZGEigVKUd2hzsCId4gdtkZZIVscLhNxMECKgRg== + +"@npmcli/promise-spawn@^1.2.0", "@npmcli/promise-spawn@^1.3.2": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@npmcli/promise-spawn/-/promise-spawn-1.3.2.tgz#42d4e56a8e9274fba180dabc0aea6e38f29274f5" + integrity sha512-QyAGYo/Fbj4MXeGdJcFzZ+FkDkomfRBrPM+9QYJSg+PxgAUL+LU3FneQk37rKR2/zjqkCV1BLHccX98wRXG3Sg== + dependencies: + infer-owner "^1.0.4" + +"@npmcli/run-script@^1.3.0": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@npmcli/run-script/-/run-script-1.8.5.tgz#f250a0c5e1a08a792d775a315d0ff42fc3a51e1d" + integrity sha512-NQspusBCpTjNwNRFMtz2C5MxoxyzlbuJ4YEhxAKrIonTiirKDtatsZictx9RgamQIx6+QuHMNmPl0wQdoESs9A== + dependencies: + "@npmcli/node-gyp" "^1.0.2" + "@npmcli/promise-spawn" "^1.3.2" + infer-owner "^1.0.4" + node-gyp "^7.1.0" + read-package-json-fast "^2.0.1" -"@schematics/angular@10.2.3": - version "10.2.3" - resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-10.2.3.tgz#a5ea7e9bc17fbfb9b1c5f760f44bc4a7b0b18834" - integrity sha512-xcnfH5XMmGcs33VHm2cu0+4g3rkfSD+qpiKFjfg7KGC4lLoOKSED4ZnjzIYwcQ6QN4gTpAvlZKxI8zO7NkKv0A== +"@schematics/angular@11.2.12": + version "11.2.12" + resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-11.2.12.tgz#1a9db7fc3ac6b520dd6607ec5096842d1e9e8d09" + integrity sha512-QCFdJhJtHrytl2L9VAdKYzSS1+R5LpjQ+pw3f/10YeEEoUHk7QyuYXmMnreCYBWSKrloO+3Q+vhdnVWUQZSRng== dependencies: - "@angular-devkit/core" "10.2.3" - "@angular-devkit/schematics" "10.2.3" - jsonc-parser "2.3.0" + "@angular-devkit/core" "11.2.12" + "@angular-devkit/schematics" "11.2.12" + jsonc-parser "3.0.0" -"@schematics/update@0.1002.3": - version "0.1002.3" - resolved "https://registry.yarnpkg.com/@schematics/update/-/update-0.1002.3.tgz#75b016d44c98e77eaaff0be844144d867a224cd1" - integrity sha512-UnuMgRQtAOp/Pk9rSYW12medajXe9s5mW4a6foixC/B2UCFFlIAVbFBTiFpr69xbalfLlFcFx1MD+8/8njWtbQ== +"@schematics/update@0.1102.12": + version "0.1102.12" + resolved "https://registry.yarnpkg.com/@schematics/update/-/update-0.1102.12.tgz#e9221c3bd8077baf2a4f688bdeca3ded329c356b" + integrity sha512-3Gm/0izWhfHqXCKENkVVqFJVkJN4+mebevSlXqlQjwLMwJNY5Yt3FMyDSxYx6s2d9MC2stODOjwjsLhd6SdafQ== dependencies: - "@angular-devkit/core" "10.2.3" - "@angular-devkit/schematics" "10.2.3" + "@angular-devkit/core" "11.2.12" + "@angular-devkit/schematics" "11.2.12" "@yarnpkg/lockfile" "1.1.0" - ini "1.3.6" + ini "2.0.0" npm-package-arg "^8.0.0" - pacote "9.5.12" - semver "7.3.2" + pacote "11.2.4" + semver "7.3.4" semver-intersect "1.4.0" +"@tootallnate/once@1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" + integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== + +"@trysound/sax@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.1.1.tgz#3348564048e7a2d7398c935d466c0414ebb6a669" + integrity sha512-Z6DoceYb/1xSg5+e+ZlPZ9v0N16ZvZ+wYMraFue4HYrE4ttONKtsvruIRf6t9TBR0YvSOfi1hUU0fJfBLCDYow== + "@types/glob@^7.1.1": version "7.1.3" resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.3.tgz#e6ba80f36b7daad2c685acd9266382e68985c183" @@ -1183,30 +1338,30 @@ "@types/minimatch" "*" "@types/node" "*" -"@types/json-schema@^7.0.5": +"@types/json-schema@^7.0.3", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.6": version "7.0.7" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad" integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA== +"@types/json5@^0.0.29": + version "0.0.29" + resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" + integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= + "@types/minimatch@*": version "3.0.4" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.4.tgz#f0ec25dbf2f0e4b18647313ac031134ca5b24b21" integrity sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA== -"@types/node@*": +"@types/node@*", "@types/node@^15.0.2": version "15.0.2" resolved "https://registry.yarnpkg.com/@types/node/-/node-15.0.2.tgz#51e9c0920d1b45936ea04341aa3e2e58d339fb67" integrity sha512-p68+a+KoxpoB47015IeYZYRrdqMUcpbK8re/zpFB8Ld46LHC1lPEbp3EXgkEhAYEcPvjJF6ZO+869SQ0aH1dcA== -"@types/node@^12.11.1": - version "12.20.12" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.12.tgz#fd9c1c2cfab536a2383ed1ef70f94adea743a226" - integrity sha512-KQZ1al2hKOONAs2MFv+yTQP1LkDWMrRJ9YCVRalXltOfXsBmH5IownLxQaiq0lnAHwAViLnh2aTYqrPcRGEbgg== - -"@types/q@^1.5.1": - version "1.5.4" - resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.4.tgz#15925414e0ad2cd765bfef58842f7e26a7accb24" - integrity sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug== +"@types/parse-json@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" + integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== "@types/source-list-map@*": version "0.1.2" @@ -1229,6 +1384,76 @@ "@types/source-list-map" "*" source-map "^0.6.1" +"@typescript-eslint/eslint-plugin@4.16.1": + version "4.16.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.16.1.tgz#2caf6a79dd19c3853b8d39769a27fccb24e4e651" + integrity sha512-SK777klBdlkUZpZLC1mPvyOWk9yAFCWmug13eAjVQ4/Q1LATE/NbcQL1xDHkptQkZOLnPmLUA1Y54m8dqYwnoQ== + dependencies: + "@typescript-eslint/experimental-utils" "4.16.1" + "@typescript-eslint/scope-manager" "4.16.1" + debug "^4.1.1" + functional-red-black-tree "^1.0.1" + lodash "^4.17.15" + regexpp "^3.0.0" + semver "^7.3.2" + tsutils "^3.17.1" + +"@typescript-eslint/experimental-utils@4.16.1": + version "4.16.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.16.1.tgz#da7a396dc7d0e01922acf102b76efff17320b328" + integrity sha512-0Hm3LSlMYFK17jO4iY3un1Ve9x1zLNn4EM50Lia+0EV99NdbK+cn0er7HC7IvBA23mBg3P+8dUkMXy4leL33UQ== + dependencies: + "@types/json-schema" "^7.0.3" + "@typescript-eslint/scope-manager" "4.16.1" + "@typescript-eslint/types" "4.16.1" + "@typescript-eslint/typescript-estree" "4.16.1" + eslint-scope "^5.0.0" + eslint-utils "^2.0.0" + +"@typescript-eslint/parser@4.16.1": + version "4.16.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.16.1.tgz#3bbd3234dd3c5b882b2bcd9899bc30e1e1586d2a" + integrity sha512-/c0LEZcDL5y8RyI1zLcmZMvJrsR6SM1uetskFkoh3dvqDKVXPsXI+wFB/CbVw7WkEyyTKobC1mUNp/5y6gRvXg== + dependencies: + "@typescript-eslint/scope-manager" "4.16.1" + "@typescript-eslint/types" "4.16.1" + "@typescript-eslint/typescript-estree" "4.16.1" + debug "^4.1.1" + +"@typescript-eslint/scope-manager@4.16.1": + version "4.16.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.16.1.tgz#244e2006bc60cfe46987e9987f4ff49c9e3f00d5" + integrity sha512-6IlZv9JaurqV0jkEg923cV49aAn8V6+1H1DRfhRcvZUrptQ+UtSKHb5kwTayzOYTJJ/RsYZdcvhOEKiBLyc0Cw== + dependencies: + "@typescript-eslint/types" "4.16.1" + "@typescript-eslint/visitor-keys" "4.16.1" + +"@typescript-eslint/types@4.16.1": + version "4.16.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.16.1.tgz#5ba2d3e38b1a67420d2487519e193163054d9c15" + integrity sha512-nnKqBwMgRlhzmJQF8tnFDZWfunXmJyuXj55xc8Kbfup4PbkzdoDXZvzN8//EiKR27J6vUSU8j4t37yUuYPiLqA== + +"@typescript-eslint/typescript-estree@4.16.1": + version "4.16.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.16.1.tgz#c2fc46b05a48fbf8bbe8b66a63f0a9ba04b356f1" + integrity sha512-m8I/DKHa8YbeHt31T+UGd/l8Kwr0XCTCZL3H4HMvvLCT7HU9V7yYdinTOv1gf/zfqNeDcCgaFH2BMsS8x6NvJg== + dependencies: + "@typescript-eslint/types" "4.16.1" + "@typescript-eslint/visitor-keys" "4.16.1" + debug "^4.1.1" + globby "^11.0.1" + is-glob "^4.0.1" + semver "^7.3.2" + tsutils "^3.17.1" + +"@typescript-eslint/visitor-keys@4.16.1": + version "4.16.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.16.1.tgz#d7571fb580749fae621520deeb134370bbfc7293" + integrity sha512-s/aIP1XcMkEqCNcPQtl60ogUYjSM8FU2mq1O7y5cFf3Xcob1z1iXWNB6cC43Op+NGRTFgGolri6s8z/efA9i1w== + dependencies: + "@typescript-eslint/types" "4.16.1" + eslint-visitor-keys "^2.0.0" + "@webassemblyjs/ast@1.9.0": version "1.9.0" resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964" @@ -1389,19 +1614,16 @@ resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31" integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ== -JSONStream@^1.3.4: - version "1.3.5" - resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0" - integrity sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ== - dependencies: - jsonparse "^1.2.0" - through ">=2.2.7 <3" - -abab@^2.0.3: +abab@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: version "1.3.7" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" @@ -1415,11 +1637,21 @@ ace-builds@^1.4.2: resolved "https://registry.yarnpkg.com/ace-builds/-/ace-builds-1.4.12.tgz#888efa386e36f4345f40b5233fcc4fe4c588fae7" integrity sha512-G+chJctFPiiLGvs3+/Mly3apXTcfgE45dT5yp12BcWZ1kUs+gm0qd3/fv4gsz6fVag4mM0moHVpjHDIgph6Psg== +acorn-jsx@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b" + integrity sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng== + acorn@^6.4.1: version "6.4.2" resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6" integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ== +acorn@^7.4.0: + version "7.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" + integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== + adjust-sourcemap-loader@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/adjust-sourcemap-loader/-/adjust-sourcemap-loader-3.0.0.tgz#5ae12fb5b7b1c585e80bbb5a63ec163a1a45e61e" @@ -1428,25 +1660,20 @@ adjust-sourcemap-loader@3.0.0: loader-utils "^2.0.0" regex-parser "^2.2.11" -agent-base@4, agent-base@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee" - integrity sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg== - dependencies: - es6-promisify "^5.0.0" - -agent-base@~4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9" - integrity sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg== +agent-base@6: + version "6.0.2" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== dependencies: - es6-promisify "^5.0.0" + debug "4" -agentkeepalive@^3.4.1: - version "3.5.2" - resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-3.5.2.tgz#a113924dd3fa24a0bc3b78108c450c2abee00f67" - integrity sha512-e0L/HNe6qkQ7H19kTlRRqUibEAwDK5AFk6y3PtMsuut2VAH6+Q4xZml1tNDJD7kSAyqmbG/K08K5WEJYtUrSlQ== +agentkeepalive@^4.1.3: + version "4.1.4" + resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.1.4.tgz#d928028a4862cb11718e55227872e842a44c945b" + integrity sha512-+V/rGa3EuU74H6wR04plBb7Ks10FbtUQgRj/FQOG7uUIEuaINI+AiqJR1k6t3SVNs7o7ZjIdus6706qqzVq8jQ== dependencies: + debug "^4.1.0" + depd "^1.1.2" humanize-ms "^1.2.1" aggregate-error@^3.0.0: @@ -1467,32 +1694,32 @@ ajv-keywords@^3.1.0, ajv-keywords@^3.4.1, ajv-keywords@^3.5.2: resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== -ajv@6.12.4: - version "6.12.4" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.4.tgz#0614facc4522127fa713445c6bfd3ebd376e2234" - integrity sha512-eienB2c9qVQs2KWexhkrdMLVDoIQCz5KSeLxwg9Lzk4DOfBtIK9PQwwufcsn1jjGuf9WZmqPMbGxOzfcuphJCQ== +ajv@6.12.6, ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.5: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== dependencies: fast-deep-equal "^3.1.1" fast-json-stable-stringify "^2.0.0" json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ajv@^6.1.0, ajv@^6.10.2, ajv@^6.12.3, ajv@^6.12.4: - version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" - integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== +ajv@^8.0.1: + version "8.3.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.3.0.tgz#25ee7348e32cdc4a1dbb38256bf6bdc451dd577c" + integrity sha512-RYE7B5An83d7eWnDR8kbdaIFqmKCNsP16ay1hDbJEU+sa0e3H9SebskCt0Uufem6cfAVu7Col6ubcn/W+Sm8/Q== dependencies: fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" uri-js "^4.2.2" -alphanum-sort@^1.0.0: +alphanum-sort@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" integrity sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM= -ansi-colors@4.1.1: +ansi-colors@4.1.1, ansi-colors@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== @@ -1519,6 +1746,11 @@ ansi-regex@^2.0.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= + ansi-regex@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" @@ -1559,16 +1791,19 @@ anymatch@~3.1.1: normalize-path "^3.0.0" picomatch "^2.0.4" -app-root-path@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/app-root-path/-/app-root-path-2.2.1.tgz#d0df4a682ee408273583d43f6f79e9892624bc9a" - integrity sha512-91IFKeKk7FjfmezPKkwtaRvSpnUc4gDwPAjA1YZ9Gn0q0PPeW+vbeUsZuyDwjI7+QTHhcLen2v25fi/AmhvbJA== - -aproba@^1.1.1: +aproba@^1.0.3, aproba@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== +are-we-there-yet@~1.1.2: + version "1.1.5" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" + integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + argparse@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" @@ -1576,13 +1811,13 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" -aria-query@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-3.0.0.tgz#65b3fcc1ca1155a8c9ae64d6eee297f15d5133cc" - integrity sha1-ZbP8wcoRVajJrmTW7uKX8V1RM8w= +aria-query@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-4.2.2.tgz#0d2ca6c9aceb56b8977e9fed6aed7e15bbd2f83b" + integrity sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA== dependencies: - ast-types-flow "0.0.7" - commander "^2.11.0" + "@babel/runtime" "^7.10.2" + "@babel/runtime-corejs3" "^7.10.2" arity-n@^1.0.4: version "1.0.4" @@ -1619,6 +1854,17 @@ array-flatten@^2.1.0: resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== +array-includes@^3.1.1: + version "3.1.3" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.3.tgz#c7f619b382ad2afaf5326cddfdc0afc61af7690a" + integrity sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.18.0-next.2" + get-intrinsic "^1.1.1" + is-string "^1.0.5" + array-union@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" @@ -1641,10 +1887,14 @@ array-unique@^0.3.2: resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= -asap@^2.0.0: - version "2.0.6" - resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" - integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= +array.prototype.flat@^1.2.3: + version "1.2.4" + resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz#6ef638b43312bd401b4c6199fdec7e2dc9e9a123" + integrity sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + es-abstract "^1.18.0-next.1" asn1.js@^5.2.0: version "5.4.1" @@ -1681,10 +1931,10 @@ assign-symbols@^1.0.0: resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= -ast-types-flow@0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad" - integrity sha1-9wtzXGvKGlycItmCw+Oef+ujva0= +astral-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" + integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== async-each@^1.0.1: version "1.0.3" @@ -1713,17 +1963,16 @@ atob@^2.1.2: resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== -autoprefixer@9.8.6: - version "9.8.6" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.6.tgz#3b73594ca1bf9266320c5acf1588d74dea74210f" - integrity sha512-XrvP4VVHdRBCdX1S3WXVD8+RyG9qeb1D5Sn1DeLiG2xfSpzellk5k54xbUERJ3M5DggQxes39UGOTP8CFrEGbg== +autoprefixer@10.2.4: + version "10.2.4" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.2.4.tgz#c0e7cf24fcc6a1ae5d6250c623f0cb8beef2f7e1" + integrity sha512-DCCdUQiMD+P/as8m3XkeTUkUKuuRqLGcwD0nll7wevhqoJfMRpJlkFd1+MQh1pvupjiQuip42lc/VFvfUTMSKw== dependencies: - browserslist "^4.12.0" - caniuse-lite "^1.0.30001109" + browserslist "^4.16.1" + caniuse-lite "^1.0.30001181" colorette "^1.2.1" + fraction.js "^4.0.13" normalize-range "^0.1.2" - num2fraction "^1.2.2" - postcss "^7.0.32" postcss-value-parser "^4.1.0" available-typed-arrays@^1.0.2: @@ -1743,22 +1992,19 @@ aws4@^1.8.0: resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== -axobject-query@2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.0.2.tgz#ea187abe5b9002b377f925d8bf7d1c561adf38f9" - integrity sha512-MCeek8ZH7hKyO1rWUbKNQBbl4l2eY0ntk7OGi+q0RlafrCnfPxC06WZA+uebCfmYp4mNU9jRBP1AhGyf8+W3ww== - dependencies: - ast-types-flow "0.0.7" +axobject-query@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be" + integrity sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA== -babel-loader@8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.1.0.tgz#c611d5112bd5209abe8b9fa84c3e4da25275f1c3" - integrity sha512-7q7nC1tYOrqvUrN3LQK4GwSk/TQorZSOlO9C+RZDZpODgyN4ZlCqE5q9cDsyWOliN+aU9B4JX01xK9eJXowJLw== +babel-loader@8.2.2: + version "8.2.2" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.2.2.tgz#9363ce84c10c9a40e6c753748e1441b60c8a0b81" + integrity sha512-JvTd0/D889PQBtUXJ2PXaKU/pjZDMtHA9V2ecm+eNRmmBCMR09a+fmpGTNwnJtFmFl5Ei7Vy47LjBb+L0wQ99g== dependencies: - find-cache-dir "^2.1.0" + find-cache-dir "^3.3.1" loader-utils "^1.4.0" - mkdirp "^0.5.3" - pify "^4.0.1" + make-dir "^3.1.0" schema-utils "^2.6.5" babel-plugin-dynamic-import-node@^2.3.3: @@ -1773,7 +2019,7 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== -base64-js@^1.0.2: +base64-js@^1.0.2, base64-js@^1.3.1: version "1.5.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== @@ -1825,7 +2071,16 @@ bindings@^1.5.0: dependencies: file-uri-to-path "1.0.0" -bluebird@^3.5.1, bluebird@^3.5.3, bluebird@^3.5.5: +bl@^4.0.3: + version "4.1.0" + resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" + integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== + dependencies: + buffer "^5.5.0" + inherits "^2.0.4" + readable-stream "^3.4.0" + +bluebird@^3.5.5: version "3.7.2" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== @@ -1868,7 +2123,7 @@ bonjour@^3.5.0: multicast-dns "^6.0.1" multicast-dns-service-types "^1.1.0" -boolbase@^1.0.0, boolbase@~1.0.0: +boolbase@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= @@ -1980,7 +2235,7 @@ browserify-zlib@^0.2.0: dependencies: pako "~1.0.5" -browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.16.6, browserslist@^4.9.1: +browserslist@^4.0.0, browserslist@^4.14.5, browserslist@^4.16.0, browserslist@^4.16.1, browserslist@^4.16.6, browserslist@^4.9.1: version "4.16.6" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.6.tgz#d7901277a5a88e554ed305b183ec9b0c08f66fa2" integrity sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ== @@ -2015,10 +2270,13 @@ buffer@^4.3.0: ieee754 "^1.1.4" isarray "^1.0.0" -builtin-modules@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" - integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8= +buffer@^5.5.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" builtin-status-codes@^3.0.0: version "3.0.0" @@ -2063,7 +2321,7 @@ cacache@15.0.5: tar "^6.0.2" unique-filename "^1.1.1" -cacache@^12.0.0, cacache@^12.0.2: +cacache@^12.0.2: version "12.0.4" resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.4.tgz#668bcbd105aeb5f1d92fe25570ec9525c8faa40c" integrity sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ== @@ -2084,7 +2342,7 @@ cacache@^12.0.0, cacache@^12.0.2: unique-filename "^1.1.1" y18n "^4.0.0" -cacache@^15.0.4, cacache@^15.0.5: +cacache@^15.0.5: version "15.0.6" resolved "https://registry.yarnpkg.com/cacache/-/cacache-15.0.6.tgz#65a8c580fda15b59150fb76bf3f3a8e45d583099" integrity sha512-g1WYDMct/jzW+JdWEyjaX2zoBkZ6ZT9VpOyp2I/VMtDsNLffNat3kqPFfi1eDRSK9/SuKGyORDHcQMcPF8sQ/w== @@ -2130,31 +2388,17 @@ call-bind@^1.0.0, call-bind@^1.0.2: function-bind "^1.1.1" get-intrinsic "^1.0.2" -caller-callsite@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" - integrity sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ= - dependencies: - callsites "^2.0.0" - -caller-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4" - integrity sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ= - dependencies: - caller-callsite "^2.0.0" - -callsites@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" - integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== camelcase@5.3.1, camelcase@^5.0.0: version "5.3.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== -camelcase@^6.0.0: +camelcase@^6.2.0: version "6.2.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809" integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== @@ -2169,7 +2413,7 @@ caniuse-api@^3.0.0: lodash.memoize "^4.1.2" lodash.uniq "^4.5.0" -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001032, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001219: +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001032, caniuse-lite@^1.0.30001181, caniuse-lite@^1.0.30001219: version "1.0.30001228" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001228.tgz#bfdc5942cd3326fa51ee0b42fbef4da9d492a7fa" integrity sha512-QQmLOGJ3DEgokHbMSA8cj2a+geXqmnpyOFT0lhQV6P3/YOJvGDEwoedcwxEQ30gJIwIIunHIicunJ2rzK5gB2A== @@ -2184,7 +2428,7 @@ caseless@~0.12.0: resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= -chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4.2: +chalk@^2.0.0, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -2193,7 +2437,7 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^4.1.0: +chalk@^4.0.0, chalk@^4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.1.tgz#c80b3fab28bf6371e6863325eee67e618b77e6ad" integrity sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg== @@ -2240,7 +2484,7 @@ chokidar@^2.1.8: optionalDependencies: fsevents "^1.2.7" -chownr@^1.1.1, chownr@^1.1.2: +chownr@^1.1.1: version "1.1.4" resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== @@ -2263,10 +2507,10 @@ cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: inherits "^2.0.1" safe-buffer "^5.0.1" -circular-dependency-plugin@5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/circular-dependency-plugin/-/circular-dependency-plugin-5.2.0.tgz#e09dbc2dd3e2928442403e2d45b41cea06bc0a93" - integrity sha512-7p4Kn/gffhQaavNfyDFg7LS5S/UT1JAjyGd4UqR2+jzoYF02eDkj0Ec3+48TsIa4zghjLY87nQHIh/ecK9qLdw== +circular-dependency-plugin@5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/circular-dependency-plugin/-/circular-dependency-plugin-5.2.2.tgz#39e836079db1d3cf2f988dc48c5188a44058b600" + integrity sha512-g38K9Cm5WRwlaH6g03B9OEz/0qRizI+2I7n+Gz+L5DxXJAPAiWQvwlYNm1V1jkdpUv95bOe/ASm2vfi/G560jQ== class-utils@^0.3.5: version "0.3.6" @@ -2290,7 +2534,7 @@ cli-cursor@^3.1.0: dependencies: restore-cursor "^3.1.0" -cli-spinners@^2.4.0: +cli-spinners@^2.5.0: version "2.6.0" resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.6.0.tgz#36c7dc98fb6a9a76bd6238ec3f77e2425627e939" integrity sha512-t+4/y50K/+4xcCRosKkA7W4gTr1MySvLV0q+PxmG7FJ5g+66ChKurYjxBCjHggHH3HA5Hh9cy+lcUGWDqVH+4Q== @@ -2318,39 +2562,24 @@ cliui@^7.0.2: strip-ansi "^6.0.0" wrap-ansi "^7.0.0" +clone-deep@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" + integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== + dependencies: + is-plain-object "^2.0.4" + kind-of "^6.0.2" + shallow-clone "^3.0.0" + clone@^1.0.2: version "1.0.4" resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= -clone@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" - integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18= - -coa@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/coa/-/coa-2.0.2.tgz#43f6c21151b4ef2bf57187db0d73de229e3e7ec3" - integrity sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA== - dependencies: - "@types/q" "^1.5.1" - chalk "^2.4.1" - q "^1.1.2" - -codelyzer@^5.1.2: - version "5.2.2" - resolved "https://registry.yarnpkg.com/codelyzer/-/codelyzer-5.2.2.tgz#d0530a455784e6bea0b6d7e97166c73c30a5347f" - integrity sha512-jB4FZ1Sx7kZhvZVdf+N2BaKTdrrNZOL0Bj10RRfrhHrb3zEvXjJvvq298JPMJAiyiCS/v4zs1QlGU0ip7xGqeA== - dependencies: - app-root-path "^2.2.1" - aria-query "^3.0.0" - axobject-query "2.0.2" - css-selector-tokenizer "^0.7.1" - cssauron "^1.4.0" - damerau-levenshtein "^1.0.4" - semver-dsl "^1.0.1" - source-map "^0.5.7" - sprintf-js "^1.1.2" +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= collection-visit@^1.0.0: version "1.0.0" @@ -2392,7 +2621,7 @@ color-string@^1.5.4: color-name "^1.0.0" simple-swizzle "^0.2.2" -color@^3.0.0: +color@^3.1.1: version "3.1.3" resolved "https://registry.yarnpkg.com/color/-/color-3.1.3.tgz#ca67fb4e7b97d611dcde39eceed422067d91596e" integrity sha512-xgXAcTHa2HeFCGLE9Xs/R82hujGtu9Jd9x4NW3T34+OMs7VoPsjwzRczKHvTAHeJwWFwX5j15+MgAppE8ztObQ== @@ -2412,11 +2641,21 @@ combined-stream@^1.0.6, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" -commander@2, commander@^2.11.0, commander@^2.12.1, commander@^2.20.0: +commander@2, commander@^2.20.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== +commander@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" + integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== + +comment-parser@1.1.5, comment-parser@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/comment-parser/-/comment-parser-1.1.5.tgz#453627ef8f67dbcec44e79a9bd5baa37f0bce9b2" + integrity sha512-RePCE4leIhBlmrqiYTvaqEeGYg7qpSl4etaIabKtdOQVi+mSTIBBklGUwIr79GXYnl3LpMwmDw4KeR2stNc6FA== + commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" @@ -2479,11 +2718,21 @@ console-browserify@^1.1.0: resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA== +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= + constants-browserify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= +contains-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" + integrity sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo= + content-disposition@0.5.3: version "0.5.3" resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" @@ -2542,24 +2791,24 @@ copy-descriptor@^0.1.0: resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= -copy-webpack-plugin@6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-6.0.3.tgz#2b3d2bfc6861b96432a65f0149720adbd902040b" - integrity sha512-q5m6Vz4elsuyVEIUXr7wJdIdePWTubsqVbEMvf1WQnHGv0Q+9yPRu7MtYFPt+GBOXRav9lvIINifTQ1vSCs+eA== +copy-webpack-plugin@6.3.2: + version "6.3.2" + resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-6.3.2.tgz#0e920a6c181a5052aa6e2861b164bda03f83afeb" + integrity sha512-MgJ1uouLIbDg4ST1GzqrGQyKoXY5iPqi6fghFqarijam7FQcBa/r6Rg0VkoIuzx75Xq8iAMghyOueMkWUQ5OaA== dependencies: - cacache "^15.0.4" + cacache "^15.0.5" fast-glob "^3.2.4" find-cache-dir "^3.3.1" glob-parent "^5.1.1" globby "^11.0.1" loader-utils "^2.0.0" normalize-path "^3.0.0" - p-limit "^3.0.1" - schema-utils "^2.7.0" - serialize-javascript "^4.0.0" + p-limit "^3.0.2" + schema-utils "^3.0.0" + serialize-javascript "^5.0.1" webpack-sources "^1.4.3" -core-js-compat@^3.6.2: +core-js-compat@^3.8.0: version "3.12.1" resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.12.1.tgz#2c302c4708505fa7072b0adb5156d26f7801a18b" integrity sha512-i6h5qODpw6EsHAoIdQhKoZdWn+dGBF3dSS8m5tif36RlWvW3A6+yu2S16QHUo3CrkzrnEskMAt9f8FxmY9fhWQ== @@ -2567,10 +2816,15 @@ core-js-compat@^3.6.2: browserslist "^4.16.6" semver "7.0.0" -core-js@3.6.4: - version "3.6.4" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.6.4.tgz#440a83536b458114b9cb2ac1580ba377dc470647" - integrity sha512-4paDGScNgZP2IXXilaffL9X7968RuvwlkK3xWtZRVqgd8SYNiVKRJvkFd1aqqEuPfN7E68ZHEp9hDj6lHj4Hyw== +core-js-pure@^3.0.0: + version "3.12.1" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.12.1.tgz#934da8b9b7221e2a2443dc71dfa5bd77a7ea00b8" + integrity sha512-1cch+qads4JnDSWsvc7d6nzlKAippwjUlf6vykkTLW53VSV+NkE6muGBToAjEA8pG90cSfcud3JgVmW2ds5TaQ== + +core-js@3.8.3: + version "3.8.3" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.8.3.tgz#c21906e1f14f3689f93abcc6e26883550dd92dd0" + integrity sha512-KPYXeVZYemC2TkNEkX/01I+7yd+nX3KddKwZ1Ww7SKWdI2wQprSgLmrTddT8nw92AjEklTsPBoSdQBhbI1bQ6Q== core-js@^3.6.4: version "3.12.1" @@ -2582,15 +2836,16 @@ core-util-is@1.0.2, core-util-is@~1.0.0: resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= -cosmiconfig@^5.0.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a" - integrity sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA== +cosmiconfig@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.0.tgz#ef9b44d773959cae63ddecd122de23853b60f8d3" + integrity sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA== dependencies: - import-fresh "^2.0.0" - is-directory "^0.3.1" - js-yaml "^3.13.1" - parse-json "^4.0.0" + "@types/parse-json" "^4.0.0" + import-fresh "^3.2.1" + parse-json "^5.0.0" + path-type "^4.0.0" + yaml "^1.10.0" create-ecdh@^4.0.0: version "4.0.4" @@ -2623,6 +2878,17 @@ create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7: safe-buffer "^5.0.1" sha.js "^2.4.8" +critters@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/critters/-/critters-0.0.7.tgz#548b470360f4f3c51e622de3b7aa733c8f0b17bf" + integrity sha512-qUF2SaAWFYjNPdCcPpu68p2DnHiosia84yx5mPTlUMQjkjChR+n6sO1/I7yn2U2qNDgSPTd2SoaTIDQcUL+EwQ== + dependencies: + chalk "^4.1.0" + css "^3.0.0" + parse5 "^6.0.1" + parse5-htmlparser2-tree-adapter "^6.0.1" + pretty-bytes "^5.3.0" + cross-spawn@^6.0.0: version "6.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" @@ -2634,6 +2900,15 @@ cross-spawn@^6.0.0: shebang-command "^1.2.0" which "^1.2.9" +cross-spawn@^7.0.2: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + crypto-browserify@^3.11.0: version "3.12.0" resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" @@ -2651,35 +2926,39 @@ crypto-browserify@^3.11.0: randombytes "^2.0.0" randomfill "^1.0.3" -css-color-names@0.0.4, css-color-names@^0.0.4: +css-color-names@^0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0" integrity sha1-gIrcLnnPhHOAabZGyyDsJ762KeA= -css-declaration-sorter@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz#c198940f63a76d7e36c1e71018b001721054cb22" - integrity sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA== +css-color-names@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-1.0.1.tgz#6ff7ee81a823ad46e020fa2fd6ab40a887e2ba67" + integrity sha512-/loXYOch1qU1biStIFsHH8SxTmOseh1IJqFvy8IujXOm1h+QjUdDhkzOrR5HG8K8mlxREj0yfi8ewCHx0eMxzA== + +css-declaration-sorter@6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-6.0.0.tgz#eb21f75860078627e9e3cc6f5535ccfcea445817" + integrity sha512-S0TE4E0ha5+tBHdLWPc5n+S8E4dFBS5xScPvgHkLNZwWvX4ISoFGhGeerLC9uS1cKA/sC+K2wHq6qEbcagT/fg== dependencies: - postcss "^7.0.1" timsort "^0.3.0" -css-loader@4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-4.2.2.tgz#b668b3488d566dc22ebcf9425c5f254a05808c89" - integrity sha512-omVGsTkZPVwVRpckeUnLshPp12KsmMSLqYxs12+RzM9jRR5Y+Idn/tBffjXRvOE+qW7if24cuceFJqYR5FmGBg== +css-loader@5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-5.0.1.tgz#9e4de0d6636a6266a585bd0900b422c85539d25f" + integrity sha512-cXc2ti9V234cq7rJzFKhirb2L2iPy8ZjALeVJAozXYz9te3r4eqLSixNAbMDJSgJEQywqXzs8gonxaboeKqwiw== dependencies: - camelcase "^6.0.0" + camelcase "^6.2.0" cssesc "^3.0.0" - icss-utils "^4.1.1" + icss-utils "^5.0.0" loader-utils "^2.0.0" - postcss "^7.0.32" - postcss-modules-extract-imports "^2.0.0" - postcss-modules-local-by-default "^3.0.3" - postcss-modules-scope "^2.2.0" - postcss-modules-values "^3.0.0" + postcss "^8.1.4" + postcss-modules-extract-imports "^3.0.0" + postcss-modules-local-by-default "^4.0.0" + postcss-modules-scope "^3.0.0" + postcss-modules-values "^4.0.0" postcss-value-parser "^4.1.0" - schema-utils "^2.7.0" + schema-utils "^3.0.0" semver "^7.3.2" css-parse@~2.0.0: @@ -2689,36 +2968,16 @@ css-parse@~2.0.0: dependencies: css "^2.0.0" -css-select-base-adapter@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz#3b2ff4972cc362ab88561507a95408a1432135d7" - integrity sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w== - -css-select@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/css-select/-/css-select-2.1.0.tgz#6a34653356635934a81baca68d0255432105dbef" - integrity sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ== +css-select@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-3.1.2.tgz#d52cbdc6fee379fba97fb0d3925abbd18af2d9d8" + integrity sha512-qmss1EihSuBNWNNhHjxzxSfJoFBM/lERB/Q4EnsJQQC62R2evJDW481091oAdOr9uh46/0n4nrg0It5cAnj1RA== dependencies: boolbase "^1.0.0" - css-what "^3.2.1" - domutils "^1.7.0" - nth-check "^1.0.2" - -css-selector-tokenizer@^0.7.1: - version "0.7.3" - resolved "https://registry.yarnpkg.com/css-selector-tokenizer/-/css-selector-tokenizer-0.7.3.tgz#735f26186e67c749aaf275783405cf0661fae8f1" - integrity sha512-jWQv3oCEL5kMErj4wRnK/OPoBi0D+P1FR2cDCKYPaMeD2eW3/mttav8HT4hT1CKopiJI/psEULjkClhvJo4Lvg== - dependencies: - cssesc "^3.0.0" - fastparse "^1.1.2" - -css-tree@1.0.0-alpha.37: - version "1.0.0-alpha.37" - resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.37.tgz#98bebd62c4c1d9f960ec340cf9f7522e30709a22" - integrity sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg== - dependencies: - mdn-data "2.0.4" - source-map "^0.6.1" + css-what "^4.0.0" + domhandler "^4.0.0" + domutils "^2.4.3" + nth-check "^2.0.0" css-tree@^1.1.2: version "1.1.3" @@ -2728,10 +2987,10 @@ css-tree@^1.1.2: mdn-data "2.0.14" source-map "^0.6.1" -css-what@^3.2.1: - version "3.4.2" - resolved "https://registry.yarnpkg.com/css-what/-/css-what-3.4.2.tgz#ea7026fcb01777edbde52124e21f327e7ae950e4" - integrity sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ== +css-what@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-4.0.0.tgz#35e73761cab2eeb3d3661126b23d7aa0e8432233" + integrity sha512-teijzG7kwYfNVsUh2H/YN62xW3KK9YhXEgSlbxMlcyjPNvdKJqFx5lrwlJgoFP1ZHlB89iGDlo/JyshKeRhv5A== css@^2.0.0: version "2.2.4" @@ -2743,87 +3002,70 @@ css@^2.0.0: source-map-resolve "^0.5.2" urix "^0.1.0" -cssauron@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/cssauron/-/cssauron-1.4.0.tgz#a6602dff7e04a8306dc0db9a551e92e8b5662ad8" - integrity sha1-pmAt/34EqDBtwNuaVR6S6LVmKtg= +css@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/css/-/css-3.0.0.tgz#4447a4d58fdd03367c516ca9f64ae365cee4aa5d" + integrity sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ== dependencies: - through X.X.X + inherits "^2.0.4" + source-map "^0.6.1" + source-map-resolve "^0.6.0" cssesc@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== -cssnano-preset-default@^4.0.7: - version "4.0.8" - resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-4.0.8.tgz#920622b1fc1e95a34e8838203f1397a504f2d3ff" - integrity sha512-LdAyHuq+VRyeVREFmuxUZR1TXjQm8QQU/ktoo/x7bz+SdOge1YKc5eMN6pRW7YWBmyq59CqYba1dJ5cUukEjLQ== - dependencies: - css-declaration-sorter "^4.0.1" - cssnano-util-raw-cache "^4.0.1" - postcss "^7.0.0" - postcss-calc "^7.0.1" - postcss-colormin "^4.0.3" - postcss-convert-values "^4.0.1" - postcss-discard-comments "^4.0.2" - postcss-discard-duplicates "^4.0.2" - postcss-discard-empty "^4.0.1" - postcss-discard-overridden "^4.0.1" - postcss-merge-longhand "^4.0.11" - postcss-merge-rules "^4.0.3" - postcss-minify-font-values "^4.0.2" - postcss-minify-gradients "^4.0.2" - postcss-minify-params "^4.0.2" - postcss-minify-selectors "^4.0.2" - postcss-normalize-charset "^4.0.1" - postcss-normalize-display-values "^4.0.2" - postcss-normalize-positions "^4.0.2" - postcss-normalize-repeat-style "^4.0.2" - postcss-normalize-string "^4.0.2" - postcss-normalize-timing-functions "^4.0.2" - postcss-normalize-unicode "^4.0.1" - postcss-normalize-url "^4.0.1" - postcss-normalize-whitespace "^4.0.2" - postcss-ordered-values "^4.1.2" - postcss-reduce-initial "^4.0.3" - postcss-reduce-transforms "^4.0.2" - postcss-svgo "^4.0.3" - postcss-unique-selectors "^4.0.1" - -cssnano-util-get-arguments@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz#ed3a08299f21d75741b20f3b81f194ed49cc150f" - integrity sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8= - -cssnano-util-get-match@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz#c0e4ca07f5386bb17ec5e52250b4f5961365156d" - integrity sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0= - -cssnano-util-raw-cache@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz#b26d5fd5f72a11dfe7a7846fb4c67260f96bf282" - integrity sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA== - dependencies: - postcss "^7.0.0" - -cssnano-util-same-parent@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz#574082fb2859d2db433855835d9a8456ea18bbf3" - integrity sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q== +cssnano-preset-default@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-5.0.1.tgz#76adc00f7aae36ae80552b8356e21bec4b233ca2" + integrity sha512-cfmfThYODGqhpQKDq9H0MTAqkMvZ3dGbOUTBKw0xWZiIycMqHid22LsJXJl4r1qX4qzDeKxcSyQ/Xb5Mu3Z//Q== + dependencies: + css-declaration-sorter "6.0.0" + cssnano-utils "^2.0.0" + postcss-calc "^8.0.0" + postcss-colormin "^5.0.0" + postcss-convert-values "^5.0.0" + postcss-discard-comments "^5.0.0" + postcss-discard-duplicates "^5.0.0" + postcss-discard-empty "^5.0.0" + postcss-discard-overridden "^5.0.0" + postcss-merge-longhand "^5.0.1" + postcss-merge-rules "^5.0.0" + postcss-minify-font-values "^5.0.0" + postcss-minify-gradients "^5.0.0" + postcss-minify-params "^5.0.0" + postcss-minify-selectors "^5.0.0" + postcss-normalize-charset "^5.0.0" + postcss-normalize-display-values "^5.0.0" + postcss-normalize-positions "^5.0.0" + postcss-normalize-repeat-style "^5.0.0" + postcss-normalize-string "^5.0.0" + postcss-normalize-timing-functions "^5.0.0" + postcss-normalize-unicode "^5.0.0" + postcss-normalize-url "^5.0.0" + postcss-normalize-whitespace "^5.0.0" + postcss-ordered-values "^5.0.0" + postcss-reduce-initial "^5.0.0" + postcss-reduce-transforms "^5.0.0" + postcss-svgo "^5.0.0" + postcss-unique-selectors "^5.0.0" + +cssnano-utils@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/cssnano-utils/-/cssnano-utils-2.0.0.tgz#b04baaa312aa3dd5a854b7f61d76b9d94be07f74" + integrity sha512-xvxmTszdrvSyTACdPe8VU5J6p4sm3egpgw54dILvNqt5eBUv6TFjACLhSxtRuEsxYrgy8uDy269YjScO5aKbGA== -cssnano@4.1.10: - version "4.1.10" - resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-4.1.10.tgz#0ac41f0b13d13d465487e111b778d42da631b8b2" - integrity sha512-5wny+F6H4/8RgNlaqab4ktc3e0/blKutmq8yNlBFXA//nSFFAqAngjNVRzUvCgYROULmZZUoosL/KSoZo5aUaQ== +cssnano@5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-5.0.1.tgz#ed4822c4a9212f22f6820717859c52a6b7f9cf5c" + integrity sha512-5WubEmKcK2cqw43DUAayRBiIlTdX7iX3ZowrWDVxSVcW3hyohVnbJ4K4mbnWtJp5rfJnUwHg5H4mDAGzmuCM3g== dependencies: - cosmiconfig "^5.0.0" - cssnano-preset-default "^4.0.7" - is-resolvable "^1.0.0" - postcss "^7.0.0" + cosmiconfig "^7.0.0" + cssnano-preset-default "^5.0.0" + is-resolvable "^1.1.0" -csso@^4.0.2: +csso@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/csso/-/csso-4.2.0.tgz#ea3a561346e8dc9f546d6febedd50187cf389529" integrity sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA== @@ -2843,11 +3085,6 @@ d@1, d@^1.0.1: es5-ext "^0.10.50" type "^1.0.1" -damerau-levenshtein@^1.0.4: - version "1.0.7" - resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.7.tgz#64368003512a1a6992593741a09a9d31a836f55d" - integrity sha512-VvdQIPGdWP0SqFXghj79Wf/5LArmreyMsGLa6FG6iC4t3j7j5s71TrwWmT/4akbDQIqjfACkLZmjXhA7g2oUZw== - dashdash@^1.12.0: version "1.14.1" resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" @@ -2855,54 +3092,33 @@ dashdash@^1.12.0: dependencies: assert-plus "^1.0.0" -data-urls@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b" - integrity sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ== - dependencies: - abab "^2.0.3" - whatwg-mimetype "^2.3.0" - whatwg-url "^8.0.0" - -debug@2.6.9, debug@^2.2.0, debug@^2.3.3: +debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== dependencies: ms "2.0.0" -debug@3.1.0, debug@~3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" - integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== - dependencies: - ms "2.0.0" - -debug@4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" - integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== +debug@4, debug@4.3.1, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" + integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== dependencies: - ms "^2.1.1" + ms "2.1.2" -debug@^3.1.0, debug@^3.1.1, debug@^3.2.5: +debug@^3.1.1, debug@^3.2.6: version "3.2.7" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== dependencies: ms "^2.1.1" -debug@^4.1.0, debug@^4.1.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" - integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== +debug@~3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== dependencies: - ms "2.1.2" - -debuglog@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" - integrity sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI= + ms "2.0.0" decamelize@^1.2.0: version "1.2.0" @@ -2947,6 +3163,11 @@ deep-equal@^2.0.1: which-collection "^1.0.1" which-typed-array "^1.1.2" +deep-is@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= + default-gateway@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-4.2.0.tgz#167104c7500c2115f6dd69b0a536bb8ed720552b" @@ -3009,7 +3230,12 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= -depd@~1.1.2: +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= + +depd@^1.1.2, depd@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= @@ -3037,19 +3263,6 @@ detect-node@^2.0.4: resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.5.tgz#9d270aa7eaa5af0b72c4c9d9b814e7f4ce738b79" integrity sha512-qi86tE6hRcFHy8jI1m2VG+LaPUR1LhqDa5G8tVjuUXmOrpuAgqsA1pN0+ldgr3aKUH+QLI9hCY/OcRYisERejw== -dezalgo@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/dezalgo/-/dezalgo-1.0.3.tgz#7f742de066fc748bc8db820569dddce49bf0d456" - integrity sha1-f3Qt4Gb8dIvI24IFad3c5Jvw1FY= - dependencies: - asap "^2.0.0" - wrappy "1" - -diff@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" - integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== - diffie-hellman@^5.0.0: version "5.0.3" resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" @@ -3086,12 +3299,28 @@ dns-txt@^2.0.2: dependencies: buffer-indexof "^1.0.0" -dom-serializer@0: - version "0.2.2" - resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51" - integrity sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g== +doctrine@1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" + integrity sha1-N53Ocw9hZvds76TmcHoVmwLFpvo= + dependencies: + esutils "^2.0.2" + isarray "^1.0.0" + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + +dom-serializer@^1.0.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.3.1.tgz#d845a1565d7c041a95e5dab62184ab41e3a519be" + integrity sha512-Pv2ZluG5ife96udGgEDovOOOA5UELkltfJpnIExPrAk1LTvecolUGn6lIaoLh86d83GiB86CjzciMd9BuRB71Q== dependencies: domelementtype "^2.0.1" + domhandler "^4.0.0" entities "^2.0.0" domain-browser@^1.1.1: @@ -3099,28 +3328,31 @@ domain-browser@^1.1.1: resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== -domelementtype@1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" - integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== - -domelementtype@^2.0.1: +domelementtype@^2.0.1, domelementtype@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.2.0.tgz#9a0b6c2782ed6a1c7323d42267183df9bd8b1d57" integrity sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A== +domhandler@^4.0.0, domhandler@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.2.0.tgz#f9768a5f034be60a89a27c2e4d0f74eba0d8b059" + integrity sha512-zk7sgt970kzPks2Bf+dwT/PLzghLnsivb9CcxkvR8Mzr66Olr0Ofd8neSbglHJHaHa2MadfoSdNlKYAaafmWfA== + dependencies: + domelementtype "^2.2.0" + domino@^2.1.2: version "2.1.6" resolved "https://registry.yarnpkg.com/domino/-/domino-2.1.6.tgz#fe4ace4310526e5e7b9d12c7de01b7f485a57ffe" integrity sha512-3VdM/SXBZX2omc9JF9nOPCtDaYQ67BGp5CoLpIQlO2KCAPETs8TcDHacF26jXadGbvUteZzRTeos2fhID5+ucQ== -domutils@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" - integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg== +domutils@^2.4.3: + version "2.6.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.6.0.tgz#2e15c04185d43fb16ae7057cb76433c6edb938b7" + integrity sha512-y0BezHuy4MDYxh6OvolXYsH+1EMGmFbwv5FKW7ovwMG6zTPWqNPq3WF9ayZssFq+UlKdffGLbOEaghNdaOm1WA== dependencies: - dom-serializer "0" - domelementtype "1" + dom-serializer "^1.0.1" + domelementtype "^2.2.0" + domhandler "^4.2.0" dot-prop@^5.2.0: version "5.3.0" @@ -3200,7 +3432,7 @@ encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= -encoding@^0.1.11: +encoding@^0.1.12: version "0.1.13" resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== @@ -3214,14 +3446,13 @@ end-of-stream@^1.0.0, end-of-stream@^1.1.0: dependencies: once "^1.4.0" -enhanced-resolve@4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.3.0.tgz#3b806f3bfafc1ec7de69551ef93cca46c1704126" - integrity sha512-3e87LvavsdxyoCfGusJnrZ5G8SLPOFeHSNpZI/ATL9a5leXo2k0w6MKnbqhdBad9qTobSfB20Ld7UmgoNbAZkQ== +enhanced-resolve@5.7.0: + version "5.7.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.7.0.tgz#525c5d856680fbd5052de453ac83e32049958b5c" + integrity sha512-6njwt/NsZFUKhM6j9U8hzVyD4E4r0x7NQzhTCbcWOJ0IQjNSAoalWmb0AE51Wn+fwan5qVESWi7t2ToBxs9vrw== dependencies: - graceful-fs "^4.1.2" - memory-fs "^0.5.0" - tapable "^1.0.0" + graceful-fs "^4.2.4" + tapable "^2.2.0" enhanced-resolve@^4.3.0: version "4.5.0" @@ -3232,16 +3463,33 @@ enhanced-resolve@^4.3.0: memory-fs "^0.5.0" tapable "^1.0.0" +enquirer@^2.3.5: + version "2.3.6" + resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" + integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== + dependencies: + ansi-colors "^4.1.1" + entities@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== +env-paths@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" + integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== + err-code@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/err-code/-/err-code-1.1.2.tgz#06e0116d3028f6aef4806849eb0ea6a748ae6960" integrity sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA= +err-code@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/err-code/-/err-code-2.0.3.tgz#23c2f3b756ffdfc608d30e27c9a941024807e7f9" + integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA== + errno@^0.1.1, errno@^0.1.3, errno@~0.1.7: version "0.1.8" resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" @@ -3249,14 +3497,14 @@ errno@^0.1.1, errno@^0.1.3, errno@~0.1.7: dependencies: prr "~1.0.1" -error-ex@^1.3.1: +error-ex@^1.2.0, error-ex@^1.3.1: version "1.3.2" resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== dependencies: is-arrayish "^0.2.1" -es-abstract@^1.17.2, es-abstract@^1.18.0-next.1, es-abstract@^1.18.0-next.2: +es-abstract@^1.18.0-next.1, es-abstract@^1.18.0-next.2: version "1.18.0" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.0.tgz#ab80b359eecb7ede4c298000390bc5ac3ec7b5a4" integrity sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw== @@ -3319,18 +3567,6 @@ es6-iterator@2.0.3, es6-iterator@~2.0.3: es5-ext "^0.10.35" es6-symbol "^3.1.1" -es6-promise@^4.0.3: - version "4.2.8" - resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" - integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== - -es6-promisify@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" - integrity sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM= - dependencies: - es6-promise "^4.0.3" - es6-symbol@^3.1.1, es6-symbol@~3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" @@ -3354,6 +3590,61 @@ escape-string-regexp@^1.0.5: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= +eslint-import-resolver-node@^0.3.4: + version "0.3.4" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz#85ffa81942c25012d8231096ddf679c03042c717" + integrity sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA== + dependencies: + debug "^2.6.9" + resolve "^1.13.1" + +eslint-module-utils@^2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz#579ebd094f56af7797d19c9866c9c9486629bfa6" + integrity sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA== + dependencies: + debug "^2.6.9" + pkg-dir "^2.0.0" + +eslint-plugin-import@latest: + version "2.22.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.22.1.tgz#0896c7e6a0cf44109a2d97b95903c2bb689d7702" + integrity sha512-8K7JjINHOpH64ozkAhpT3sd+FswIZTfMZTjdx052pnWrgRCVfp8op9tbjpAk3DdUeI/Ba4C8OjdC0r90erHEOw== + dependencies: + array-includes "^3.1.1" + array.prototype.flat "^1.2.3" + contains-path "^0.1.0" + debug "^2.6.9" + doctrine "1.5.0" + eslint-import-resolver-node "^0.3.4" + eslint-module-utils "^2.6.0" + has "^1.0.3" + minimatch "^3.0.4" + object.values "^1.1.1" + read-pkg-up "^2.0.0" + resolve "^1.17.0" + tsconfig-paths "^3.9.0" + +eslint-plugin-jsdoc@latest: + version "33.3.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-33.3.0.tgz#a287db838d2cac4b36b76d99213901be6a31e9f5" + integrity sha512-wt6I9X8JoOyUtnsafM7AWBEfLCD3BI1wR5/vTu0hti4CoZc37bB4ZX9A7DsWKbEC/xROAAcBV2VAT638w9VKyQ== + dependencies: + "@es-joy/jsdoccomment" "^0.4.4" + comment-parser "1.1.5" + debug "^4.3.1" + esquery "^1.4.0" + jsdoctypeparser "^9.0.0" + lodash "^4.17.21" + regextras "^0.7.1" + semver "^7.3.5" + spdx-expression-parse "^3.0.1" + +eslint-plugin-prefer-arrow@latest: + version "1.2.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-prefer-arrow/-/eslint-plugin-prefer-arrow-1.2.3.tgz#e7fbb3fa4cd84ff1015b9c51ad86550e55041041" + integrity sha512-J9I5PKCOJretVuiZRGvPQxCbllxGAV/viI20JO3LYblAodofBxyMnZAJ+WGeClHgANnSJberTNoFWWjrWKBuXQ== + eslint-scope@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" @@ -3362,12 +3653,96 @@ eslint-scope@^4.0.3: esrecurse "^4.1.0" estraverse "^4.1.1" +eslint-scope@^5.0.0, eslint-scope@^5.1.0, eslint-scope@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + +eslint-utils@^2.0.0, eslint-utils@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" + integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== + dependencies: + eslint-visitor-keys "^1.1.0" + +eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" + integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== + +eslint-visitor-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" + integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== + +eslint@^7.6.0: + version "7.26.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.26.0.tgz#d416fdcdcb3236cd8f282065312813f8c13982f6" + integrity sha512-4R1ieRf52/izcZE7AlLy56uIHHDLT74Yzz2Iv2l6kDaYvEu9x+wMB5dZArVL8SYGXSYV2YAg70FcW5Y5nGGNIg== + dependencies: + "@babel/code-frame" "7.12.11" + "@eslint/eslintrc" "^0.4.1" + ajv "^6.10.0" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.0.1" + doctrine "^3.0.0" + enquirer "^2.3.5" + eslint-scope "^5.1.1" + eslint-utils "^2.1.0" + eslint-visitor-keys "^2.0.0" + espree "^7.3.1" + esquery "^1.4.0" + esutils "^2.0.2" + file-entry-cache "^6.0.1" + functional-red-black-tree "^1.0.1" + glob-parent "^5.0.0" + globals "^13.6.0" + ignore "^4.0.6" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + js-yaml "^3.13.1" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash "^4.17.21" + minimatch "^3.0.4" + natural-compare "^1.4.0" + optionator "^0.9.1" + progress "^2.0.0" + regexpp "^3.1.0" + semver "^7.2.1" + strip-ansi "^6.0.0" + strip-json-comments "^3.1.0" + table "^6.0.4" + text-table "^0.2.0" + v8-compile-cache "^2.0.3" + +espree@^7.3.0, espree@^7.3.1: + version "7.3.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6" + integrity sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g== + dependencies: + acorn "^7.4.0" + acorn-jsx "^5.3.1" + eslint-visitor-keys "^1.3.0" + esprima@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== -esrecurse@^4.1.0: +esquery@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" + integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== + dependencies: + estraverse "^5.1.0" + +esrecurse@^4.1.0, esrecurse@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== @@ -3379,7 +3754,7 @@ estraverse@^4.1.1: resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== -estraverse@^5.2.0: +estraverse@^5.1.0, estraverse@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== @@ -3563,10 +3938,10 @@ fast-json-stable-stringify@2.1.0, fast-json-stable-stringify@^2.0.0: resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== -fastparse@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/fastparse/-/fastparse-1.1.2.tgz#91728c5a5942eced8531283c79441ee4122c35a9" - integrity sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ== +fast-levenshtein@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= fastq@^1.6.0: version "1.11.0" @@ -3575,21 +3950,14 @@ fastq@^1.6.0: dependencies: reusify "^1.0.4" -faye-websocket@^0.10.0: - version "0.10.0" - resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4" - integrity sha1-TkkvjQTftviQA1B/btvy1QHnxvQ= - dependencies: - websocket-driver ">=0.5.1" - -faye-websocket@~0.11.1: +faye-websocket@^0.11.3: version "0.11.3" resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.3.tgz#5c0e9a8968e8912c286639fde977a8b209f2508e" integrity sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA== dependencies: websocket-driver ">=0.5.1" -figgy-pudding@^3.4.1, figgy-pudding@^3.5.1: +figgy-pudding@^3.5.1: version "3.5.2" resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e" integrity sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw== @@ -3601,13 +3969,20 @@ figures@^3.0.0: dependencies: escape-string-regexp "^1.0.5" -file-loader@6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.0.0.tgz#97bbfaab7a2460c07bcbd72d3a6922407f67649f" - integrity sha512-/aMOAYEFXDdjG0wytpTL5YQLfZnnTmLNjn+AIrJ/6HVnTfDqLsVKUUwkDf4I4kgex36BvjuXEn/TX9B/1ESyqQ== +file-entry-cache@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" + integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== + dependencies: + flat-cache "^3.0.4" + +file-loader@6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.2.0.tgz#baef7cf8e1840df325e4390b4484879480eebe4d" + integrity sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw== dependencies: loader-utils "^2.0.0" - schema-utils "^2.6.5" + schema-utils "^3.0.0" file-uri-to-path@1.0.0: version "1.0.0" @@ -3662,6 +4037,13 @@ find-cache-dir@^2.1.0: make-dir "^2.0.0" pkg-dir "^3.0.0" +find-up@^2.0.0, find-up@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= + dependencies: + locate-path "^2.0.0" + find-up@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" @@ -3677,6 +4059,19 @@ find-up@^4.0.0: locate-path "^5.0.0" path-exists "^4.0.0" +flat-cache@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" + integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== + dependencies: + flatted "^3.1.0" + rimraf "^3.0.2" + +flatted@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.1.1.tgz#c4b489e80096d9df1dfc97c79871aea7c617c469" + integrity sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA== + flush-write-stream@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" @@ -3719,6 +4114,11 @@ forwarded@~0.1.2: resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= +fraction.js@^4.0.13: + version "4.0.13" + resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.0.13.tgz#3c1c315fa16b35c85fffa95725a36fa729c69dfe" + integrity sha512-E1fz2Xs9ltlUp+qbiyx9wmt2n9dRzPsS11Jtdb8D2o+cC7wr9xkkKsVKJuBX0ST+LVS+LhLO+SbLJNtfWcJvXA== + fragment-cache@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" @@ -3748,14 +4148,7 @@ fs-extra@4.0.2: jsonfile "^4.0.0" universalify "^0.1.0" -fs-minipass@^1.2.5: - version "1.2.7" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7" - integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA== - dependencies: - minipass "^2.6.0" - -fs-minipass@^2.0.0: +fs-minipass@^2.0.0, fs-minipass@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== @@ -3785,11 +4178,6 @@ fsevents@^1.2.7: bindings "^1.5.0" nan "^2.12.1" -fsevents@~2.1.2: - version "2.1.3" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" - integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== - fsevents@~2.3.1: version "2.3.2" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" @@ -3800,10 +4188,24 @@ function-bind@^1.1.1: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== -genfun@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/genfun/-/genfun-5.0.0.tgz#9dd9710a06900a5c4a5bf57aca5da4e52fe76537" - integrity sha512-KGDOARWVga7+rnB3z9Sd2Letx515owfk0hSxHGuqjANb1M+x2bGZGqHLiozPsYMdM2OubeMni/Hpwmjq6qIUhA== +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= + +gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" gensync@^1.0.0-beta.1, gensync@^1.0.0-beta.2: version "1.0.0-beta.2" @@ -3824,7 +4226,7 @@ get-intrinsic@^1.0.1, get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@ has "^1.0.3" has-symbols "^1.0.1" -get-stream@^4.0.0, get-stream@^4.1.0: +get-stream@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== @@ -3851,7 +4253,7 @@ glob-parent@^3.1.0: is-glob "^3.1.0" path-dirname "^1.0.0" -glob-parent@^5.1.0, glob-parent@^5.1.1, glob-parent@~5.1.0: +glob-parent@^5.0.0, glob-parent@^5.1.0, glob-parent@^5.1.1, glob-parent@~5.1.0: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== @@ -3870,7 +4272,7 @@ glob@7.1.6: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.0.3, glob@^7.1.1, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: +glob@^7.0.3, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: version "7.1.7" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== @@ -3887,6 +4289,20 @@ globals@^11.1.0: resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== +globals@^12.1.0: + version "12.4.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-12.4.0.tgz#a18813576a41b00a24a97e7f815918c2e19925f8" + integrity sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg== + dependencies: + type-fest "^0.8.1" + +globals@^13.6.0: + version "13.8.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.8.0.tgz#3e20f504810ce87a8d72e55aecf8435b50f4c1b3" + integrity sha512-rHtdA6+PDBIjeEvA91rpqzEvk/k3/i7EeNQiryiWuJH0Hw9cpyJMAt2jtbAwUaRdhD+573X4vWw6IcjKPasi9Q== + dependencies: + type-fest "^0.20.2" + globby@^11.0.1: version "11.0.3" resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.3.tgz#9b1f0cb523e171dd1ad8c7b2a9fb4b644b9593cb" @@ -3910,7 +4326,7 @@ globby@^6.1.0: pify "^2.0.0" pinkie-promise "^2.0.0" -graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6: +graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.3, graceful-fs@^4.2.4: version "4.2.6" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== @@ -3958,6 +4374,11 @@ has-symbols@^1.0.1, has-symbols@^1.0.2: resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= + has-value@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" @@ -3989,7 +4410,7 @@ has-values@^1.0.0: is-number "^3.0.0" kind-of "^4.0.0" -has@^1.0.0, has@^1.0.3: +has@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== @@ -4027,12 +4448,12 @@ hmac-drbg@^1.0.1: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.1" -hosted-git-info@^2.1.4, hosted-git-info@^2.7.1: +hosted-git-info@^2.1.4: version "2.8.9" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== -hosted-git-info@^3.0.2: +hosted-git-info@^3.0.6: version "3.0.8" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-3.0.8.tgz#6e35d4cc87af2c5f816e4cb9ce350ba87a3f370d" integrity sha512-aXpmwoOhRBrw6X3j0h5RloK4x1OzsxMPyxqIHyNfSe2pypkVTZFpEiRoSipPEPlMrh0HW/XsjkJ5WgnCirpNUw== @@ -4071,10 +4492,10 @@ html-entities@^1.3.1: resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.4.0.tgz#cfbd1b01d2afaf9adca1b10ae7dffab98c71d2dc" integrity sha512-8nxjcBcd8wovbeKx7h3wTji4e6+rhaVuPNpMqwWgnHh+N9ToqsCs6XztWRBPQ+UtzsoMAdKZtUENoVzU/EMtZA== -http-cache-semantics@^3.8.1: - version "3.8.1" - resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2" - integrity sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w== +http-cache-semantics@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" + integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== http-deceiver@^1.2.7: version "1.2.7" @@ -4118,13 +4539,14 @@ http-parser-js@>=0.5.1: resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.3.tgz#01d2709c79d41698bb01d4decc5e9da4e4a033d9" integrity sha512-t7hjvef/5HEK7RWTdUzVUhl8zkEu+LlaE0IYzdMuvbSDipxBRpOn4Uhw8ZyECEa808iVT8XCjzo6xmYt4CiLZg== -http-proxy-agent@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz#e4821beef5b2142a2026bd73926fe537631c5405" - integrity sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg== +http-proxy-agent@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" + integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== dependencies: - agent-base "4" - debug "3.1.0" + "@tootallnate/once" "1" + agent-base "6" + debug "4" http-proxy-middleware@0.19.1: version "0.19.1" @@ -4159,13 +4581,13 @@ https-browserify@^1.0.0: resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= -https-proxy-agent@^2.2.3: - version "2.2.4" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz#4ee7a737abd92678a293d9b34a1af4d0d08c787b" - integrity sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg== +https-proxy-agent@5.0.0, https-proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" + integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA== dependencies: - agent-base "^4.3.0" - debug "^3.1.0" + agent-base "6" + debug "4" humanize-ms@^1.2.1: version "1.2.1" @@ -4174,7 +4596,7 @@ humanize-ms@^1.2.1: dependencies: ms "^2.0.0" -iconv-lite@0.4.24, iconv-lite@^0.4.24: +iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== @@ -4188,14 +4610,12 @@ iconv-lite@^0.6.2: dependencies: safer-buffer ">= 2.1.2 < 3.0.0" -icss-utils@^4.0.0, icss-utils@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-4.1.1.tgz#21170b53789ee27447c2f47dd683081403f9a467" - integrity sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA== - dependencies: - postcss "^7.0.14" +icss-utils@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" + integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== -ieee754@^1.1.4: +ieee754@^1.1.13, ieee754@^1.1.4: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== @@ -4205,44 +4625,35 @@ iferr@^0.1.5: resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE= -ignore-walk@^3.0.1: +ignore-walk@^3.0.3: version "3.0.4" resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.4.tgz#c9a09f69b7c7b479a5d74ac1a3c0d4236d2a6335" integrity sha512-PY6Ii8o1jMRA1z4F2hRkH/xN59ox43DavKvD3oDpfurRlOJyAHpifIwpbdv1n4jt4ov0jSpw3kQ4GhJnpBL6WQ== dependencies: minimatch "^3.0.4" -ignore@^5.1.4: +ignore@5.1.8, ignore@^5.1.4: version "5.1.8" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== +ignore@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" + integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== + image-size@~0.5.0: version "0.5.5" resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.5.5.tgz#09dfd4ab9d20e29eb1c3e80b8990378df9e3cb9c" integrity sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w= -import-cwd@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/import-cwd/-/import-cwd-2.1.0.tgz#aa6cf36e722761285cb371ec6519f53e2435b0a9" - integrity sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk= - dependencies: - import-from "^2.1.0" - -import-fresh@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" - integrity sha1-2BNVwVYS04bGH53dOSLUMEgipUY= - dependencies: - caller-path "^2.0.0" - resolve-from "^3.0.0" - -import-from@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/import-from/-/import-from-2.1.0.tgz#335db7f2a7affd53aaa471d4b8021dee36b7f3b1" - integrity sha1-M1238qev/VOqpHHUuAId7ja387E= +import-fresh@^3.0.0, import-fresh@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== dependencies: - resolve-from "^3.0.0" + parent-module "^1.0.0" + resolve-from "^4.0.0" import-local@^2.0.0: version "2.0.0" @@ -4295,10 +4706,10 @@ inherits@2.0.3: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= -ini@1.3.6: - version "1.3.6" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.6.tgz#f1c46a2a93a253e7b3905115e74d527cd23061a1" - integrity sha512-IZUoxEjNjubzrmvzZU4lKP7OnYmX72XRl3sqkfJhBKweKi5rnGi5+IUdlj/H1M+Ip5JQ1WzaDMOBRY90Ajc5jg== +ini@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ini/-/ini-2.0.0.tgz#e5fd556ecdd5726be978fa1001862eacb0a94bc5" + integrity sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA== inquirer@7.3.3: version "7.3.3" @@ -4327,19 +4738,12 @@ internal-ip@^4.3.0: default-gateway "^4.2.0" ipaddr.js "^1.9.0" -invariant@^2.2.2: - version "2.2.4" - resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" - integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== - dependencies: - loose-envify "^1.0.0" - ip-regex@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" integrity sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk= -ip@1.1.5, ip@^1.1.0, ip@^1.1.5: +ip@^1.1.0, ip@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= @@ -4349,11 +4753,6 @@ ipaddr.js@1.9.1, ipaddr.js@^1.9.0: resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== -is-absolute-url@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6" - integrity sha1-UFMN+4T8yap9vnhS6Do3uTufKqY= - is-absolute-url@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-3.0.3.tgz#96c6a22b6a23929b11ea0afb1836c36ad4a5d698" @@ -4426,7 +4825,7 @@ is-callable@^1.1.4, is-callable@^1.2.3: resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.3.tgz#8b1e0500b73a1d76c70487636f368e519de8db8e" integrity sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ== -is-color-stop@^1.0.0: +is-color-stop@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-color-stop/-/is-color-stop-1.1.0.tgz#cfff471aee4dd5c9e158598fbe12967b5cdad345" integrity sha1-z/9HGu5N1cnhWFmPvhKWe1za00U= @@ -4438,7 +4837,7 @@ is-color-stop@^1.0.0: rgb-regex "^1.0.1" rgba-regex "^1.0.0" -is-core-module@^2.2.0: +is-core-module@^2.1.0, is-core-module@^2.2.0: version "2.4.0" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.4.0.tgz#8e9fc8e15027b011418026e98f0e6f4d86305cc1" integrity sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A== @@ -4482,11 +4881,6 @@ is-descriptor@^1.0.0, is-descriptor@^1.0.2: is-data-descriptor "^1.0.0" kind-of "^6.0.2" -is-directory@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" - integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= - is-docker@^2.0.0: version "2.2.1" resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" @@ -4509,6 +4903,13 @@ is-extglob@^2.1.0, is-extglob@^2.1.1: resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= + dependencies: + number-is-nan "^1.0.0" + is-fullwidth-code-point@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" @@ -4538,6 +4939,11 @@ is-interactive@^1.0.0: resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== +is-lambda@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-lambda/-/is-lambda-1.0.1.tgz#3d9877899e6a53efc0160504cde15f82e6f061d5" + integrity sha1-PZh3iZ5qU+/AFgUEzeFfgubwYdU= + is-map@^2.0.1, is-map@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.2.tgz#00922db8c9bf73e81b7a335827bc2a43f2b91127" @@ -4589,11 +4995,6 @@ is-path-inside@^2.1.0: dependencies: path-is-inside "^1.0.2" -is-plain-obj@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" - integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= - is-plain-object@^2.0.3, is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" @@ -4609,7 +5010,7 @@ is-regex@^1.0.4, is-regex@^1.1.1, is-regex@^1.1.2: call-bind "^1.0.2" has-symbols "^1.0.2" -is-resolvable@^1.0.0: +is-resolvable@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg== @@ -4736,16 +5137,7 @@ istanbul-lib-instrument@^4.0.3: istanbul-lib-coverage "^3.0.0" semver "^6.3.0" -jest-worker@26.3.0: - version "26.3.0" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.3.0.tgz#7c8a97e4f4364b4f05ed8bca8ca0c24de091871f" - integrity sha512-Vmpn2F6IASefL+DVBhPzI2J9/GJUsqzomdeN+P+dK8/jKxbh8R3BtFnx3FIta7wYlPU62cpJMJQo4kuOowcMnw== - dependencies: - "@types/node" "*" - merge-stream "^2.0.0" - supports-color "^7.0.0" - -jest-worker@^26.3.0: +jest-worker@26.6.2, jest-worker@^26.5.0: version "26.6.2" resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ== @@ -4759,7 +5151,7 @@ jquery@^3.5.1: resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.6.0.tgz#c72a09f15c1bdce142f49dbf1170bdf8adac2470" integrity sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw== -"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: +js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== @@ -4777,6 +5169,11 @@ jsbn@~0.1.0: resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= +jsdoctypeparser@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/jsdoctypeparser/-/jsdoctypeparser-9.0.0.tgz#8c97e2fb69315eb274b0f01377eaa5c940bd7b26" + integrity sha512-jrTA2jJIL6/DAEILBEh2/w9QxCuwmvNXIry39Ay/HVfhE3o2yVV0U44blYkqdHA/OKloJEqvJy0xU+GSdE2SIw== + jsesc@^2.5.1: version "2.5.2" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" @@ -4787,7 +5184,7 @@ jsesc@~0.5.0: resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= -json-parse-better-errors@^1.0.0, json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: +json-parse-better-errors@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== @@ -4802,17 +5199,27 @@ json-schema-traverse@^0.4.1: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + json-schema@0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + json-stringify-safe@~5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= -json3@^3.3.2: +json3@^3.3.3: version "3.3.3" resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81" integrity sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA== @@ -4831,10 +5238,10 @@ json5@^2.1.2: dependencies: minimist "^1.2.5" -jsonc-parser@2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-2.3.0.tgz#7c7fc988ee1486d35734faaaa866fadb00fa91ee" - integrity sha512-b0EBt8SWFNnixVdvoR2ZtEGa9ZqLhbJnOjezn+WP+8kspFm+PFYDN8Z4Bc7pRlDjvuVcADSUkroIuTWWn/YiIA== +jsonc-parser@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.0.0.tgz#abdd785701c7e7eaca8a9ec8cf070ca51a745a22" + integrity sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA== jsonfile@^4.0.0: version "4.0.0" @@ -4843,7 +5250,7 @@ jsonfile@^4.0.0: optionalDependencies: graceful-fs "^4.1.6" -jsonparse@^1.2.0: +jsonparse@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" integrity sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA= @@ -4899,27 +5306,27 @@ kind-of@^6.0.0, kind-of@^6.0.2: resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== -klona@^2.0.3: +klona@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.4.tgz#7bb1e3affb0cb8624547ef7e8f6708ea2e39dfc0" integrity sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA== -less-loader@6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/less-loader/-/less-loader-6.2.0.tgz#8b26f621c155b342eefc24f5bd6e9dc40c42a719" - integrity sha512-Cl5h95/Pz/PWub/tCBgT1oNMFeH1WTD33piG80jn5jr12T4XbxZcjThwNXDQ7AG649WEynuIzO4b0+2Tn9Qolg== +less-loader@7.3.0: + version "7.3.0" + resolved "https://registry.yarnpkg.com/less-loader/-/less-loader-7.3.0.tgz#f9d6d36d18739d642067a05fb5bd70c8c61317e5" + integrity sha512-Mi8915g7NMaLlgi77mgTTQvK022xKRQBIVDSyfl3ErTuBhmZBQab0mjeJjNNqGbdR+qrfTleKXqbGI4uEFavxg== dependencies: - clone "^2.1.2" - less "^3.11.3" + klona "^2.0.4" loader-utils "^2.0.0" - schema-utils "^2.7.0" + schema-utils "^3.0.0" -less@^3.11.3: - version "3.13.1" - resolved "https://registry.yarnpkg.com/less/-/less-3.13.1.tgz#0ebc91d2a0e9c0c6735b83d496b0ab0583077909" - integrity sha512-SwA1aQXGUvp+P5XdZslUOhhLnClSLIjWvJhmd+Vgib5BFIr9lMNlQwmwUNOjXThF/A0x+MCYYPeWEfeWiLRnTw== +less@4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/less/-/less-4.1.1.tgz#15bf253a9939791dc690888c3ff424f3e6c7edba" + integrity sha512-w09o8tZFPThBscl5d0Ggp3RcrKIouBoQscnOMgFH3n5V3kN/CXGHNfCkRPtxJk6nKryDXaV9aHLK55RXuH4sAw== dependencies: copy-anything "^2.0.1" + parse-node-version "^1.0.1" tslib "^1.10.0" optionalDependencies: errno "^0.1.1" @@ -4927,29 +5334,40 @@ less@^3.11.3: image-size "~0.5.0" make-dir "^2.1.0" mime "^1.4.1" - native-request "^1.0.5" + needle "^2.5.2" source-map "~0.6.0" -leven@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" - integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== - -levenary@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/levenary/-/levenary-1.1.1.tgz#842a9ee98d2075aa7faeedbe32679e9205f46f77" - integrity sha512-mkAdOIt79FD6irqjYSs4rdbnlT5vRonMEvBVPVb3XmevfS8kgRXwfes0dhPdEtzTWD/1eNE/Bm/G1iRt6DcnQQ== +levn@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== dependencies: - leven "^3.1.0" + prelude-ls "^1.2.1" + type-check "~0.4.0" -license-webpack-plugin@2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/license-webpack-plugin/-/license-webpack-plugin-2.3.0.tgz#c00f70d5725ba0408de208acb9e66612cc2eceda" - integrity sha512-JK/DXrtN6UeYQSgkg5q1+pgJ8aiKPL9tnz9Wzw+Ikkf+8mJxG56x6t8O+OH/tAeF/5NREnelTEMyFtbJNkjH4w== +license-webpack-plugin@2.3.11: + version "2.3.11" + resolved "https://registry.yarnpkg.com/license-webpack-plugin/-/license-webpack-plugin-2.3.11.tgz#0d93188a31fce350a44c86212badbaf33dcd29d8" + integrity sha512-0iVGoX5vx0WDy8dmwTTpOOMYiGqILyUbDeVMFH52AjgBlS58lHwOlFMSoqg5nY8Kxl6+FRKyUZY/UdlQaOyqDw== dependencies: "@types/webpack-sources" "^0.1.5" webpack-sources "^1.2.0" +lines-and-columns@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" + integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= + +load-json-file@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" + integrity sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg= + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + strip-bom "^3.0.0" + loader-runner@^2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" @@ -4973,7 +5391,7 @@ loader-utils@2.0.0, loader-utils@^2.0.0: emojis-list "^3.0.0" json5 "^2.1.2" -loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.3, loader-utils@^1.4.0: +loader-utils@^1.1.0, loader-utils@^1.2.3, loader-utils@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613" integrity sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA== @@ -4982,6 +5400,14 @@ loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.3, loader-utils@^1.4 emojis-list "^3.0.0" json5 "^1.0.1" +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + locate-path@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" @@ -5007,12 +5433,17 @@ lodash.memoize@^4.1.2: resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= +lodash.truncate@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" + integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM= + lodash.uniq@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= -lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.7.0: +lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -5030,13 +5461,6 @@ loglevel@^1.6.8: resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.7.1.tgz#005fde2f5e6e47068f935ff28573e125ef72f197" integrity sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw== -loose-envify@^1.0.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" - integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== - dependencies: - js-tokens "^3.0.0 || ^4.0.0" - lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" @@ -5066,29 +5490,33 @@ make-dir@^2.0.0, make-dir@^2.1.0: pify "^4.0.1" semver "^5.6.0" -make-dir@^3.0.2: +make-dir@^3.0.2, make-dir@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== dependencies: semver "^6.0.0" -make-fetch-happen@^5.0.0: - version "5.0.2" - resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-5.0.2.tgz#aa8387104f2687edca01c8687ee45013d02d19bd" - integrity sha512-07JHC0r1ykIoruKO8ifMXu+xEU8qOXDFETylktdug6vJDACnP+HKevOu3PXyNPzFyTSlz8vrBYlBO1JZRe8Cag== +make-fetch-happen@^8.0.9: + version "8.0.14" + resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-8.0.14.tgz#aaba73ae0ab5586ad8eaa68bd83332669393e222" + integrity sha512-EsS89h6l4vbfJEtBZnENTOFk8mCRpY5ru36Xe5bcX1KYIli2mkSHqoFsp5O1wMDvTJJzxe/4THpCTtygjeeGWQ== dependencies: - agentkeepalive "^3.4.1" - cacache "^12.0.0" - http-cache-semantics "^3.8.1" - http-proxy-agent "^2.1.0" - https-proxy-agent "^2.2.3" - lru-cache "^5.1.1" - mississippi "^3.0.0" - node-fetch-npm "^2.0.2" - promise-retry "^1.1.1" - socks-proxy-agent "^4.0.0" - ssri "^6.0.0" + agentkeepalive "^4.1.3" + cacache "^15.0.5" + http-cache-semantics "^4.1.0" + http-proxy-agent "^4.0.1" + https-proxy-agent "^5.0.0" + is-lambda "^1.0.1" + lru-cache "^6.0.0" + minipass "^3.1.3" + minipass-collect "^1.0.2" + minipass-fetch "^1.3.2" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.4" + promise-retry "^2.0.1" + socks-proxy-agent "^5.0.0" + ssri "^8.0.0" map-cache@^0.2.2: version "0.2.2" @@ -5121,11 +5549,6 @@ mdn-data@2.0.14: resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50" integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow== -mdn-data@2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.4.tgz#699b3c38ac6f1d728091a64650b65d388502fd5b" - integrity sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA== - media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" @@ -5236,14 +5659,13 @@ mimic-fn@^2.1.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== -mini-css-extract-plugin@0.10.0: - version "0.10.0" - resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-0.10.0.tgz#a0e6bfcad22a9c73f6c882a3c7557a98e2d3d27d" - integrity sha512-QgKgJBjaJhxVPwrLNqqwNS0AGkuQQ31Hp4xGXEK/P7wehEg6qmNtReHKai3zRXqY60wGVWLYcOMJK2b98aGc3A== +mini-css-extract-plugin@1.3.5: + version "1.3.5" + resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-1.3.5.tgz#252166e78879c106e0130f229d44e0cbdfcebed3" + integrity sha512-tvmzcwqJJXau4OQE5vT72pRT18o2zF+tQJp8CWchqvfQnTlflkzS+dANYcRdyPRWUWRkfmeNTKltx0NZI/b5dQ== dependencies: - loader-utils "^1.1.0" - normalize-url "1.9.1" - schema-utils "^1.0.0" + loader-utils "^2.0.0" + schema-utils "^3.0.0" webpack-sources "^1.1.0" minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: @@ -5275,6 +5697,17 @@ minipass-collect@^1.0.2: dependencies: minipass "^3.0.0" +minipass-fetch@^1.3.0, minipass-fetch@^1.3.2: + version "1.3.3" + resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-1.3.3.tgz#34c7cea038c817a8658461bf35174551dce17a0a" + integrity sha512-akCrLDWfbdAWkMLBxJEeWTdNsjML+dt5YgOI4gJ53vuO0vrmYQkUPxa6j6V65s9CcePIr2SSWqjT2EcrNseryQ== + dependencies: + minipass "^3.1.0" + minipass-sized "^1.0.3" + minizlib "^2.0.0" + optionalDependencies: + encoding "^0.1.12" + minipass-flush@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/minipass-flush/-/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373" @@ -5282,36 +5715,36 @@ minipass-flush@^1.0.5: dependencies: minipass "^3.0.0" -minipass-pipeline@^1.2.2: +minipass-json-stream@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minipass-json-stream/-/minipass-json-stream-1.0.1.tgz#7edbb92588fbfc2ff1db2fc10397acb7b6b44aa7" + integrity sha512-ODqY18UZt/I8k+b7rl2AENgbWE8IDYam+undIJONvigAz8KR5GWblsFTEfQs0WODsjbSXWlm+JHEv8Gr6Tfdbg== + dependencies: + jsonparse "^1.3.1" + minipass "^3.0.0" + +minipass-pipeline@^1.2.2, minipass-pipeline@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz#68472f79711c084657c067c5c6ad93cddea8214c" integrity sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A== dependencies: minipass "^3.0.0" -minipass@^2.3.5, minipass@^2.6.0, minipass@^2.8.6, minipass@^2.9.0: - version "2.9.0" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" - integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== +minipass-sized@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/minipass-sized/-/minipass-sized-1.0.3.tgz#70ee5a7c5052070afacfbc22977ea79def353b70" + integrity sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g== dependencies: - safe-buffer "^5.1.2" - yallist "^3.0.0" + minipass "^3.0.0" -minipass@^3.0.0, minipass@^3.1.1: +minipass@^3.0.0, minipass@^3.1.0, minipass@^3.1.1, minipass@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.3.tgz#7d42ff1f39635482e15f9cdb53184deebd5815fd" integrity sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg== dependencies: yallist "^4.0.0" -minizlib@^1.2.1: - version "1.3.3" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d" - integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q== - dependencies: - minipass "^2.9.0" - -minizlib@^2.1.1: +minizlib@^2.0.0, minizlib@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== @@ -5343,7 +5776,7 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" -mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.5, mkdirp@~0.5.1: +mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.5: version "0.5.5" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== @@ -5415,6 +5848,11 @@ nan@^2.12.1: resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19" integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ== +nanoid@^3.1.22: + version "3.1.23" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.23.tgz#f744086ce7c2bc47ee0a8472574d5c78e4183a81" + integrity sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw== + nanomatch@^1.2.9: version "1.2.13" resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" @@ -5432,10 +5870,19 @@ nanomatch@^1.2.9: snapdragon "^0.8.1" to-regex "^3.0.1" -native-request@^1.0.5: - version "1.0.8" - resolved "https://registry.yarnpkg.com/native-request/-/native-request-1.0.8.tgz#8f66bf606e0f7ea27c0e5995eb2f5d03e33ae6fb" - integrity sha512-vU2JojJVelUGp6jRcLwToPoWGxSx23z/0iX+I77J3Ht17rf2INGjrhOoQnjVo60nQd8wVsgzKkPfRXBiVdD2ag== +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= + +needle@^2.5.2: + version "2.6.0" + resolved "https://registry.yarnpkg.com/needle/-/needle-2.6.0.tgz#24dbb55f2509e2324b4a99d61f413982013ccdbe" + integrity sha512-KKYdza4heMsEfSWD7VPUIz3zX2XDwOyX2d+geb4vrERZMT5RMU6ujjaD+I5Yr54uZxQ2w6XRTAhHBbSCyovZBg== + dependencies: + debug "^3.2.6" + iconv-lite "^0.4.4" + sax "^1.2.4" negotiator@0.6.2: version "0.6.2" @@ -5465,20 +5912,27 @@ nice-try@^1.0.4: resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== -node-fetch-npm@^2.0.2: - version "2.0.4" - resolved "https://registry.yarnpkg.com/node-fetch-npm/-/node-fetch-npm-2.0.4.tgz#6507d0e17a9ec0be3bec516958a497cec54bf5a4" - integrity sha512-iOuIQDWDyjhv9qSDrj9aq/klt6F9z1p2otB3AV7v3zBDcL/x+OfGsvGQZZCcMZbUf4Ujw1xGNQkjvGnVT22cKg== - dependencies: - encoding "^0.1.11" - json-parse-better-errors "^1.0.0" - safe-buffer "^5.1.1" - node-forge@^0.10.0: version "0.10.0" resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3" integrity sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA== +node-gyp@^7.1.0: + version "7.1.2" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-7.1.2.tgz#21a810aebb187120251c3bcec979af1587b188ae" + integrity sha512-CbpcIo7C3eMu3dL1c3d0xw449fHIGALIJsRP4DDPHpyiW8vcriNY7ubh9TE4zEKfSxscY7PjeFnshE7h75ynjQ== + dependencies: + env-paths "^2.2.0" + glob "^7.1.4" + graceful-fs "^4.2.3" + nopt "^5.0.0" + npmlog "^4.1.2" + request "^2.88.2" + rimraf "^3.0.2" + semver "^7.3.2" + tar "^6.0.2" + which "^2.0.2" + node-libs-browser@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425" @@ -5513,7 +5967,14 @@ node-releases@^1.1.71: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.71.tgz#cb1334b179896b1c89ecfdd4b725fb7bbdfc7dbb" integrity sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg== -normalize-package-data@^2.0.0, normalize-package-data@^2.4.0: +nopt@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88" + integrity sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ== + dependencies: + abbrev "1" + +normalize-package-data@^2.3.2: version "2.5.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== @@ -5540,22 +6001,12 @@ normalize-range@^0.1.2: resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI= -normalize-url@1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-1.9.1.tgz#2cc0d66b31ea23036458436e3620d85954c66c3c" - integrity sha1-LMDWazHqIwNkWENuNiDYWVTGbDw= - dependencies: - object-assign "^4.0.1" - prepend-http "^1.0.0" - query-string "^4.1.0" - sort-keys "^1.0.0" - -normalize-url@^3.0.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-3.3.0.tgz#b2e1c4dc4f7c6d57743df733a4f5978d18650559" - integrity sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg== +normalize-url@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.0.tgz#453354087e6ca96957bd8f5baf753f5982142129" + integrity sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ== -npm-bundled@^1.0.1: +npm-bundled@^1.1.1: version "1.1.2" resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.1.2.tgz#944c78789bd739035b70baa2ca5cc32b8d860bc1" integrity sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ== @@ -5569,31 +6020,21 @@ npm-install-checks@^4.0.0: dependencies: semver "^7.1.1" -npm-normalize-package-bin@^1.0.0, npm-normalize-package-bin@^1.0.1: +npm-normalize-package-bin@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz#6e79a41f23fd235c0623218228da7d9c23b8f6e2" integrity sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA== -npm-package-arg@8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-8.0.1.tgz#9d76f8d7667b2373ffda60bb801a27ef71e3e270" - integrity sha512-/h5Fm6a/exByzFSTm7jAyHbgOqErl9qSNJDQF32Si/ZzgwT2TERVxRxn3Jurw1wflgyVVAxnFR4fRHPM7y1ClQ== +npm-package-arg@8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-8.1.0.tgz#b5f6319418c3246a1c38e1a8fbaa06231bc5308f" + integrity sha512-/ep6QDxBkm9HvOhOg0heitSd7JHA1U7y1qhhlRlteYYAi9Pdb/ZV7FW5aHpkrpM8+P+4p/jjR8zCyKPBMBjSig== dependencies: - hosted-git-info "^3.0.2" + hosted-git-info "^3.0.6" semver "^7.0.0" validate-npm-package-name "^3.0.0" -npm-package-arg@^6.0.0, npm-package-arg@^6.1.0: - version "6.1.1" - resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-6.1.1.tgz#02168cb0a49a2b75bf988a28698de7b529df5cb7" - integrity sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg== - dependencies: - hosted-git-info "^2.7.1" - osenv "^0.1.5" - semver "^5.6.0" - validate-npm-package-name "^3.0.0" - -npm-package-arg@^8.0.0: +npm-package-arg@^8.0.0, npm-package-arg@^8.0.1, npm-package-arg@^8.1.2: version "8.1.2" resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-8.1.2.tgz#b868016ae7de5619e729993fbd8d11dc3c52ab62" integrity sha512-6Eem455JsSMJY6Kpd3EyWE+n5hC+g9bSyHr9K9U2zqZb7+02+hObQ2c0+8iDk/mNF+8r1MhY44WypKJAkySIYA== @@ -5602,13 +6043,14 @@ npm-package-arg@^8.0.0: semver "^7.3.4" validate-npm-package-name "^3.0.0" -npm-packlist@^1.1.12: - version "1.4.8" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.8.tgz#56ee6cc135b9f98ad3d51c1c95da22bbb9b2ef3e" - integrity sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A== +npm-packlist@^2.1.4: + version "2.2.2" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-2.2.2.tgz#076b97293fa620f632833186a7a8f65aaa6148c8" + integrity sha512-Jt01acDvJRhJGthnUJVF/w6gumWOZxO7IkpY/lsX9//zqQgnF7OJaxgQXcerd4uQOLu7W5bkb4mChL9mdfm+Zg== dependencies: - ignore-walk "^3.0.1" - npm-bundled "^1.0.1" + glob "^7.1.6" + ignore-walk "^3.0.3" + npm-bundled "^1.1.1" npm-normalize-package-bin "^1.0.1" npm-pick-manifest@6.1.0: @@ -5620,27 +6062,29 @@ npm-pick-manifest@6.1.0: npm-package-arg "^8.0.0" semver "^7.0.0" -npm-pick-manifest@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-3.0.2.tgz#f4d9e5fd4be2153e5f4e5f9b7be8dc419a99abb7" - integrity sha512-wNprTNg+X5nf+tDi+hbjdHhM4bX+mKqv6XmPh7B5eG+QY9VARfQPfCEH013H5GqfNj6ee8Ij2fg8yk0mzps1Vw== +npm-pick-manifest@^6.0.0, npm-pick-manifest@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-6.1.1.tgz#7b5484ca2c908565f43b7f27644f36bb816f5148" + integrity sha512-dBsdBtORT84S8V8UTad1WlUyKIY9iMsAmqxHbLdeEeBNMLQDlDWWra3wYUx9EBEIiG/YwAy0XyNHDd2goAsfuA== dependencies: - figgy-pudding "^3.5.1" - npm-package-arg "^6.0.0" - semver "^5.4.1" + npm-install-checks "^4.0.0" + npm-normalize-package-bin "^1.0.1" + npm-package-arg "^8.1.2" + semver "^7.3.4" -npm-registry-fetch@^4.0.0: - version "4.0.7" - resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-4.0.7.tgz#57951bf6541e0246b34c9f9a38ab73607c9449d7" - integrity sha512-cny9v0+Mq6Tjz+e0erFAB+RYJ/AVGzkjnISiobqP8OWj9c9FLoZZu8/SPSKJWE17F1tk4018wfjV+ZbIbqC7fQ== +npm-registry-fetch@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-9.0.0.tgz#86f3feb4ce00313bc0b8f1f8f69daae6face1661" + integrity sha512-PuFYYtnQ8IyVl6ib9d3PepeehcUeHN9IO5N/iCRhyg9tStQcqGQBRVHmfmMWPDERU3KwZoHFvbJ4FPXPspvzbA== dependencies: - JSONStream "^1.3.4" - bluebird "^3.5.1" - figgy-pudding "^3.4.1" - lru-cache "^5.1.1" - make-fetch-happen "^5.0.0" - npm-package-arg "^6.1.0" - safe-buffer "^5.2.0" + "@npmcli/ci-detect" "^1.0.0" + lru-cache "^6.0.0" + make-fetch-happen "^8.0.9" + minipass "^3.1.3" + minipass-fetch "^1.3.0" + minipass-json-stream "^1.0.1" + minizlib "^2.0.0" + npm-package-arg "^8.0.0" npm-run-path@^2.0.0: version "2.0.2" @@ -5649,17 +6093,27 @@ npm-run-path@^2.0.0: dependencies: path-key "^2.0.0" -nth-check@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" - integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg== +npmlog@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== dependencies: - boolbase "~1.0.0" + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.3" + set-blocking "~2.0.0" -num2fraction@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" - integrity sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4= +nth-check@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.0.0.tgz#1bb4f6dac70072fc313e8c9cd1417b5074c0a125" + integrity sha512-i4sc/Kj8htBrAiH1viZ0TgU8Y5XqCaV/FziYK6TBczxmeKm3AEFWqqF3195yKudrarqy7Zu80Ra5dobFjn9X/Q== + dependencies: + boolbase "^1.0.0" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= oauth-sign@~0.9.0: version "0.9.0" @@ -5715,15 +6169,6 @@ object.assign@^4.1.0, object.assign@^4.1.2: has-symbols "^1.0.1" object-keys "^1.1.1" -object.getownpropertydescriptors@^2.0.3, object.getownpropertydescriptors@^2.1.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.2.tgz#1bd63aeacf0d5d2d2f31b5e393b03a7c601a23f7" - integrity sha512-WtxeKSzfBjlzL+F9b7M7hewDzMwy+C8NRssHd1YrNlzHzIDrXcXiNOMrezdAEM4UXixgV+vvnyBeN7Rygl2ttQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.18.0-next.2" - object.pick@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" @@ -5731,7 +6176,7 @@ object.pick@^1.3.0: dependencies: isobject "^3.0.1" -object.values@^1.1.0: +object.values@^1.1.1: version "1.1.3" resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.3.tgz#eaa8b1e17589f02f698db093f7c62ee1699742ee" integrity sha512-nkF6PfDB9alkOUxpf1HNm/QlkeW3SReqL5WXeBLpEJJnlPSvRaDQpW3gQTksTN3fgJX4hL42RzKyOin6ff3tyw== @@ -5772,10 +6217,10 @@ onetime@^5.1.0: dependencies: mimic-fn "^2.1.0" -open@7.2.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/open/-/open-7.2.0.tgz#212959bd7b0ce2e8e3676adc76e3cf2f0a2498b4" - integrity sha512-4HeyhxCvBTI5uBePsAdi55C5fmqnWZ2e2MlmvWi5KW5tdH5rxoiv/aMtbeVxKZc3eWkT1GymMnLG8XC4Rq4TDQ== +open@7.4.0: + version "7.4.0" + resolved "https://registry.yarnpkg.com/open/-/open-7.4.0.tgz#ad95b98f871d9acb0ec8fecc557082cc9986626b" + integrity sha512-PGoBCX/lclIWlpS/R2PQuIR4NJoXh6X5AwVzE7WXnWRGvHg7+4TBCgsujUgiPpm0K1y4qvQeWnCWVTpTKZBtvA== dependencies: is-docker "^2.0.0" is-wsl "^2.1.1" @@ -5787,17 +6232,29 @@ opn@^5.5.0: dependencies: is-wsl "^1.1.0" -ora@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/ora/-/ora-5.0.0.tgz#4f0b34f2994877b49b452a707245ab1e9f6afccb" - integrity sha512-s26qdWqke2kjN/wC4dy+IQPBIMWBJlSU/0JZhk30ZDBLelW25rv66yutUWARMigpGPzcXHb+Nac5pNhN/WsARw== +optionator@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" + integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== dependencies: + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" + word-wrap "^1.2.3" + +ora@5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/ora/-/ora-5.3.0.tgz#fb832899d3a1372fe71c8b2c534bbfe74961bb6f" + integrity sha512-zAKMgGXUim0Jyd6CXK9lraBnD3H5yPGBPPOkC23a2BG6hsm4Zu6OQSjQuEtV0BHDf4aKHcUFvJiGRrFuW3MG8g== + dependencies: + bl "^4.0.3" chalk "^4.1.0" cli-cursor "^3.1.0" - cli-spinners "^2.4.0" + cli-spinners "^2.5.0" is-interactive "^1.0.0" log-symbols "^4.0.0" - mute-stream "0.0.8" strip-ansi "^6.0.0" wcwidth "^1.0.1" @@ -5813,29 +6270,23 @@ os-browserify@^0.3.0: resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc= -os-homedir@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" - integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= - -os-tmpdir@^1.0.0, os-tmpdir@~1.0.2: +os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= -osenv@^0.1.5: - version "0.1.5" - resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" - integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== - dependencies: - os-homedir "^1.0.0" - os-tmpdir "^1.0.0" - p-finally@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= +p-limit@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== + dependencies: + p-try "^1.0.0" + p-limit@^2.0.0, p-limit@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" @@ -5843,13 +6294,20 @@ p-limit@^2.0.0, p-limit@^2.2.0: dependencies: p-try "^2.0.0" -p-limit@^3.0.1, p-limit@^3.0.2: +p-limit@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== dependencies: yocto-queue "^0.1.0" +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= + dependencies: + p-limit "^1.1.0" + p-locate@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" @@ -5883,46 +6341,40 @@ p-retry@^3.0.1: dependencies: retry "^0.12.0" +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= + p-try@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== -pacote@9.5.12: - version "9.5.12" - resolved "https://registry.yarnpkg.com/pacote/-/pacote-9.5.12.tgz#1e11dd7a8d736bcc36b375a9804d41bb0377bf66" - integrity sha512-BUIj/4kKbwWg4RtnBncXPJd15piFSVNpTzY0rysSr3VnMowTYgkGKcaHrbReepAkjTr8lH2CVWRi58Spg2CicQ== +pacote@11.2.4: + version "11.2.4" + resolved "https://registry.yarnpkg.com/pacote/-/pacote-11.2.4.tgz#dc7ca740a573ed86a3bf863511d22c1d413ec82f" + integrity sha512-GfTeVQGJ6WyBQbQD4t3ocHbyOmTQLmWjkCKSZPmKiGFKYKNUaM5U2gbLzUW8WG1XmS9yQFnsTFA0k3o1+q4klQ== dependencies: - bluebird "^3.5.3" - cacache "^12.0.2" - chownr "^1.1.2" - figgy-pudding "^3.5.1" - get-stream "^4.1.0" - glob "^7.1.3" + "@npmcli/git" "^2.0.1" + "@npmcli/installed-package-contents" "^1.0.5" + "@npmcli/promise-spawn" "^1.2.0" + "@npmcli/run-script" "^1.3.0" + cacache "^15.0.5" + chownr "^2.0.0" + fs-minipass "^2.1.0" infer-owner "^1.0.4" - lru-cache "^5.1.1" - make-fetch-happen "^5.0.0" - minimatch "^3.0.4" - minipass "^2.3.5" - mississippi "^3.0.0" - mkdirp "^0.5.1" - normalize-package-data "^2.4.0" - npm-normalize-package-bin "^1.0.0" - npm-package-arg "^6.1.0" - npm-packlist "^1.1.12" - npm-pick-manifest "^3.0.0" - npm-registry-fetch "^4.0.0" - osenv "^0.1.5" - promise-inflight "^1.0.1" + minipass "^3.1.3" + mkdirp "^1.0.3" + npm-package-arg "^8.0.1" + npm-packlist "^2.1.4" + npm-pick-manifest "^6.0.0" + npm-registry-fetch "^9.0.0" promise-retry "^1.1.1" - protoduck "^5.0.1" - rimraf "^2.6.2" - safe-buffer "^5.1.2" - semver "^5.6.0" - ssri "^6.0.1" - tar "^4.4.10" - unique-filename "^1.1.1" - which "^1.3.1" + read-package-json-fast "^1.1.3" + rimraf "^3.0.2" + ssri "^8.0.0" + tar "^6.1.0" pako@~1.0.5: version "1.0.11" @@ -5938,6 +6390,13 @@ parallel-transform@^1.1.0: inherits "^2.0.3" readable-stream "^2.1.5" +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + parse-asn1@^5.0.0, parse-asn1@^5.1.5: version "5.1.6" resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.6.tgz#385080a3ec13cb62a62d39409cb3e88844cdaed4" @@ -5949,22 +6408,51 @@ parse-asn1@^5.0.0, parse-asn1@^5.1.5: pbkdf2 "^3.0.3" safe-buffer "^5.1.1" -parse-json@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" - integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= dependencies: + error-ex "^1.2.0" + +parse-json@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== + dependencies: + "@babel/code-frame" "^7.0.0" error-ex "^1.3.1" - json-parse-better-errors "^1.0.1" + json-parse-even-better-errors "^2.3.0" + lines-and-columns "^1.1.6" + +parse-node-version@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parse-node-version/-/parse-node-version-1.0.1.tgz#e2b5dbede00e7fa9bc363607f53327e8b073189b" + integrity sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA== + +parse5-html-rewriting-stream@6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5-html-rewriting-stream/-/parse5-html-rewriting-stream-6.0.1.tgz#de1820559317ab4e451ea72dba05fddfd914480b" + integrity sha512-vwLQzynJVEfUlURxgnf51yAJDQTtVpNyGD8tKi2Za7m+akukNHxCcUQMAa/mUGLhCeicFdpy7Tlvj8ZNKadprg== + dependencies: + parse5 "^6.0.1" + parse5-sax-parser "^6.0.1" -parse5-htmlparser2-tree-adapter@6.0.1: +parse5-htmlparser2-tree-adapter@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz#2cdf9ad823321140370d4dbf5d3e92c7c8ddc6e6" integrity sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA== dependencies: parse5 "^6.0.1" -parse5@6.0.1, parse5@^6.0.1: +parse5-sax-parser@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5-sax-parser/-/parse5-sax-parser-6.0.1.tgz#98b4d366b5b266a7cd90b4b58906667af882daba" + integrity sha512-kXX+5S81lgESA0LsDuGjAlBybImAChYRMT+/uKCEXFBFOeEhS52qUCydGhU3qLRD8D9DVjaUo821WK7DM4iCeg== + dependencies: + parse5 "^6.0.1" + +parse5@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== @@ -6014,6 +6502,11 @@ path-key@^2.0.0, path-key@^2.0.1: resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= +path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + path-parse@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" @@ -6024,6 +6517,13 @@ path-to-regexp@0.1.7: resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= +path-type@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" + integrity sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM= + dependencies: + pify "^2.0.0" + path-type@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" @@ -6072,6 +6572,13 @@ pinkie@^2.0.0: resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= +pkg-dir@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" + integrity sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s= + dependencies: + find-up "^2.1.0" + pkg-dir@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" @@ -6112,296 +6619,245 @@ posix-character-classes@^0.1.0: resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= -postcss-calc@^7.0.1: - version "7.0.5" - resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-7.0.5.tgz#f8a6e99f12e619c2ebc23cf6c486fdc15860933e" - integrity sha512-1tKHutbGtLtEZF6PT4JSihCHfIVldU72mZ8SdZHIYriIZ9fh9k9aWSppaT8rHsyI3dX+KSR+W+Ix9BMY3AODrg== +postcss-calc@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-8.0.0.tgz#a05b87aacd132740a5db09462a3612453e5df90a" + integrity sha512-5NglwDrcbiy8XXfPM11F3HeC6hoT9W7GUH/Zi5U/p7u3Irv4rHhdDcIZwG0llHXV4ftsBjpfWMXAnXNl4lnt8g== dependencies: - postcss "^7.0.27" postcss-selector-parser "^6.0.2" postcss-value-parser "^4.0.2" -postcss-colormin@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-4.0.3.tgz#ae060bce93ed794ac71264f08132d550956bd381" - integrity sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw== +postcss-colormin@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-5.0.0.tgz#283b8934c8bdbc531e7648aeb0970107f6d06d0e" + integrity sha512-Yt84+5V6CgS/AhK7d7MA58vG8dSZ7+ytlRtWLaQhag3HXOncTfmYpuUOX4cDoXjvLfw1sHRCHMiBjYhc35CymQ== dependencies: - browserslist "^4.0.0" - color "^3.0.0" - has "^1.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" + browserslist "^4.16.0" + color "^3.1.1" + postcss-value-parser "^4.1.0" -postcss-convert-values@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz#ca3813ed4da0f812f9d43703584e449ebe189a7f" - integrity sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ== +postcss-convert-values@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-5.0.0.tgz#cd77e1d23ebe8fcf508640551eed08e232784cba" + integrity sha512-V5kmYm4xoBAjNs+eHY/6XzXJkkGeg4kwNf2ocfqhLb1WBPEa4oaSmoi1fnVO7Dkblqvus9h+AenDvhCKUCK7uQ== dependencies: - postcss "^7.0.0" - postcss-value-parser "^3.0.0" + postcss-value-parser "^4.1.0" -postcss-discard-comments@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz#1fbabd2c246bff6aaad7997b2b0918f4d7af4033" - integrity sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg== - dependencies: - postcss "^7.0.0" +postcss-discard-comments@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-5.0.0.tgz#6c27310e0657c0b9e38a6175ad001b5aa28964bc" + integrity sha512-Umig6Gxs8m20RihiXY6QkePd6mp4FxkA1Dg+f/Kd6uw0gEMfKRjDeQOyFkLibexbJJGHpE3lrN/Q0R9SMrUMbQ== -postcss-discard-duplicates@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz#3fe133cd3c82282e550fc9b239176a9207b784eb" - integrity sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ== - dependencies: - postcss "^7.0.0" +postcss-discard-duplicates@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-5.0.0.tgz#6a2c4f779e8d20da6781e90730f234f9e650c51c" + integrity sha512-vEJJ+Y3pFUnO1FyCBA6PSisGjHtnphL3V6GsNvkASq/VkP3OX5/No5RYXXLxHa2QegStNzg6HYrYdo71uR4caQ== -postcss-discard-empty@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz#c8c951e9f73ed9428019458444a02ad90bb9f765" - integrity sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w== - dependencies: - postcss "^7.0.0" +postcss-discard-empty@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-5.0.0.tgz#0f0a9baee415f5f7be4ae046ba235e98626ba821" + integrity sha512-+wigy099Y1xZxG36WG5L1f2zeH1oicntkJEW4TDIqKKDO2g9XVB3OhoiHTu08rDEjLnbcab4rw0BAccwi2VjiQ== -postcss-discard-overridden@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz#652aef8a96726f029f5e3e00146ee7a4e755ff57" - integrity sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg== - dependencies: - postcss "^7.0.0" +postcss-discard-overridden@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-5.0.0.tgz#ac00f695a60001eda52135a11fac87376b8da9ee" + integrity sha512-hybnScTaZM2iEA6kzVQ6Spozy7kVdLw+lGw8hftLlBEzt93uzXoltkYp9u0tI8xbfhxDLTOOzHsHQCkYdmzRUg== -postcss-import@12.0.1: - version "12.0.1" - resolved "https://registry.yarnpkg.com/postcss-import/-/postcss-import-12.0.1.tgz#cf8c7ab0b5ccab5649024536e565f841928b7153" - integrity sha512-3Gti33dmCjyKBgimqGxL3vcV8w9+bsHwO5UrBawp796+jdardbcFl4RP5w/76BwNL7aGzpKstIfF9I+kdE8pTw== +postcss-import@14.0.0: + version "14.0.0" + resolved "https://registry.yarnpkg.com/postcss-import/-/postcss-import-14.0.0.tgz#3ed1dadac5a16650bde3f4cdea6633b9c3c78296" + integrity sha512-gFDDzXhqr9ELmnLHgCC3TbGfA6Dm/YMb/UN8/f7Uuq4fL7VTk2vOIj6hwINEwbokEmp123bLD7a5m+E+KIetRg== dependencies: - postcss "^7.0.1" - postcss-value-parser "^3.2.3" + postcss-value-parser "^4.0.0" read-cache "^1.0.0" resolve "^1.1.7" -postcss-load-config@^2.0.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-2.1.2.tgz#c5ea504f2c4aef33c7359a34de3573772ad7502a" - integrity sha512-/rDeGV6vMUo3mwJZmeHfEDvwnTKKqQ0S7OHUi/kJvvtx3aWtyWG2/0ZWnzCt2keEclwN6Tf0DST2v9kITdOKYw== - dependencies: - cosmiconfig "^5.0.0" - import-cwd "^2.0.0" - -postcss-loader@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-3.0.0.tgz#6b97943e47c72d845fa9e03f273773d4e8dd6c2d" - integrity sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA== +postcss-loader@4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-4.2.0.tgz#f6993ea3e0f46600fb3ee49bbd010448123a7db4" + integrity sha512-mqgScxHqbiz1yxbnNcPdKYo/6aVt+XExURmEbQlviFVWogDbM4AJ0A/B+ZBpYsJrTRxKw7HyRazg9x0Q9SWwLA== dependencies: - loader-utils "^1.1.0" - postcss "^7.0.0" - postcss-load-config "^2.0.0" - schema-utils "^1.0.0" + cosmiconfig "^7.0.0" + klona "^2.0.4" + loader-utils "^2.0.0" + schema-utils "^3.0.0" + semver "^7.3.4" -postcss-merge-longhand@^4.0.11: - version "4.0.11" - resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz#62f49a13e4a0ee04e7b98f42bb16062ca2549e24" - integrity sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw== +postcss-merge-longhand@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-5.0.1.tgz#1a008ff72d14cd3e2f3d32accc2ad37948bcabf4" + integrity sha512-H1RO8le5deFGumQzuhJjuL0bIXPRysa+w7xtk5KrHe38oiaSS9ksPXDo24+IOS3SETPhip0J5+1uCOW+ALs3Yw== dependencies: - css-color-names "0.0.4" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - stylehacks "^4.0.0" + css-color-names "^1.0.1" + postcss-value-parser "^4.1.0" + stylehacks "^5.0.0" -postcss-merge-rules@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz#362bea4ff5a1f98e4075a713c6cb25aefef9a650" - integrity sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ== +postcss-merge-rules@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-5.0.0.tgz#e0d0c0d45c98376f4adb49eb1f1dfe2aebfd7048" + integrity sha512-TfsXbKjNYCGfUPEXGIGPySnMiJbdS+3gcVeV8gwmJP4RajyKZHW8E0FYDL1WmggTj3hi+m+WUCAvqRpX2ut4Kg== dependencies: - browserslist "^4.0.0" + browserslist "^4.16.0" caniuse-api "^3.0.0" - cssnano-util-same-parent "^4.0.0" - postcss "^7.0.0" - postcss-selector-parser "^3.0.0" - vendors "^1.0.0" + cssnano-utils "^2.0.0" + postcss-selector-parser "^6.0.4" + vendors "^1.0.3" -postcss-minify-font-values@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz#cd4c344cce474343fac5d82206ab2cbcb8afd5a6" - integrity sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg== +postcss-minify-font-values@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-5.0.0.tgz#fee5d0fa192fae8757cb744870a0ad02be5f402e" + integrity sha512-zi2JhFaMOcIaNxhndX5uhsqSY1rexKDp23wV8EOmC9XERqzLbHsoRye3aYF716Zm+hkcR4loqKDt8LZlmihwAg== dependencies: - postcss "^7.0.0" - postcss-value-parser "^3.0.0" + postcss-value-parser "^4.1.0" -postcss-minify-gradients@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz#93b29c2ff5099c535eecda56c4aa6e665a663471" - integrity sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q== +postcss-minify-gradients@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-5.0.0.tgz#95dbe61567a45c0cd7ab897d78fb65d5096844ed" + integrity sha512-/jPtNgs6JySMwgsE5dPOq8a2xEopWTW3RyqoB9fLqxgR+mDUNLSi7joKd+N1z7FXWgVkc4l/dEBMXHgNAaUbvg== dependencies: - cssnano-util-get-arguments "^4.0.0" - is-color-stop "^1.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" + cssnano-utils "^2.0.0" + is-color-stop "^1.1.0" + postcss-value-parser "^4.1.0" -postcss-minify-params@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz#6b9cef030c11e35261f95f618c90036d680db874" - integrity sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg== +postcss-minify-params@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-5.0.0.tgz#12c7f75d69b0b4827fafbd6649970a53784a9c24" + integrity sha512-KvZYIxTPBVKjdd+XgObq9A+Sfv8lMkXTpbZTsjhr42XbfWIeLaTItMlygsDWfjArEc3muUfDaUFgNSeDiJ5jug== dependencies: - alphanum-sort "^1.0.0" - browserslist "^4.0.0" - cssnano-util-get-arguments "^4.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" + alphanum-sort "^1.0.2" + browserslist "^4.16.0" + cssnano-utils "^2.0.0" + postcss-value-parser "^4.1.0" uniqs "^2.0.0" -postcss-minify-selectors@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz#e2e5eb40bfee500d0cd9243500f5f8ea4262fbd8" - integrity sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g== +postcss-minify-selectors@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-5.0.0.tgz#d3e43d97fd0ba83ba0010950fc5acfa420f7caa9" + integrity sha512-cEM0O0eWwFIvmo6nfB0lH0vO/XFwgqIvymODbfPXZ1gTA3i76FKnb7TGUrEpiTxaXH6tgYQ6DcTHwRiRS+YQLQ== dependencies: - alphanum-sort "^1.0.0" - has "^1.0.0" - postcss "^7.0.0" - postcss-selector-parser "^3.0.0" + alphanum-sort "^1.0.2" + postcss-selector-parser "^3.1.2" -postcss-modules-extract-imports@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz#818719a1ae1da325f9832446b01136eeb493cd7e" - integrity sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ== - dependencies: - postcss "^7.0.5" +postcss-modules-extract-imports@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz#cda1f047c0ae80c97dbe28c3e76a43b88025741d" + integrity sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw== -postcss-modules-local-by-default@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.3.tgz#bb14e0cc78279d504dbdcbfd7e0ca28993ffbbb0" - integrity sha512-e3xDq+LotiGesympRlKNgaJ0PCzoUIdpH0dj47iWAui/kyTgh3CiAr1qP54uodmJhl6p9rN6BoNcdEDVJx9RDw== +postcss-modules-local-by-default@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz#ebbb54fae1598eecfdf691a02b3ff3b390a5a51c" + integrity sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ== dependencies: - icss-utils "^4.1.1" - postcss "^7.0.32" + icss-utils "^5.0.0" postcss-selector-parser "^6.0.2" postcss-value-parser "^4.1.0" -postcss-modules-scope@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz#385cae013cc7743f5a7d7602d1073a89eaae62ee" - integrity sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ== - dependencies: - postcss "^7.0.6" - postcss-selector-parser "^6.0.0" - -postcss-modules-values@^3.0.0: +postcss-modules-scope@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz#5b5000d6ebae29b4255301b4a3a54574423e7f10" - integrity sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg== + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz#9ef3151456d3bbfa120ca44898dfca6f2fa01f06" + integrity sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg== dependencies: - icss-utils "^4.0.0" - postcss "^7.0.6" + postcss-selector-parser "^6.0.4" -postcss-normalize-charset@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz#8b35add3aee83a136b0471e0d59be58a50285dd4" - integrity sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g== +postcss-modules-values@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz#d7c5e7e68c3bb3c9b27cbf48ca0bb3ffb4602c9c" + integrity sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ== dependencies: - postcss "^7.0.0" + icss-utils "^5.0.0" -postcss-normalize-display-values@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz#0dbe04a4ce9063d4667ed2be476bb830c825935a" - integrity sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ== +postcss-normalize-charset@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-5.0.0.tgz#59e1fe2094fb2e3371cc5b054cbc39828a41a710" + integrity sha512-pqsCkgo9KmQP0ew6DqSA+uP9YN6EfsW20pQ3JU5JoQge09Z6Too4qU0TNDsTNWuEaP8SWsMp+19l15210MsDZQ== + +postcss-normalize-display-values@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-display-values/-/postcss-normalize-display-values-5.0.0.tgz#4ff2d3b3b5146a366de28ec9e24131a1868f1933" + integrity sha512-t4f2d//gH1f7Ns0Jq3eNdnWuPT7TeLuISZ6RQx4j8gpl5XrhkdshdNcOnlrEK48YU6Tcb6jqK7dorME3N4oOGA== dependencies: - cssnano-util-get-match "^4.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" + cssnano-utils "^2.0.0" + postcss-value-parser "^4.1.0" -postcss-normalize-positions@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz#05f757f84f260437378368a91f8932d4b102917f" - integrity sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA== +postcss-normalize-positions@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-5.0.0.tgz#fe1d9a8122dd385b9c6908bd2008140dea17750d" + integrity sha512-0o6/qU5ky74X/eWYj/tv4iiKCm3YqJnrhmVADpIMNXxzFZywsSQxl8F7cKs8jQEtF3VrJBgcDHTexZy1zgDoYg== dependencies: - cssnano-util-get-arguments "^4.0.0" - has "^1.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" + postcss-value-parser "^4.1.0" -postcss-normalize-repeat-style@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz#c4ebbc289f3991a028d44751cbdd11918b17910c" - integrity sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q== +postcss-normalize-repeat-style@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.0.0.tgz#e11d88fbf63f89179c6a7391853b2fe7f46e589d" + integrity sha512-KRT14JbrXKcFMYuc4q7lh8lvv8u22wLyMrq+UpHKLtbx2H/LOjvWXYdoDxmNrrrJzomAWL+ViEXr48/IhSUJnQ== dependencies: - cssnano-util-get-arguments "^4.0.0" - cssnano-util-get-match "^4.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" + cssnano-utils "^2.0.0" + postcss-value-parser "^4.1.0" -postcss-normalize-string@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz#cd44c40ab07a0c7a36dc5e99aace1eca4ec2690c" - integrity sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA== +postcss-normalize-string@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-5.0.0.tgz#2ea08ff4cb8817ce160755e9fdc7e6ef6d495002" + integrity sha512-wSO4pf7GNcDZpmelREWYADF1+XZWrAcbFLQCOqoE92ZwYgaP/RLumkUTaamEzdT2YKRZAH8eLLKGWotU/7FNPw== dependencies: - has "^1.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" + postcss-value-parser "^4.1.0" -postcss-normalize-timing-functions@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz#8e009ca2a3949cdaf8ad23e6b6ab99cb5e7d28d9" - integrity sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A== +postcss-normalize-timing-functions@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.0.0.tgz#380eb1c9b179f96efc307c659a8049116f16f381" + integrity sha512-TwPaDX+wl9wO3MUm23lzGmOzGCGKnpk+rSDgzB2INpakD5dgWR3L6bJq1P1LQYzBAvz8fRIj2NWdnZdV4EV98Q== dependencies: - cssnano-util-get-match "^4.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" + cssnano-utils "^2.0.0" + postcss-value-parser "^4.1.0" -postcss-normalize-unicode@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz#841bd48fdcf3019ad4baa7493a3d363b52ae1cfb" - integrity sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg== +postcss-normalize-unicode@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-5.0.0.tgz#aa46a89c86ae51a01cbca13e73c1ed7b0b38807e" + integrity sha512-2CpVoz/67rXU5s9tsPZDxG1YGS9OFHwoY9gsLAzrURrCxTAb0H7Vp87/62LvVPgRWTa5ZmvgmqTp2rL8tlm72A== dependencies: - browserslist "^4.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" + browserslist "^4.16.0" + postcss-value-parser "^4.1.0" -postcss-normalize-url@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz#10e437f86bc7c7e58f7b9652ed878daaa95faae1" - integrity sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA== +postcss-normalize-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-5.0.0.tgz#626a4c7d30007f94466cdf245e7ed9f253f1dbd9" + integrity sha512-ICDaGFBqLgA3dlrCIRuhblLl80D13YtgEV9NJPTYJtgR72vu61KgxAHv+z/lKMs1EbwfSQa3ALjOFLSmXiE34A== dependencies: - is-absolute-url "^2.0.0" - normalize-url "^3.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" + is-absolute-url "^3.0.3" + normalize-url "^4.5.0" + postcss-value-parser "^4.1.0" -postcss-normalize-whitespace@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz#bf1d4070fe4fcea87d1348e825d8cc0c5faa7d82" - integrity sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA== +postcss-normalize-whitespace@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.0.0.tgz#1faf147a4f8d3d93a3c75109d120b4eefa00589b" + integrity sha512-KRnxQvQAVkJfaeXSz7JlnD9nBN9sFZF9lrk9452Q2uRoqrRSkinqifF8Iex7wZGei2DZVG/qpmDFDmRvbNAOGA== dependencies: - postcss "^7.0.0" - postcss-value-parser "^3.0.0" + postcss-value-parser "^4.1.0" -postcss-ordered-values@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz#0cf75c820ec7d5c4d280189559e0b571ebac0eee" - integrity sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw== +postcss-ordered-values@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-5.0.0.tgz#a50f224c5f40c566b338b0663655478737dcebee" + integrity sha512-dPr+SRObiHueCIc4IUaG0aOGQmYkuNu50wQvdXTGKy+rzi2mjmPsbeDsheLk5WPb9Zyf2tp8E+I+h40cnivm6g== dependencies: - cssnano-util-get-arguments "^4.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" + cssnano-utils "^2.0.0" + postcss-value-parser "^4.1.0" -postcss-reduce-initial@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz#7fd42ebea5e9c814609639e2c2e84ae270ba48df" - integrity sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA== +postcss-reduce-initial@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-5.0.0.tgz#c724e5513b0ae7f3d7bff16f0fc82133fb2f820a" + integrity sha512-wR6pXUaFbSMG1oCKx8pKVA+rnSXCHlca5jMrlmkmif+uig0HNUTV9oGN5kjKsM3mATQAldv2PF9Tbl2vqLFjnA== dependencies: - browserslist "^4.0.0" + browserslist "^4.16.0" caniuse-api "^3.0.0" - has "^1.0.0" - postcss "^7.0.0" -postcss-reduce-transforms@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz#17efa405eacc6e07be3414a5ca2d1074681d4e29" - integrity sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg== +postcss-reduce-transforms@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-5.0.0.tgz#5c820f71fbd4eec82b323523642b7b2d1c7d29ef" + integrity sha512-iHdGODW4YzM3WjVecBhPQt6fpJC4lGQZxJKjkBNHpp2b8dzmvj0ogKThqya+IRodQEFzjfXgYeESkf172FH5Lw== dependencies: - cssnano-util-get-match "^4.0.0" - has "^1.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" + cssnano-utils "^2.0.0" + postcss-value-parser "^4.1.0" -postcss-selector-parser@^3.0.0: +postcss-selector-parser@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz#b310f5c4c0fdaf76f94902bbaa30db6aa84f5270" integrity sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA== @@ -6410,7 +6866,7 @@ postcss-selector-parser@^3.0.0: indexes-of "^1.0.1" uniq "^1.0.1" -postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.2: +postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4: version "6.0.5" resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.5.tgz#042d74e137db83e6f294712096cb413f5aa612c4" integrity sha512-aFYPoYmXbZ1V6HZaSvat08M97A8HqO6Pjz+PiNpw/DhuRrC72XWAdp3hL6wusDCN31sSmcZyMGa2hZEuX+Xfhg== @@ -6418,30 +6874,24 @@ postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.2: cssesc "^3.0.0" util-deprecate "^1.0.2" -postcss-svgo@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-4.0.3.tgz#343a2cdbac9505d416243d496f724f38894c941e" - integrity sha512-NoRbrcMWTtUghzuKSoIm6XV+sJdvZ7GZSc3wdBN0W19FTtp2ko8NqLsgoh/m9CzNhU3KLPvQmjIwtaNFkaFTvw== +postcss-svgo@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-5.0.0.tgz#c8d806e573394ab24f1e233cac5be4c199e9f1b2" + integrity sha512-M3/VS4sFI1Yp9g0bPL+xzzCNz5iLdRUztoFaugMit5a8sMfkVzzhwqbsOlD8IFFymCdJDmXmh31waYHWw1K4BA== dependencies: - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - svgo "^1.0.0" + postcss-value-parser "^4.1.0" + svgo "^2.3.0" -postcss-unique-selectors@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz#9446911f3289bfd64c6d680f073c03b1f9ee4bac" - integrity sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg== +postcss-unique-selectors@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-5.0.0.tgz#17856278f6c38d024defc9694d568bb09dd7f771" + integrity sha512-o9l4pF8SRn7aCMTmzb/kNv/kjV7wPZpZ8Nlb1Gq8v/Qvw969K1wanz1RVA0ehHzWe9+wHXaC2DvZlak/gdMJ5w== dependencies: - alphanum-sort "^1.0.0" - postcss "^7.0.0" + alphanum-sort "^1.0.2" + postcss-selector-parser "^6.0.2" uniqs "^2.0.0" -postcss-value-parser@^3.0.0, postcss-value-parser@^3.2.3: - version "3.3.1" - resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" - integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== - -postcss-value-parser@^4.0.2, postcss-value-parser@^4.1.0: +postcss-value-parser@^4.0.0, postcss-value-parser@^4.0.2, postcss-value-parser@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb" integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ== @@ -6455,28 +6905,33 @@ postcss@7.0.21: source-map "^0.6.1" supports-color "^6.1.0" -postcss@7.0.32: - version "7.0.32" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.32.tgz#4310d6ee347053da3433db2be492883d62cec59d" - integrity sha512-03eXong5NLnNCD05xscnGKGDZ98CyzoqPSMjOe6SuoQY7Z2hIj0Ld1g/O/UQRuOle2aRtiIRDg9tDcTGAkLfKw== +postcss@8.2.13: + version "8.2.13" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.13.tgz#dbe043e26e3c068e45113b1ed6375d2d37e2129f" + integrity sha512-FCE5xLH+hjbzRdpbRb1IMCvPv9yZx2QnDarBEYSN0N0HYk+TcXsEhwdFcFb+SRWOKzKGErhIEbBK2ogyLdTtfQ== dependencies: - chalk "^2.4.2" + colorette "^1.2.2" + nanoid "^3.1.22" source-map "^0.6.1" - supports-color "^6.1.0" -postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.27, postcss@^7.0.32, postcss@^7.0.5, postcss@^7.0.6: - version "7.0.35" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.35.tgz#d2be00b998f7f211d8a276974079f2e92b970e24" - integrity sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg== +postcss@^8.1.4: + version "8.2.14" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.14.tgz#dcf313eb8247b3ce8078d048c0e8262ca565ad2b" + integrity sha512-+jD0ZijcvyCqPQo/m/CW0UcARpdFylq04of+Q7RKX6f/Tu+dvpUI/9Sp81+i6/vJThnOBX09Quw0ZLOVwpzX3w== dependencies: - chalk "^2.4.2" + colorette "^1.2.2" + nanoid "^3.1.22" source-map "^0.6.1" - supports-color "^6.1.0" -prepend-http@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" - integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= +prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== + +pretty-bytes@^5.3.0: + version "5.6.0" + resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb" + integrity sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg== process-nextick-args@~2.0.0: version "2.0.1" @@ -6488,6 +6943,11 @@ process@^0.11.10: resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= +progress@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + promise-inflight@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" @@ -6501,6 +6961,14 @@ promise-retry@^1.1.1: err-code "^1.0.0" retry "^0.10.0" +promise-retry@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-2.0.1.tgz#ff747a13620ab57ba688f5fc67855410c370da22" + integrity sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g== + dependencies: + err-code "^2.0.2" + retry "^0.12.0" + propagating-hammerjs@^1.4.6: version "1.5.0" resolved "https://registry.yarnpkg.com/propagating-hammerjs/-/propagating-hammerjs-1.5.0.tgz#223d58465489b64879fb0cef2c99ba92b294c239" @@ -6508,13 +6976,6 @@ propagating-hammerjs@^1.4.6: dependencies: hammerjs "^2.0.8" -protoduck@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/protoduck/-/protoduck-5.0.1.tgz#03c3659ca18007b69a50fd82a7ebcc516261151f" - integrity sha512-WxoCeDCoCBY55BMvj4cAEjdVUFGRWed9ZxPlqTKYyw1nDDTQ4pqmnIMAGfJlg7Dx35uB/M+PHJPTmGOvaCaPTg== - dependencies: - genfun "^5.0.0" - proxy-addr@~2.0.5: version "2.0.6" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf" @@ -6585,11 +7046,6 @@ punycode@^2.1.0, punycode@^2.1.1: resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== -q@^1.1.2: - version "1.5.1" - resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" - integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= - qs@6.7.0: version "6.7.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" @@ -6600,14 +7056,6 @@ qs@~6.5.2: resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== -query-string@^4.1.0: - version "4.3.4" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-4.3.4.tgz#bbb693b9ca915c232515b228b1a02b609043dbeb" - integrity sha1-u7aTucqRXCMlFbIosaArYJBD2+s= - dependencies: - object-assign "^4.1.0" - strict-uri-encode "^1.0.0" - querystring-es3@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" @@ -6658,13 +7106,13 @@ raw-body@2.4.0: iconv-lite "0.4.24" unpipe "1.0.0" -raw-loader@4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/raw-loader/-/raw-loader-4.0.1.tgz#14e1f726a359b68437e183d5a5b7d33a3eba6933" - integrity sha512-baolhQBSi3iNh1cglJjA0mYzga+wePk7vdEX//1dTFd+v4TsQlQE0jitJSNF1OIP82rdYulH7otaVmdlDaJ64A== +raw-loader@4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/raw-loader/-/raw-loader-4.0.2.tgz#1aac6b7d1ad1501e66efdac1522c73e59a584eb6" + integrity sha512-ZnScIV3ag9A4wPX/ZayxL/jZH+euYb6FcUinPcgiQW0+UBtEv0O6Q3lGd3cqJ+GHH+rksEv3Pj99oxJ3u3VIKA== dependencies: loader-utils "^2.0.0" - schema-utils "^2.6.5" + schema-utils "^3.0.0" read-cache@^1.0.0: version "1.0.0" @@ -6673,26 +7121,40 @@ read-cache@^1.0.0: dependencies: pify "^2.3.0" -read-package-json@^2.0.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-2.1.2.tgz#6992b2b66c7177259feb8eaac73c3acd28b9222a" - integrity sha512-D1KmuLQr6ZSJS0tW8hf3WGpRlwszJOXZ3E8Yd/DNRaM5d+1wVRZdHlpGBLAuovjr28LbWvjpWkBHMxpRGGjzNA== +read-package-json-fast@^1.1.3: + version "1.2.2" + resolved "https://registry.yarnpkg.com/read-package-json-fast/-/read-package-json-fast-1.2.2.tgz#fba77b0b0d66b1ab344e214cb0876577e749c423" + integrity sha512-39DbPJjkltEzfXJXB6D8/Ir3GFOU2YbSKa2HaB/Y3nKrc/zY+0XrALpID6/13ezWyzqvOHrBbR4t4cjQuTdBVQ== dependencies: - glob "^7.1.1" json-parse-even-better-errors "^2.3.0" - normalize-package-data "^2.0.0" - npm-normalize-package-bin "^1.0.0" + npm-normalize-package-bin "^1.0.1" -read-package-tree@5.3.1: - version "5.3.1" - resolved "https://registry.yarnpkg.com/read-package-tree/-/read-package-tree-5.3.1.tgz#a32cb64c7f31eb8a6f31ef06f9cedf74068fe636" - integrity sha512-mLUDsD5JVtlZxjSlPPx1RETkNjjvQYuweKwNVt1Sn8kP5Jh44pvYuUHCp6xSVDZWbNxVxG5lyZJ921aJH61sTw== +read-package-json-fast@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/read-package-json-fast/-/read-package-json-fast-2.0.2.tgz#2dcb24d9e8dd50fb322042c8c35a954e6cc7ac9e" + integrity sha512-5fyFUyO9B799foVk4n6ylcoAktG/FbE3jwRKxvwaeSrIunaoMc0u81dzXxjeAFKOce7O5KncdfwpGvvs6r5PsQ== + dependencies: + json-parse-even-better-errors "^2.3.0" + npm-normalize-package-bin "^1.0.1" + +read-pkg-up@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" + integrity sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4= + dependencies: + find-up "^2.0.0" + read-pkg "^2.0.0" + +read-pkg@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" + integrity sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg= dependencies: - read-package-json "^2.0.0" - readdir-scoped-modules "^1.0.0" - util-promisify "^2.1.0" + load-json-file "^2.0.0" + normalize-package-data "^2.3.2" + path-type "^2.0.0" -"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: version "2.3.7" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== @@ -6705,7 +7167,7 @@ read-package-tree@5.3.1: string_decoder "~1.1.1" util-deprecate "~1.0.1" -readable-stream@^3.0.6, readable-stream@^3.6.0: +readable-stream@^3.0.6, readable-stream@^3.4.0, readable-stream@^3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== @@ -6714,16 +7176,6 @@ readable-stream@^3.0.6, readable-stream@^3.6.0: string_decoder "^1.1.1" util-deprecate "^1.0.1" -readdir-scoped-modules@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/readdir-scoped-modules/-/readdir-scoped-modules-1.1.0.tgz#8d45407b4f870a0dcaebc0e28670d18e74514309" - integrity sha512-asaikDeqAQg7JifRsZn1NJZXo9E+VwlyCfbkZhwyISinqk5zNS6266HS5kah6P0SaQKGF6SkNnZVHUzHFYxYDw== - dependencies: - debuglog "^1.0.1" - dezalgo "^1.0.0" - graceful-fs "^4.1.2" - once "^1.3.0" - readdirp@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" @@ -6790,6 +7242,11 @@ regexp.prototype.flags@^1.2.0, regexp.prototype.flags@^1.3.0: call-bind "^1.0.2" define-properties "^1.1.3" +regexpp@^3.0.0, regexpp@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2" + integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q== + regexpu-core@^4.7.1: version "4.7.1" resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.7.1.tgz#2dea5a9a07233298fbf0db91fa9abc4c6e0f8ad6" @@ -6802,6 +7259,11 @@ regexpu-core@^4.7.1: unicode-match-property-ecmascript "^1.0.4" unicode-match-property-value-ecmascript "^1.2.0" +regextras@^0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/regextras/-/regextras-0.7.1.tgz#be95719d5f43f9ef0b9fa07ad89b7c606995a3b2" + integrity sha512-9YXf6xtW+qzQ+hcMQXx95MOvfqXFgsKDZodX3qZB0x2n5Z94ioetIITsBtvJbiOyxa/6s9AtyweBLCdPmPko/w== + regjsgen@^0.5.1: version "0.5.2" resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.2.tgz#92ff295fb1deecbf6ecdab2543d207e91aa33733" @@ -6860,6 +7322,11 @@ require-directory@^2.1.1: resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= +require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + require-main-filename@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" @@ -6882,6 +7349,11 @@ resolve-from@^3.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" integrity sha1-six699nWiBvItuZTM17rywoYh0g= +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + resolve-url-loader@3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/resolve-url-loader/-/resolve-url-loader-3.1.2.tgz#235e2c28e22e3e432ba7a5d4e305c59a58edfc08" @@ -6903,7 +7375,15 @@ resolve-url@^0.2.1: resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= -resolve@^1.1.7, resolve@^1.10.0, resolve@^1.3.2, resolve@^1.8.1: +resolve@1.19.0: + version "1.19.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.19.0.tgz#1af5bf630409734a067cae29318aac7fa29a267c" + integrity sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg== + dependencies: + is-core-module "^2.1.0" + path-parse "^1.0.6" + +resolve@^1.1.7, resolve@^1.10.0, resolve@^1.13.1, resolve@^1.17.0: version "1.20.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== @@ -6962,14 +7442,14 @@ rgba-regex@^1.0.0: resolved "https://registry.yarnpkg.com/rgba-regex/-/rgba-regex-1.0.0.tgz#43374e2e2ca0968b0ef1523460b7d730ff22eeb3" integrity sha1-QzdOLiyglosO8VI0YLfXMP8i7rM= -rimraf@3.0.2, rimraf@^3.0.2: +rimraf@3.0.2, rimraf@^3.0.0, rimraf@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== dependencies: glob "^7.1.3" -rimraf@^2.5.4, rimraf@^2.6.2, rimraf@^2.6.3: +rimraf@^2.5.4, rimraf@^2.6.3: version "2.7.1" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== @@ -6984,12 +7464,12 @@ ripemd160@^2.0.0, ripemd160@^2.0.1: hash-base "^3.0.0" inherits "^2.0.1" -rollup@2.26.5: - version "2.26.5" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.26.5.tgz#5562ec36fcba3eed65cfd630bd78e037ad0e0307" - integrity sha512-rCyFG3ZtQdnn9YwfuAVH0l/Om34BdO5lwCA0W6Hq+bNB21dVEBbCRxhaHOmu1G7OBFDWytbzAC104u7rxHwGjA== +rollup@2.38.4: + version "2.38.4" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.38.4.tgz#1b84ea8728c73b1a00a6a6e9c630ec8c3fe48cea" + integrity sha512-B0LcJhjiwKkTl79aGVF/u5KdzsH8IylVfV56Ut6c9ouWLJcUK17T83aZBetNYSnZtXf2OHD4+2PbmRW+Fp5ulg== optionalDependencies: - fsevents "~2.1.2" + fsevents "~2.3.1" run-async@^2.4.0: version "2.4.1" @@ -7010,10 +7490,10 @@ run-queue@^1.0.0, run-queue@^1.0.3: dependencies: aproba "^1.1.1" -rxjs@6.6.2: - version "6.6.2" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.2.tgz#8096a7ac03f2cc4fe5860ef6e572810d9e01c0d2" - integrity sha512-BHdBMVoWC2sL26w//BCu3YzKT4s2jip/WhwsGEDmeKYBhKDZeYezVUnHatYB7L85v5xs0BAQmg6BEYJEKxBabg== +rxjs@6.6.3: + version "6.6.3" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.3.tgz#8ca84635c4daa900c0d3967a6ee7ac60271ee552" + integrity sha512-trsQc+xYYXZ3urjOiJOuCOa5N3jAZ3eiSpQB5hIT8zGlL2QfnHLJ2r7GMkBGuIausdJN1OneaI6gQlsqNHHmZQ== dependencies: tslib "^1.9.0" @@ -7046,25 +7526,25 @@ safe-regex@^1.1.0: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -sass-loader@10.0.1: - version "10.0.1" - resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-10.0.1.tgz#10c0364d8034f22fee25ddcc9eded20f99bbe3b4" - integrity sha512-b2PSldKVTS3JcFPHSrEXh3BeAfR7XknGiGCAO5aHruR3Pf3kqLP3Gb2ypXLglRrAzgZkloNxLZ7GXEGDX0hBUQ== +sass-loader@10.1.1: + version "10.1.1" + resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-10.1.1.tgz#4ddd5a3d7638e7949065dd6e9c7c04037f7e663d" + integrity sha512-W6gVDXAd5hR/WHsPicvZdjAWHBcEJ44UahgxcIE196fW2ong0ZHMPO1kZuI5q0VlvMQZh32gpv69PLWQm70qrw== dependencies: - klona "^2.0.3" + klona "^2.0.4" loader-utils "^2.0.0" neo-async "^2.6.2" - schema-utils "^2.7.0" + schema-utils "^3.0.0" semver "^7.3.2" -sass@1.26.10: - version "1.26.10" - resolved "https://registry.yarnpkg.com/sass/-/sass-1.26.10.tgz#851d126021cdc93decbf201d1eca2a20ee434760" - integrity sha512-bzN0uvmzfsTvjz0qwccN1sPm2HxxpNI/Xa+7PlUEMS+nQvbyuEK7Y0qFqxlPHhiNHb1Ze8WQJtU31olMObkAMw== +sass@1.32.6: + version "1.32.6" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.32.6.tgz#e3646c8325cd97ff75a8a15226007f3ccd221393" + integrity sha512-1bcDHDcSqeFtMr0JXI3xc/CXX6c4p0wHHivJdru8W7waM7a1WjKMm4m/Z5sY7CbVw4Whi2Chpcw6DFfSWwGLzQ== dependencies: chokidar ">=2.0.0 <4.0.0" -sax@~1.2.4: +sax@^1.2.4, sax@~1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== @@ -7078,7 +7558,7 @@ schema-utils@^1.0.0: ajv-errors "^1.0.0" ajv-keywords "^3.1.0" -schema-utils@^2.6.5, schema-utils@^2.6.6, schema-utils@^2.7.0: +schema-utils@^2.6.5, schema-utils@^2.7.0: version "2.7.1" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.1.tgz#1ca4f32d1b24c590c203b8e7a50bf0ea4cd394d7" integrity sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg== @@ -7087,25 +7567,27 @@ schema-utils@^2.6.5, schema-utils@^2.6.6, schema-utils@^2.7.0: ajv "^6.12.4" ajv-keywords "^3.5.2" +schema-utils@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.0.0.tgz#67502f6aa2b66a2d4032b4279a2944978a0913ef" + integrity sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA== + dependencies: + "@types/json-schema" "^7.0.6" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + select-hose@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo= -selfsigned@^1.10.7: +selfsigned@^1.10.8: version "1.10.11" resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.11.tgz#24929cd906fe0f44b6d01fb23999a739537acbe9" integrity sha512-aVmbPOfViZqOZPgRBT0+3u4yZFHpmnIghLMlAcb5/xhp5ZtB/RVnKhz5vl2M32CLXAqR4kha9zfhNg0Lf/sxKA== dependencies: node-forge "^0.10.0" -semver-dsl@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/semver-dsl/-/semver-dsl-1.0.1.tgz#d3678de5555e8a61f629eed025366ae5f27340a0" - integrity sha1-02eN5VVeimH2Ke7QJTZq5fJzQKA= - dependencies: - semver "^5.3.0" - semver-intersect@1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/semver-intersect/-/semver-intersect-1.4.0.tgz#bdd9c06bedcdd2fedb8cd352c3c43ee8c61321f3" @@ -7113,7 +7595,7 @@ semver-intersect@1.4.0: dependencies: semver "^5.0.0" -"semver@2 || 3 || 4 || 5", semver@^5.0.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0: +"semver@2 || 3 || 4 || 5", semver@^5.0.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== @@ -7123,17 +7605,19 @@ semver@7.0.0: resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== -semver@7.3.2: - version "7.3.2" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" - integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== +semver@7.3.4: + version "7.3.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.4.tgz#27aaa7d2e4ca76452f98d3add093a72c943edc97" + integrity sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw== + dependencies: + lru-cache "^6.0.0" semver@^6.0.0, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== -semver@^7.0.0, semver@^7.1.1, semver@^7.3.2, semver@^7.3.4: +semver@^7.0.0, semver@^7.1.1, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5: version "7.3.5" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== @@ -7166,6 +7650,13 @@ serialize-javascript@^4.0.0: dependencies: randombytes "^2.1.0" +serialize-javascript@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-5.0.1.tgz#7886ec848049a462467a97d3d918ebb2aaf934f4" + integrity sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA== + dependencies: + randombytes "^2.1.0" + serve-index@^1.9.1: version "1.9.1" resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" @@ -7189,7 +7680,7 @@ serve-static@1.14.1: parseurl "~1.3.3" send "0.17.1" -set-blocking@^2.0.0: +set-blocking@^2.0.0, set-blocking@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= @@ -7227,6 +7718,13 @@ sha.js@^2.4.0, sha.js@^2.4.8: inherits "^2.0.1" safe-buffer "^5.0.1" +shallow-clone@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" + integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== + dependencies: + kind-of "^6.0.2" + shebang-command@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" @@ -7234,11 +7732,23 @@ shebang-command@^1.2.0: dependencies: shebang-regex "^1.0.0" +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + shebang-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + side-channel@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" @@ -7265,6 +7775,15 @@ slash@^3.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== +slice-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" + integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== + dependencies: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + smart-buffer@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.1.0.tgz#91605c25d91652f4661ea69ccf45f1b331ca21ba" @@ -7300,65 +7819,60 @@ snapdragon@^0.8.1: source-map-resolve "^0.5.0" use "^3.1.0" -sockjs-client@1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.4.0.tgz#c9f2568e19c8fd8173b4997ea3420e0bb306c7d5" - integrity sha512-5zaLyO8/nri5cua0VtOrFXBPK1jbL4+1cebT/mmKA1E1ZXOvJrII75bPu0l0k843G/+iAbhEqzyKr0w/eCCj7g== +sockjs-client@^1.5.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.5.1.tgz#256908f6d5adfb94dabbdbd02c66362cca0f9ea6" + integrity sha512-VnVAb663fosipI/m6pqRXakEOw7nvd7TUgdr3PlR/8V2I95QIdwT8L4nMxhyU8SmDBHYXU1TOElaKOmKLfYzeQ== dependencies: - debug "^3.2.5" + debug "^3.2.6" eventsource "^1.0.7" - faye-websocket "~0.11.1" - inherits "^2.0.3" - json3 "^3.3.2" - url-parse "^1.4.3" + faye-websocket "^0.11.3" + inherits "^2.0.4" + json3 "^3.3.3" + url-parse "^1.5.1" -sockjs@0.3.20: - version "0.3.20" - resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.20.tgz#b26a283ec562ef8b2687b44033a4eeceac75d855" - integrity sha512-SpmVOVpdq0DJc0qArhF3E5xsxvaiqGNb73XfgBpK1y3UD5gs8DSo8aCTsuT5pX8rssdc2NDIzANwP9eCAiSdTA== +sockjs@^0.3.21: + version "0.3.21" + resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.21.tgz#b34ffb98e796930b60a0cfa11904d6a339a7d417" + integrity sha512-DhbPFGpxjc6Z3I+uX07Id5ZO2XwYsWOrYjaSeieES78cq+JaJvVe5q/m1uvjIQhXinhIeCFRH6JgXe+mvVMyXw== dependencies: - faye-websocket "^0.10.0" + faye-websocket "^0.11.3" uuid "^3.4.0" - websocket-driver "0.6.5" + websocket-driver "^0.7.4" -socks-proxy-agent@^4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-4.0.2.tgz#3c8991f3145b2799e70e11bd5fbc8b1963116386" - integrity sha512-NT6syHhI9LmuEMSK6Kd2V7gNv5KFZoLE7V5udWmn0de+3Mkj3UMA/AJPLyeNUVmElCurSHtUdM3ETpR3z770Wg== +socks-proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-5.0.0.tgz#7c0f364e7b1cf4a7a437e71253bed72e9004be60" + integrity sha512-lEpa1zsWCChxiynk+lCycKuC502RxDWLKJZoIhnxrWNjLSDGYRFflHA1/228VkRcnv9TIb8w98derGbpKxJRgA== dependencies: - agent-base "~4.2.1" - socks "~2.3.2" + agent-base "6" + debug "4" + socks "^2.3.3" -socks@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/socks/-/socks-2.3.3.tgz#01129f0a5d534d2b897712ed8aceab7ee65d78e3" - integrity sha512-o5t52PCNtVdiOvzMry7wU4aOqYWL0PeCXRWBEiJow4/i/wr+wpsJQ9awEu1EonLIqsfGd5qSgDdxEOvCdmBEpA== +socks@^2.3.3: + version "2.6.1" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.6.1.tgz#989e6534a07cf337deb1b1c94aaa44296520d30e" + integrity sha512-kLQ9N5ucj8uIcxrDwjm0Jsqk06xdpBjGNQtpXy4Q8/QY2k+fY7nZH8CARy+hkbG+SGAovmzzuauCpBlb8FrnBA== dependencies: - ip "1.1.5" + ip "^1.1.5" smart-buffer "^4.1.0" -sort-keys@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad" - integrity sha1-RBttTTRnmPG05J6JIK37oOVD+a0= - dependencies: - is-plain-obj "^1.0.0" - -source-list-map@^2.0.0: +source-list-map@^2.0.0, source-list-map@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== -source-map-loader@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/source-map-loader/-/source-map-loader-1.0.2.tgz#b0a6582b2eaa387ede1ecf8061ae0b93c23f9eb0" - integrity sha512-oX8d6ndRjN+tVyjj6PlXSyFPhDdVAPsZA30nD3/II8g4uOv8fCz0DMn5sy8KtVbDfKQxOpGwGJnK3xIW3tauDw== +source-map-loader@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/source-map-loader/-/source-map-loader-1.1.3.tgz#7dbc2fe7ea09d3e43c51fd9fc478b7f016c1f820" + integrity sha512-6YHeF+XzDOrT/ycFJNI53cgEsp/tHTMl37hi7uVyqFAlTXW109JazaQCkbc+jjoL2637qkH1amLi+JzrIpt5lA== dependencies: - data-urls "^2.0.0" + abab "^2.0.5" iconv-lite "^0.6.2" loader-utils "^2.0.0" - schema-utils "^2.7.0" + schema-utils "^3.0.0" source-map "^0.6.1" + whatwg-mimetype "^2.3.0" source-map-resolve@^0.5.0, source-map-resolve@^0.5.2: version "0.5.3" @@ -7371,6 +7885,14 @@ source-map-resolve@^0.5.0, source-map-resolve@^0.5.2: source-map-url "^0.4.0" urix "^0.1.0" +source-map-resolve@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.6.0.tgz#3d9df87e236b53f16d01e58150fc7711138e5ed2" + integrity sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w== + dependencies: + atob "^2.1.2" + decode-uri-component "^0.2.0" + source-map-support@0.5.19, source-map-support@^0.5.5, source-map-support@~0.5.12, source-map-support@~0.5.19: version "0.5.19" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" @@ -7394,7 +7916,7 @@ source-map@0.7.3, source-map@^0.7.3, source-map@~0.7.2: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== -source-map@^0.5.0, source-map@^0.5.6, source-map@^0.5.7: +source-map@^0.5.0, source-map@^0.5.6: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= @@ -7417,7 +7939,7 @@ spdx-exceptions@^2.1.0: resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== -spdx-expression-parse@^3.0.0: +spdx-expression-parse@^3.0.0, spdx-expression-parse@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== @@ -7453,12 +7975,12 @@ spdy@^4.0.2: select-hose "^2.0.0" spdy-transport "^3.0.0" -speed-measure-webpack-plugin@1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/speed-measure-webpack-plugin/-/speed-measure-webpack-plugin-1.3.3.tgz#6ff894fc83e8a6310dde3af863a0329cd79da4f5" - integrity sha512-2ljD4Ch/rz2zG3HsLsnPfp23osuPBS0qPuz9sGpkNXTN1Ic4M+W9xB8l8rS8ob2cO4b1L+WTJw/0AJwWYVgcxQ== +speed-measure-webpack-plugin@1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/speed-measure-webpack-plugin/-/speed-measure-webpack-plugin-1.4.2.tgz#1608e62d3bdb45f01810010e1b5bfedefedfa58f" + integrity sha512-AtVzD0bnIy2/B0fWqJpJgmhcrfWFhBlduzSo0uwplr/QvB33ZNZj2NEth3NONgdnZJqicK0W0mSxnLSbsVCDbw== dependencies: - chalk "^2.0.1" + chalk "^4.1.0" split-string@^3.0.1, split-string@^3.0.2: version "3.1.0" @@ -7467,11 +7989,6 @@ split-string@^3.0.1, split-string@^3.0.2: dependencies: extend-shallow "^3.0.0" -sprintf-js@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.2.tgz#da1765262bf8c0f571749f2ad6c26300207ae673" - integrity sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug== - sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" @@ -7492,7 +8009,7 @@ sshpk@^1.7.0: safer-buffer "^2.0.2" tweetnacl "~0.14.0" -ssri@^6.0.0, ssri@^6.0.1: +ssri@^6.0.1: version "6.0.2" resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.2.tgz#157939134f20464e7301ddba3e90ffa8f7728ac5" integrity sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q== @@ -7556,10 +8073,22 @@ stream-shift@^1.0.0: resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== -strict-uri-encode@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" - integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +"string-width@^1.0.2 || 2": + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" string-width@^3.0.0, string-width@^3.1.0: version "3.1.0" @@ -7609,13 +8138,20 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -strip-ansi@^3.0.1: +strip-ansi@^3.0.0, strip-ansi@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= dependencies: ansi-regex "^2.0.0" +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= + dependencies: + ansi-regex "^3.0.0" + strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" @@ -7630,36 +8166,47 @@ strip-ansi@^6.0.0: dependencies: ansi-regex "^5.0.0" +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= + strip-eof@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= -style-loader@1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-1.2.1.tgz#c5cbbfbf1170d076cfdd86e0109c5bba114baa1a" - integrity sha512-ByHSTQvHLkWE9Ir5+lGbVOXhxX10fbprhLvdg96wedFZb4NDekDPxVKv5Fwmio+QcMlkkNfuK+5W1peQ5CUhZg== +strip-json-comments@3.1.1, strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +style-loader@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-2.0.0.tgz#9669602fd4690740eaaec137799a03addbbc393c" + integrity sha512-Z0gYUJmzZ6ZdRUqpg1r8GsaFKypE+3xAzuFeMuoHgjc9KZv3wMyCRjQIWEbhoFSq7+7yoHXySDJyyWQaPajeiQ== dependencies: loader-utils "^2.0.0" - schema-utils "^2.6.6" + schema-utils "^3.0.0" -stylehacks@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-4.0.3.tgz#6718fcaf4d1e07d8a1318690881e8d96726a71d5" - integrity sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g== +stylehacks@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-5.0.0.tgz#c49b0b2cf9917fe37dc030b96a4c34698b932933" + integrity sha512-QOWm6XivDLb+fqffTZP8jrmPmPITVChl2KCY2R05nsCWwLi3VGhCdVc3IVGNwd1zzTt1jPd67zIKjpQfxzQZeA== dependencies: - browserslist "^4.0.0" - postcss "^7.0.0" - postcss-selector-parser "^3.0.0" + browserslist "^4.16.0" + postcss-selector-parser "^6.0.4" -stylus-loader@3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/stylus-loader/-/stylus-loader-3.0.2.tgz#27a706420b05a38e038e7cacb153578d450513c6" - integrity sha512-+VomPdZ6a0razP+zinir61yZgpw2NfljeSsdUF5kJuEzlo3khXhY19Fn6l8QQz1GRJGtMCo8nG5C04ePyV7SUA== +stylus-loader@4.3.3: + version "4.3.3" + resolved "https://registry.yarnpkg.com/stylus-loader/-/stylus-loader-4.3.3.tgz#381bb6341272ac50bcdfd0b877707eac99b6b757" + integrity sha512-PpWB5PnCXUzW4WMYhCvNzAHJBjIBPMXwsdfkkKuA9W7k8OQFMl/19/AQvaWsxz2IptxUlCseyJ6TY/eEKJ4+UQ== dependencies: - loader-utils "^1.0.2" - lodash.clonedeep "^4.5.0" - when "~3.6.x" + fast-glob "^3.2.4" + klona "^2.0.4" + loader-utils "^2.0.0" + normalize-path "^3.0.0" + schema-utils "^3.0.0" stylus@0.54.8: version "0.54.8" @@ -7701,49 +8248,47 @@ svg-pan-zoom@^3.6.0: resolved "https://registry.yarnpkg.com/svg-pan-zoom/-/svg-pan-zoom-3.6.1.tgz#f880a1bb32d18e9c625d7715350bebc269b450cf" integrity sha512-JaKkGHHfGvRrcMPdJWkssLBeWqM+Isg/a09H7kgNNajT1cX5AztDTNs+C8UzpCxjCTRrG34WbquwaovZbmSk9g== -svgo@^1.0.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/svgo/-/svgo-1.3.2.tgz#b6dc511c063346c9e415b81e43401145b96d4167" - integrity sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw== - dependencies: - chalk "^2.4.1" - coa "^2.0.2" - css-select "^2.0.0" - css-select-base-adapter "^0.1.1" - css-tree "1.0.0-alpha.37" - csso "^4.0.2" - js-yaml "^3.13.1" - mkdirp "~0.5.1" - object.values "^1.1.0" - sax "~1.2.4" +svgo@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/svgo/-/svgo-2.3.0.tgz#6b3af81d0cbd1e19c83f5f63cec2cb98c70b5373" + integrity sha512-fz4IKjNO6HDPgIQxu4IxwtubtbSfGEAJUq/IXyTPIkGhWck/faiiwfkvsB8LnBkKLvSoyNNIY6d13lZprJMc9Q== + dependencies: + "@trysound/sax" "0.1.1" + chalk "^4.1.0" + commander "^7.1.0" + css-select "^3.1.2" + css-tree "^1.1.2" + csso "^4.2.0" stable "^0.1.8" - unquote "~1.1.1" - util.promisify "~1.0.0" -symbol-observable@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" - integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== +symbol-observable@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-3.0.0.tgz#eea8f6478c651018e059044268375c408c15c533" + integrity sha512-6tDOXSHiVjuCaasQSWTmHUWn4PuG7qa3+1WT031yTc/swT7+rLiw3GOrFxaH1E3lLP09dH3bVuVDf2gK5rxG3Q== + +table@^6.0.4: + version "6.7.0" + resolved "https://registry.yarnpkg.com/table/-/table-6.7.0.tgz#26274751f0ee099c547f6cb91d3eff0d61d155b2" + integrity sha512-SAM+5p6V99gYiiy2gT5ArdzgM1dLDed0nkrWmG6Fry/bUS/m9x83BwpJUOf1Qj/x2qJd+thL6IkIx7qPGRxqBw== + dependencies: + ajv "^8.0.1" + lodash.clonedeep "^4.5.0" + lodash.truncate "^4.4.2" + slice-ansi "^4.0.0" + string-width "^4.2.0" + strip-ansi "^6.0.0" tapable@^1.0.0, tapable@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== -tar@^4.4.10: - version "4.4.13" - resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525" - integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA== - dependencies: - chownr "^1.1.1" - fs-minipass "^1.2.5" - minipass "^2.8.6" - minizlib "^1.2.1" - mkdirp "^0.5.0" - safe-buffer "^5.1.2" - yallist "^3.0.3" +tapable@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.0.tgz#5c373d281d9c672848213d0e037d1c4165ab426b" + integrity sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw== -tar@^6.0.2: +tar@^6.0.2, tar@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.0.tgz#d1724e9bcc04b977b18d5c573b333a2207229a83" integrity sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA== @@ -7755,19 +8300,19 @@ tar@^6.0.2: mkdirp "^1.0.3" yallist "^4.0.0" -terser-webpack-plugin@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-4.1.0.tgz#6e9d6ae4e1a900d88ddce8da6a47507ea61f44bc" - integrity sha512-0ZWDPIP8BtEDZdChbufcXUigOYk6dOX/P/X0hWxqDDcVAQLb8Yy/0FAaemSfax3PAA67+DJR778oz8qVbmy4hA== +terser-webpack-plugin@4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-4.2.3.tgz#28daef4a83bd17c1db0297070adc07fc8cfc6a9a" + integrity sha512-jTgXh40RnvOrLQNgIkwEKnQ8rmHjHK4u+6UBEi+W+FPmvb+uo+chJXntKe7/3lW5mNysgSWD60KyesnhW8D6MQ== dependencies: cacache "^15.0.5" find-cache-dir "^3.3.1" - jest-worker "^26.3.0" + jest-worker "^26.5.0" p-limit "^3.0.2" - schema-utils "^2.6.6" - serialize-javascript "^4.0.0" + schema-utils "^3.0.0" + serialize-javascript "^5.0.1" source-map "^0.6.1" - terser "^5.0.0" + terser "^5.3.4" webpack-sources "^1.4.3" terser-webpack-plugin@^1.4.3: @@ -7785,14 +8330,14 @@ terser-webpack-plugin@^1.4.3: webpack-sources "^1.4.0" worker-farm "^1.7.0" -terser@5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.3.0.tgz#c481f4afecdcc182d5e2bdd2ff2dc61555161e81" - integrity sha512-XTT3D3AwxC54KywJijmY2mxZ8nJiEjBHVYzq8l9OaYuRFWeQNBwvipuzzYEP4e+/AVcd1hqG/CqgsdIRyT45Fg== +terser@5.5.1: + version "5.5.1" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.5.1.tgz#540caa25139d6f496fdea056e414284886fb2289" + integrity sha512-6VGWZNVP2KTUcltUQJ25TtNjx/XgdDsBDKGt8nN0MpydU36LmbPPcMBd2kmtZNNGVVDLg44k7GKeHHj+4zPIBQ== dependencies: commander "^2.20.0" - source-map "~0.6.1" - source-map-support "~0.5.12" + source-map "~0.7.2" + source-map-support "~0.5.19" terser@^4.1.2: version "4.8.0" @@ -7803,7 +8348,7 @@ terser@^4.1.2: source-map "~0.6.1" source-map-support "~0.5.12" -terser@^5.0.0: +terser@^5.3.4: version "5.7.0" resolved "https://registry.yarnpkg.com/terser/-/terser-5.7.0.tgz#a761eeec206bc87b605ab13029876ead938ae693" integrity sha512-HP5/9hp2UaZt5fYkuhNBR8YyRcT8juw8+uFbAme53iN9hblvKnLUTKkmwJG6ocWpIKf8UK4DoeWG4ty0J6S6/g== @@ -7812,6 +8357,11 @@ terser@^5.0.0: source-map "~0.7.2" source-map-support "~0.5.19" +text-table@0.2.0, text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= + through2@^2.0.0: version "2.0.5" resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" @@ -7820,7 +8370,7 @@ through2@^2.0.0: readable-stream "~2.3.6" xtend "~4.0.1" -"through@>=2.2.7 <3", through@X.X.X, through@^2.3.6: +through@^2.3.6: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= @@ -7842,6 +8392,13 @@ timsort@^0.3.0: resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4" integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q= +tmp@0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" + integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== + dependencies: + rimraf "^3.0.0" + tmp@^0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" @@ -7942,13 +8499,6 @@ tough-cookie@~2.5.0: psl "^1.1.28" punycode "^2.1.1" -tr46@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.0.2.tgz#03273586def1595ae08fedb38d7733cee91d2479" - integrity sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg== - dependencies: - punycode "^2.1.1" - tree-kill@1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" @@ -7959,12 +8509,22 @@ ts-pnp@^1.1.6: resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.2.0.tgz#a500ad084b0798f1c3071af391e65912c86bca92" integrity sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw== -tslib@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.0.1.tgz#410eb0d113e5b6356490eec749603725b021b43e" - integrity sha512-SgIkNheinmEBgx1IUNirK0TUD4X9yjjBRTqqjggWCU3pUEqIk3/Uwl3yRixYKT6WjQuGiwDv4NomL3wqRCj+CQ== +tsconfig-paths@^3.9.0: + version "3.9.0" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz#098547a6c4448807e8fcb8eae081064ee9a3c90b" + integrity sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw== + dependencies: + "@types/json5" "^0.0.29" + json5 "^1.0.1" + minimist "^1.2.0" + strip-bom "^3.0.0" + +tslib@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a" + integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A== -tslib@^1.10.0, tslib@^1.13.0, tslib@^1.8.1, tslib@^1.9.0: +tslib@^1.10.0, tslib@^1.8.1, tslib@^1.9.0: version "1.14.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== @@ -7974,29 +8534,10 @@ tslib@^2.0.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.2.0.tgz#fb2c475977e35e241311ede2693cee1ec6698f5c" integrity sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w== -tslint@~6.1.0: - version "6.1.3" - resolved "https://registry.yarnpkg.com/tslint/-/tslint-6.1.3.tgz#5c23b2eccc32487d5523bd3a470e9aa31789d904" - integrity sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg== - dependencies: - "@babel/code-frame" "^7.0.0" - builtin-modules "^1.1.1" - chalk "^2.3.0" - commander "^2.12.1" - diff "^4.0.1" - glob "^7.1.1" - js-yaml "^3.13.1" - minimatch "^3.0.4" - mkdirp "^0.5.3" - resolve "^1.3.2" - semver "^5.3.0" - tslib "^1.13.0" - tsutils "^2.29.0" - -tsutils@^2.29.0: - version "2.29.0" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.29.0.tgz#32b488501467acbedd4b85498673a0812aca0b99" - integrity sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA== +tsutils@^3.17.1: + version "3.21.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" + integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== dependencies: tslib "^1.8.1" @@ -8017,11 +8558,28 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0: resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= +type-check@^0.4.0, type-check@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== + dependencies: + prelude-ls "^1.2.1" + +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + type-fest@^0.21.3: version "0.21.3" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== +type-fest@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" + integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== + type-is@~1.6.17, type-is@~1.6.18: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" @@ -8045,16 +8603,16 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= -typescript@4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.0.2.tgz#7ea7c88777c723c681e33bf7988be5d008d05ac2" - integrity sha512-e4ERvRV2wb+rRZ/IQeb3jm2VxBsirQLpQhdxplZ2MEzGvDkkMmPglecnNDfSUBivMjP93vRbngYYDQqQ/78bcQ== - typescript@4.0.5: version "4.0.5" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.0.5.tgz#ae9dddfd1069f1cb5beb3ef3b2170dd7c1332389" integrity sha512-ywmr/VrTVCmNTJ6iV2LwIrfG1P+lv6luD8sUJs+2eI9NLGigaN+nUQc13iHqisq7bra9lnmUSYqbJvegraBOPQ== +typescript@4.1.5: + version "4.1.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.1.5.tgz#123a3b214aaff3be32926f0d8f1f6e704eb89a72" + integrity sha512-6OSu9PTIzmn9TCDiovULTnET6BgXtDYL4Gg4szY+cGsc3JP1dQL8qvE8kShTRx1NIw4Q9IBHlwODjkjWEtMUyA== + unbox-primitive@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" @@ -8141,11 +8699,6 @@ unpipe@1.0.0, unpipe@~1.0.0: resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= -unquote@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/unquote/-/unquote-1.1.1.tgz#8fded7324ec6e88a0ff8b905e7c098cdc086d544" - integrity sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ= - unset-value@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" @@ -8171,7 +8724,7 @@ urix@^0.1.0: resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= -url-parse@^1.4.3: +url-parse@^1.4.3, url-parse@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.1.tgz#d5fa9890af8a5e1f274a2c98376510f6425f6e3b" integrity sha512-HOfCOUJt7iSYzEx/UqgtwKRMC6EU91NFhsCHMv9oM03VJcVo2Qrp8T8kI9D7amFf1cu+/3CEhgb3rF9zL7k85Q== @@ -8197,23 +8750,6 @@ util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= -util-promisify@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/util-promisify/-/util-promisify-2.1.0.tgz#3c2236476c4d32c5ff3c47002add7c13b9a82a53" - integrity sha1-PCI2R2xNMsX/PEcAKt18E7moKlM= - dependencies: - object.getownpropertydescriptors "^2.0.3" - -util.promisify@~1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.1.tgz#6baf7774b80eeb0f7520d8b81d07982a59abbaee" - integrity sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.2" - has-symbols "^1.0.1" - object.getownpropertydescriptors "^2.1.0" - util@0.10.3: version "0.10.3" resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" @@ -8233,16 +8769,21 @@ utils-merge@1.0.1: resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= -uuid@8.3.0: - version "8.3.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.0.tgz#ab738085ca22dc9a8c92725e459b1d507df5d6ea" - integrity sha512-fX6Z5o4m6XsXBdli9g7DtWgAx+osMsRRZFKma1mIUsLCz6vRvv+pz5VNbyu9UEDzpMWulZfvpgb/cmDXVulYFQ== +uuid@8.3.2: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== uuid@^3.0.0, uuid@^3.3.2, uuid@^3.4.0: version "3.4.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== +v8-compile-cache@^2.0.3: + version "2.3.0" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" + integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== + validate-npm-package-license@^3.0.1: version "3.0.4" resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" @@ -8263,7 +8804,7 @@ vary@~1.1.2: resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= -vendors@^1.0.0: +vendors@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.4.tgz#e2b800a53e7a29b93506c3cf41100d16c4c4ad8e" integrity sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w== @@ -8330,11 +8871,6 @@ wcwidth@^1.0.1: dependencies: defaults "^1.0.3" -webidl-conversions@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514" - integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w== - webpack-dev-middleware@3.7.2: version "3.7.2" resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.7.2.tgz#0019c3db716e3fa5cecbf64f2ab88a74bab331f3" @@ -8357,10 +8893,10 @@ webpack-dev-middleware@^3.7.2: range-parser "^1.2.1" webpack-log "^2.0.0" -webpack-dev-server@3.11.0: - version "3.11.0" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.11.0.tgz#8f154a3bce1bcfd1cc618ef4e703278855e7ff8c" - integrity sha512-PUxZ+oSTxogFQgkTtFndEtJIPNmml7ExwufBZ9L2/Xyyd5PnOL5UreWe5ZT7IU25DSdykL9p1MLQzmLh2ljSeg== +webpack-dev-server@3.11.2: + version "3.11.2" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.11.2.tgz#695ebced76a4929f0d5de7fd73fafe185fe33708" + integrity sha512-A80BkuHRQfCiNtGBS1EMf2ChTUs0x+B3wGDFmOeT4rmJOHhHTCH2naNxIHhmkr0/UillP4U3yeIyv1pNp+QDLQ== dependencies: ansi-html "0.0.7" bonjour "^3.5.0" @@ -8382,11 +8918,11 @@ webpack-dev-server@3.11.0: p-retry "^3.0.1" portfinder "^1.0.26" schema-utils "^1.0.0" - selfsigned "^1.10.7" + selfsigned "^1.10.8" semver "^6.3.0" serve-index "^1.9.1" - sockjs "0.3.20" - sockjs-client "1.4.0" + sockjs "^0.3.21" + sockjs-client "^1.5.0" spdy "^4.0.2" strip-ansi "^3.0.1" supports-color "^6.1.0" @@ -8404,14 +8940,23 @@ webpack-log@^2.0.0: ansi-colors "^3.0.0" uuid "^3.3.2" -webpack-merge@4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-4.2.2.tgz#a27c52ea783d1398afd2087f547d7b9d2f43634d" - integrity sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g== +webpack-merge@5.7.3: + version "5.7.3" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.7.3.tgz#2a0754e1877a25a8bbab3d2475ca70a052708213" + integrity sha512-6/JUQv0ELQ1igjGDzHkXbVDRxkfA57Zw7PfiupdLFJYrgFqY5ZP8xxbpp2lU3EPwYx89ht5Z/aDkD40hFCm5AA== dependencies: - lodash "^4.17.15" + clone-deep "^4.0.1" + wildcard "^2.0.0" -webpack-sources@1.4.3, webpack-sources@^1.1.0, webpack-sources@^1.2.0, webpack-sources@^1.3.0, webpack-sources@^1.4.0, webpack-sources@^1.4.1, webpack-sources@^1.4.3: +webpack-sources@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-2.2.0.tgz#058926f39e3d443193b6c31547229806ffd02bac" + integrity sha512-bQsA24JLwcnWGArOKUxYKhX3Mz/nK1Xf6hxullKERyktjNMC4x8koOeaDNTA2fEJ09BdWLbM/iTW0ithREUP0w== + dependencies: + source-list-map "^2.0.1" + source-map "^0.6.1" + +webpack-sources@^1.1.0, webpack-sources@^1.2.0, webpack-sources@^1.3.0, webpack-sources@^1.4.0, webpack-sources@^1.4.1, webpack-sources@^1.4.3: version "1.4.3" resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== @@ -8419,17 +8964,17 @@ webpack-sources@1.4.3, webpack-sources@^1.1.0, webpack-sources@^1.2.0, webpack-s source-list-map "^2.0.0" source-map "~0.6.1" -webpack-subresource-integrity@1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/webpack-subresource-integrity/-/webpack-subresource-integrity-1.4.1.tgz#e8bf918b444277df46a66cd84542cbcdc5a6272d" - integrity sha512-XMLFInbGbB1HV7K4vHWANzc1CN0t/c4bBvnlvGxGwV45yE/S/feAXIm8dJsCkzqWtSKnmaEgTp/meyeThxG4Iw== +webpack-subresource-integrity@1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/webpack-subresource-integrity/-/webpack-subresource-integrity-1.5.2.tgz#e40b6578d3072e2d24104975249c52c66e9a743e" + integrity sha512-GBWYBoyalbo5YClwWop9qe6Zclp8CIXYGIz12OPclJhIrSplDxs1Ls1JDMH8xBPPrg1T6ISaTW9Y6zOrwEiAzw== dependencies: webpack-sources "^1.3.0" -webpack@4.44.1: - version "4.44.1" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.44.1.tgz#17e69fff9f321b8f117d1fda714edfc0b939cc21" - integrity sha512-4UOGAohv/VGUNQJstzEywwNxqX417FnjZgZJpJQegddzPmTvph37eBIRbRTfdySXzVtJXLJfbMN3mMYhM6GdmQ== +webpack@4.44.2: + version "4.44.2" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.44.2.tgz#6bfe2b0af055c8b2d1e90ed2cd9363f841266b72" + integrity sha512-6KJVGlCxYdISyurpQ0IPTklv+DULv05rs2hseIXer6D7KrUicRDLFb4IUM1S6LUAKypPM/nSiVSuv8jHu1m3/Q== dependencies: "@webassemblyjs/ast" "1.9.0" "@webassemblyjs/helper-module-context" "1.9.0" @@ -8455,14 +9000,7 @@ webpack@4.44.1: watchpack "^1.7.4" webpack-sources "^1.4.1" -websocket-driver@0.6.5: - version "0.6.5" - resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.6.5.tgz#5cb2556ceb85f4373c6d8238aa691c8454e13a36" - integrity sha1-XLJVbOuF9Dc8bYI4qmkchFThOjY= - dependencies: - websocket-extensions ">=0.1.1" - -websocket-driver@>=0.5.1: +websocket-driver@>=0.5.1, websocket-driver@^0.7.4: version "0.7.4" resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760" integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== @@ -8481,20 +9019,6 @@ whatwg-mimetype@^2.3.0: resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== -whatwg-url@^8.0.0: - version "8.5.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.5.0.tgz#7752b8464fc0903fec89aa9846fc9efe07351fd3" - integrity sha512-fy+R77xWv0AiqfLl4nuGUlQ3/6b5uNfQ4WAbGQVMYshCTCCPK9psC1nWh3XHuxGVCtlcDDQPQW1csmmIQo+fwg== - dependencies: - lodash "^4.7.0" - tr46 "^2.0.2" - webidl-conversions "^6.1.0" - -when@~3.6.x: - version "3.6.4" - resolved "https://registry.yarnpkg.com/when/-/when-3.6.4.tgz#473b517ec159e2b85005497a13983f095412e34e" - integrity sha1-RztRfsFZ4rhQBUl6E5g/CVQS404= - which-boxed-primitive@^1.0.1, which-boxed-primitive@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" @@ -8534,13 +9058,37 @@ which-typed-array@^1.1.2: has-symbols "^1.0.1" is-typed-array "^1.1.3" -which@^1.2.9, which@^1.3.1: +which@^1.2.9: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== dependencies: isexe "^2.0.0" +which@^2.0.1, which@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +wide-align@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== + dependencies: + string-width "^1.0.2 || 2" + +wildcard@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.0.tgz#a77d20e5200c6faaac979e4b3aadc7b3dd7f8fec" + integrity sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw== + +word-wrap@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== + worker-farm@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8" @@ -8605,7 +9153,7 @@ y18n@^5.0.5: resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== -yallist@^3.0.0, yallist@^3.0.2, yallist@^3.0.3: +yallist@^3.0.2: version "3.1.1" resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== @@ -8615,6 +9163,11 @@ yallist@^4.0.0: resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== +yaml@^1.10.0: + version "1.10.2" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" + integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== + yargs-parser@^13.1.2: version "13.1.2" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" @@ -8644,7 +9197,7 @@ yargs@^13.3.2: y18n "^4.0.0" yargs-parser "^13.1.2" -yargs@^16.1.1: +yargs@^16.2.0: version "16.2.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== @@ -8662,7 +9215,9 @@ yocto-queue@^0.1.0: resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== -zone.js@~0.10.2: - version "0.10.3" - resolved "https://registry.yarnpkg.com/zone.js/-/zone.js-0.10.3.tgz#3e5e4da03c607c9dcd92e37dd35687a14a140c16" - integrity sha512-LXVLVEq0NNOqK/fLJo3d0kfzd4sxwn2/h67/02pjCjfKDxgx1i9QqpvtHD8CrBnSSwMw5+dy11O7FRX5mkO7Cg== +zone.js@^0.11.4: + version "0.11.4" + resolved "https://registry.yarnpkg.com/zone.js/-/zone.js-0.11.4.tgz#0f70dcf6aba80f698af5735cbb257969396e8025" + integrity sha512-DDh2Ab+A/B+9mJyajPjHFPWfYU1H+pdun4wnnk0OcQTNjem1XQSZ2CDW+rfZEUDjv5M19SBqAkjZi0x5wuB5Qw== + dependencies: + tslib "^2.0.0" diff --git a/runWebconsole.sh b/runWebconsole.sh index 70972ffd2..8b22eaf92 100755 --- a/runWebconsole.sh +++ b/runWebconsole.sh @@ -2,7 +2,7 @@ LAST_PWD=$(pwd) DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" > /dev/null && pwd )" -cd $DIR/ids-webconsole/src/main/resources/www -yarn run ng serve --progress "$@" +cd $DIR/ids-webconsole/src/main/angular +yarn run ng serve "$@" cd $LAST_PWD From 45a124963341f3a737d74002d4266ad9caabfad8 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Tue, 11 May 2021 13:00:26 +0200 Subject: [PATCH 35/54] Migrated and cleaned ids-webconsole --- ids-webconsole/build.gradle.kts | 11 - .../fhg/aisec/ids/webconsole/WebConsole.java | 38 -- .../ids/webconsole/WebConsoleComponent.java | 129 ----- .../fhg/aisec/ids/webconsole/api/AppApi.java | 296 ----------- .../webconsole/api/AuthorizationRequired.java | 31 -- .../webconsole/api/CORSResponseFilter.java | 54 -- .../fhg/aisec/ids/webconsole/api/CertApi.java | 454 ----------------- .../aisec/ids/webconsole/api/ConfigApi.java | 254 ---------- .../ids/webconsole/api/ConnectionAPI.java | 104 ---- .../ids/webconsole/api/JWTRestAPIFilter.java | 74 --- .../aisec/ids/webconsole/api/MetricAPI.java | 99 ---- .../aisec/ids/webconsole/api/PolicyApi.java | 106 ---- .../aisec/ids/webconsole/api/RouteApi.java | 285 ----------- .../aisec/ids/webconsole/api/SettingsApi.java | 138 ----- .../fhg/aisec/ids/webconsole/api/UserApi.java | 138 ----- .../api/helper/ProcessExecutor.java | 44 -- .../webconsole/api/helper/StreamGobbler.java | 60 --- .../de/fhg/aisec/ids/webconsole/Controller.kt | 0 .../de/fhg/aisec/ids/webconsole/WebConsole.kt | 63 +++ .../de/fhg/aisec/ids/webconsole/api/AppApi.kt | 318 ++++++++++++ .../webconsole/api/AuthorizationRequired.kt | 33 ++ .../ids/webconsole/api/CORSResponseFilter.kt | 51 ++ .../fhg/aisec/ids/webconsole/api/CertApi.kt | 475 ++++++++++++++++++ .../fhg/aisec/ids/webconsole/api/ConfigApi.kt | 271 ++++++++++ .../aisec/ids/webconsole/api/ConnectionAPI.kt | 87 ++++ .../ids/webconsole/api/JWTRestAPIFilter.kt | 71 +++ .../fhg/aisec/ids/webconsole/api/MetricAPI.kt | 96 ++++ .../fhg/aisec/ids/webconsole/api/PolicyApi.kt | 108 ++++ .../fhg/aisec/ids/webconsole/api/RouteApi.kt | 278 ++++++++++ .../aisec/ids/webconsole/api/SettingsApi.kt | 141 ++++++ .../fhg/aisec/ids/webconsole/api/UserApi.kt | 134 +++++ .../aisec/ids/webconsole/api/data/Account.kt} | 8 +- .../webconsole/api/data/AppSearchRequest.kt} | 7 +- .../aisec/ids/webconsole/api/data/Cert.kt} | 28 +- .../ids/webconsole/api/data/Identity.kt} | 23 +- .../aisec/ids/webconsole/api/data/User.kt} | 14 +- .../webconsole/api/data/ValidationInfo.kt} | 12 +- .../webconsole/api/helper/ProcessExecutor.kt | 41 ++ .../webconsole/api/helper/StreamGobbler.kt | 57 +++ .../de/fhg/aisec/ids/webconsole/packageinfo | 0 40 files changed, 2267 insertions(+), 2364 deletions(-) delete mode 100644 ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/WebConsole.java delete mode 100644 ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/WebConsoleComponent.java delete mode 100644 ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/AppApi.java delete mode 100644 ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/AuthorizationRequired.java delete mode 100644 ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/CORSResponseFilter.java delete mode 100644 ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/CertApi.java delete mode 100644 ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/ConfigApi.java delete mode 100644 ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/ConnectionAPI.java delete mode 100644 ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/JWTRestAPIFilter.java delete mode 100644 ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/MetricAPI.java delete mode 100644 ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/PolicyApi.java delete mode 100644 ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/RouteApi.java delete mode 100644 ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/SettingsApi.java delete mode 100644 ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/UserApi.java delete mode 100644 ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/helper/ProcessExecutor.java delete mode 100644 ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/helper/StreamGobbler.java rename ids-webconsole/src/main/{java => kotlin}/de/fhg/aisec/ids/webconsole/Controller.kt (100%) create mode 100644 ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/WebConsole.kt create mode 100644 ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/AppApi.kt create mode 100644 ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/AuthorizationRequired.kt create mode 100644 ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/CORSResponseFilter.kt create mode 100644 ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/CertApi.kt create mode 100644 ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/ConfigApi.kt create mode 100644 ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/ConnectionAPI.kt create mode 100644 ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/JWTRestAPIFilter.kt create mode 100644 ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/MetricAPI.kt create mode 100644 ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/PolicyApi.kt create mode 100644 ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/RouteApi.kt create mode 100644 ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/SettingsApi.kt create mode 100644 ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/UserApi.kt rename ids-webconsole/src/main/{java/de/fhg/aisec/ids/webconsole/api/data/Account.java => kotlin/de/fhg/aisec/ids/webconsole/api/data/Account.kt} (86%) rename ids-webconsole/src/main/{java/de/fhg/aisec/ids/webconsole/api/data/User.java => kotlin/de/fhg/aisec/ids/webconsole/api/data/AppSearchRequest.kt} (86%) rename ids-webconsole/src/main/{java/de/fhg/aisec/ids/webconsole/api/data/Cert.java => kotlin/de/fhg/aisec/ids/webconsole/api/data/Cert.kt} (64%) rename ids-webconsole/src/main/{java/de/fhg/aisec/ids/webconsole/api/data/AppSearchRequest.java => kotlin/de/fhg/aisec/ids/webconsole/api/data/Identity.kt} (71%) rename ids-webconsole/src/main/{java/de/fhg/aisec/ids/webconsole/api/data/Identity.java => kotlin/de/fhg/aisec/ids/webconsole/api/data/User.kt} (80%) rename ids-webconsole/src/main/{java/de/fhg/aisec/ids/webconsole/api/data/ValidationInfo.java => kotlin/de/fhg/aisec/ids/webconsole/api/data/ValidationInfo.kt} (77%) create mode 100644 ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/helper/ProcessExecutor.kt create mode 100644 ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/helper/StreamGobbler.kt rename ids-webconsole/src/main/{java => kotlin}/de/fhg/aisec/ids/webconsole/packageinfo (100%) diff --git a/ids-webconsole/build.gradle.kts b/ids-webconsole/build.gradle.kts index 6e35a39d8..150e65437 100644 --- a/ids-webconsole/build.gradle.kts +++ b/ids-webconsole/build.gradle.kts @@ -15,15 +15,6 @@ plugins { description = "IDS Core Platform Webconsole" -sourceSets { - main { - // only include the OSGI blueprint and the built angular app - resources { - include("OSGI-INF/blueprint/*") - } - } -} - swagger { apiSource( closureOf { @@ -103,8 +94,6 @@ dependencies { providedByBundle("org.bitbucket.b_c", "jose4j", libraryVersions["jose4j"]) implementation("com.auth0", "java-jwt", libraryVersions["auth0Jwt"]) - osgiCore("org.apache.felix", "org.apache.felix.framework", libraryVersions["felixFramework"]) - osgiCore("org.osgi", "osgi.cmpn", libraryVersions["osgiCompendium"]) compileOnly("io.swagger", "swagger-jaxrs", libraryVersions["swagger"]) diff --git a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/WebConsole.java b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/WebConsole.java deleted file mode 100644 index d9bd3d773..000000000 --- a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/WebConsole.java +++ /dev/null @@ -1,38 +0,0 @@ -package de.fhg.aisec.ids.webconsole; - -import de.fhg.aisec.ids.webconsole.api.*; -import org.glassfish.jersey.server.ResourceConfig; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; - -import javax.ws.rs.ApplicationPath; - -@Component -// Path for legacy reasons -@ApplicationPath("cxf/api/v1") -public class WebConsole extends ResourceConfig { - - private static final Logger LOG = LoggerFactory.getLogger(WebConsole.class); - - public WebConsole() { - registerEndpoints(); - } - - private void registerEndpoints() { - LOG.info("Registering WebConsole classes"); - - register(AppApi.class); - register(CertApi.class); - register(ConfigApi.class); - register(ConnectionAPI.class); - register(MetricAPI.class); - register(PolicyApi.class); - register(RouteApi.class); - register(SettingsApi.class); - register(UserApi.class); - - register(CORSResponseFilter.class); - register(JWTRestAPIFilter.class); - } -} diff --git a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/WebConsoleComponent.java b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/WebConsoleComponent.java deleted file mode 100644 index 7a3b0c033..000000000 --- a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/WebConsoleComponent.java +++ /dev/null @@ -1,129 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-webconsole - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.webconsole; - -import de.fhg.aisec.ids.api.acme.AcmeClient; -import de.fhg.aisec.ids.api.cm.ContainerManager; -import de.fhg.aisec.ids.api.conm.ConnectionManager; -import de.fhg.aisec.ids.api.endpointconfig.EndpointConfigManager; -import de.fhg.aisec.ids.api.policy.PAP; -import de.fhg.aisec.ids.api.router.RouteManager; -import de.fhg.aisec.ids.api.settings.Settings; -import org.checkerframework.checker.nullness.qual.Nullable; -import org.osgi.service.component.annotations.*; - -/** - * IDS management console, reachable at http://localhost:8181. - * - *

This OSGi component registers a web application, as soon as it is bound to an - * HttpService interface. The web application will allow to control and configure the IDS - * Core Platform and the connected services. - * - *

Note that the web console does not enforce any authorization or encryption and provides - * everyone with the ability to control highly critical settings of the core platform. It must only - * be used for demonstration purposes and must be deactivated and/or removed in productive use. - * - * @author Julian Schuette (julian.schuette@aisec.fraunhofer.de) - * @author Gerd Brost (gerd.brost@aisec.fraunhofer.de) - * @author Michael Lux (michael.lux@aisec.fraunhofer.de) - */ -@Component(name = "ids-webconsole") -public class WebConsoleComponent { - @Reference(cardinality = ReferenceCardinality.OPTIONAL) - private EndpointConfigManager dynEndConManager = null; - - @Reference(cardinality = ReferenceCardinality.OPTIONAL) - - private Settings settings = null; - - @Reference(cardinality = ReferenceCardinality.OPTIONAL) - private ContainerManager cml = null; - - @Reference(cardinality = ReferenceCardinality.OPTIONAL) - private AcmeClient acmeClient = null; - - @Reference(cardinality = ReferenceCardinality.OPTIONAL) - private RouteManager rm = null; - - @Reference(cardinality = ReferenceCardinality.OPTIONAL) - private ConnectionManager connectionManager = null; - - @Reference(cardinality = ReferenceCardinality.OPTIONAL) - private PAP pap = null; - - private static WebConsoleComponent instance; - - @Activate - @SuppressWarnings("squid:S2696") - protected void activate() { - instance = this; - } - - @Deactivate - @SuppressWarnings("squid:S2696") - protected void deactivate() { - instance = null; - } - - @Nullable - public static AcmeClient getAcmeClient() { - WebConsoleComponent in = instance; - if (in != null) { - return in.acmeClient; - } - return null; - } - - @Nullable - public static ConnectionManager getConnectionManager() { - WebConsoleComponent in = instance; - if (in != null) { - return in.connectionManager; - } - return null; - } - - @Nullable - public static Settings getSettings() { - WebConsoleComponent in = instance; - if (in != null) { - return in.settings; - } - return null; - } - - @Nullable - public static PAP getPolicyAdministrationPoint() { - WebConsoleComponent in = instance; - if (in != null) { - return in.pap; - } - return null; - } - - @Nullable - public static EndpointConfigManager getEndpointConfigManager() { - WebConsoleComponent in = instance; - if (in != null) { - return in.dynEndConManager; - } - return null; - } -} diff --git a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/AppApi.java b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/AppApi.java deleted file mode 100644 index 0afde1afc..000000000 --- a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/AppApi.java +++ /dev/null @@ -1,296 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-webconsole - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.webconsole.api; - -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; -import de.fhg.aisec.ids.api.cm.ApplicationContainer; -import de.fhg.aisec.ids.api.cm.ContainerManager; -import de.fhg.aisec.ids.api.cm.NoContainerExistsException; -import de.fhg.aisec.ids.api.settings.Settings; -import de.fhg.aisec.ids.webconsole.api.data.AppSearchRequest; -import io.swagger.annotations.*; -import org.checkerframework.checker.nullness.qual.NonNull; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import javax.ws.rs.*; -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.core.MediaType; -import java.io.IOException; -import java.time.ZonedDateTime; -import java.util.*; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; - -/** - * REST API interface for managing "apps" in the connector. - * - *

In this implementation, apps are either docker or trustX containers. - * - *

The API will be available at http://localhost:8181/cxf/api/v1/apps/. - * - * @author Julian Schuette (julian.schuette@aisec.fraunhofer.de) - */ -@Component -@Path("app") -@Api( - value = "Applications", - authorizations = {@Authorization(value = "oauth2")}) -public class AppApi { - private static final long PULL_TIMEOUT_MINUTES = 20; - private static final Logger LOG = LoggerFactory.getLogger(AppApi.class); - - private @NonNull ContainerManager cml; - private @NonNull Settings settings; - - public AppApi(@Autowired @NonNull ContainerManager cml, @Autowired @NonNull Settings settings) { - this.cml = cml; - this.settings = settings; - } - - @GET - @Path("list") - @ApiOperation( - value = "List all applications installed in the connector", - notes = "Returns an empty list if no apps are installed", - response = ApplicationContainer.class, - responseContainer = "List") - @ApiResponses(@ApiResponse(code = 200, message = "List of apps")) - @Produces(MediaType.APPLICATION_JSON) - @AuthorizationRequired - public List list() { - List result = cml.list(false); - result.sort( - (app1, app2) -> { - try { - ZonedDateTime date1 = ZonedDateTime.parse(app1.getCreated()); - ZonedDateTime date2 = ZonedDateTime.parse(app2.getCreated()); - return date1.compareTo(date2); - } catch (Exception t) { - LOG.warn("Unexpected app creation date/time. Cannot sort. {}", t.getMessage()); - } - return 0; - }); - return result; - } - - @GET - @Path("start/{containerId}") - @ApiOperation( - value = "Start an application", - notes = - "Starting an application may take some time. This method will start the app asynchronously and return immediately. This method starts the latest version of the app.", - response = Boolean.class) - @ApiResponses( - @ApiResponse( - code = 200, - message = - "true if the app has been requested to be started. " - + "false if no container management layer is available")) - @Produces(MediaType.APPLICATION_JSON) - @AuthorizationRequired - public boolean start( - @ApiParam(value = "ID of the app to start") @PathParam("containerId") String containerId) { - return start(containerId, null); - } - - @GET - @Path("start/{containerId}/{key}") - @ApiOperation( - value = "Start an application", - notes = - "Starting an application may take some time. This method will start the app asynchronously and return immediately. This methods starts a specific version of the app.", - response = Boolean.class) - @ApiResponses( - @ApiResponse( - code = 200, - message = - "true if the app has been requested to be started. " - + "false if no container management layer is available")) - @Produces(MediaType.APPLICATION_JSON) - @AuthorizationRequired - public boolean start( - @ApiParam(value = "ID of the app to start") @PathParam("containerId") String containerId, - @ApiParam(value = "Key for user token (required for trustX containers)") @PathParam("key") - String key) { - try { - cml.startContainer(containerId, key); - return true; - } catch (NoContainerExistsException | ServiceUnavailableException e) { - LOG.error("Error starting container", e); - return false; - } - } - - @GET - @Path("stop/{containerId}") - @ApiOperation( - value = "Stop an app", - notes = - "Stops an application. The application will remain installed and can be re-started later. All temporary data will be lost, however.", - response = Boolean.class) - @ApiResponses( - @ApiResponse( - code = 200, - message = - "true if the app has been requested to be stopped. " - + "false if no container management layer is available")) - @Produces(MediaType.APPLICATION_JSON) - @AuthorizationRequired - public boolean stop( - @ApiParam(value = "ID of the app to stop") @PathParam("containerId") String containerId) { - try { - cml.stopContainer(containerId); - return true; - } catch (NoContainerExistsException | ServiceUnavailableException e) { - LOG.error(e.getMessage(), e); - return false; - } - } - - @POST - // @OPTIONS - @Path("install") - @ApiOperation( - value = "Install an app", - notes = "Requests to install an app.", - response = Boolean.class) - @ApiResponses({ - @ApiResponse( - code = 200, - message = - "If the app has been requested to be installed. " - + "The actual installation takes place asynchronously in the background " - + "and will terminate after a timeout of 20 minutes", - response = Boolean.class), - @ApiResponse( - code = 500, - message = "_No cmld_: If no container management layer is available", - response = String.class), - @ApiResponse( - code = 500, - message = "_Null image_: If imageID not given", - response = String.class) - }) - @Produces(MediaType.APPLICATION_JSON) - @AuthorizationRequired - public String install( - @ApiParam(value = "String with imageID", collectionFormat = "Map") - Map apps) { - ApplicationContainer app = apps.get("app"); - LOG.debug("Request to load {}", app.getImage()); - - final String image = app.getImage(); - if (image == null) { - LOG.warn("Null image"); - throw new InternalServerErrorException("Null image"); - } - LOG.debug("Pulling app {}", image); - ScheduledExecutorService executor = - Executors.newScheduledThreadPool(Runtime.getRuntime().availableProcessors()); - - // Pull image asynchronously and create new container - final Future handler = - executor.submit( - () -> { - Optional containerId = cml.pullImage(app); - return containerId.orElse(null); - }); - // Cancel pulling after 20 minutes, just in case. - executor.schedule(() -> handler.cancel(true), PULL_TIMEOUT_MINUTES, TimeUnit.MINUTES); - return "OK"; - } - - @GET - @Path("wipe") - @ApiOperation(value = "Wipes an app and all its data") - @ApiResponses({ - @ApiResponse(code = 200, message = "If the app is being wiped"), - @ApiResponse(code = 500, message = "_No cmld_ if no container management layer is available") - }) - @AuthorizationRequired - public String wipe( - @ApiParam(value = "ID of the app to wipe") @QueryParam("containerId") String containerId) { - try { - cml.wipe(containerId); - } catch (NullPointerException | NoContainerExistsException e) { - LOG.error(e.getMessage(), e); - } - return "OK"; - } - - @GET - @Path("cml_version") - @ApiOperation( - value = "Returns the version of the currently active container management layer", - response = Map.class) - @Produces(MediaType.APPLICATION_JSON) - @AuthorizationRequired - public Map getCml() { - try { - Map result = new HashMap<>(); - result.put("cml_version", cml.getVersion()); - return result; - } catch (ServiceUnavailableException sue) { - return Collections.emptyMap(); - } - } - - @POST - @Path("search") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @AuthorizationRequired - public List search(AppSearchRequest searchRequest) { - String term = searchRequest.getSearchTerm(); - try { - Client client = ClientBuilder.newBuilder().build(); - String url = settings.getConnectorConfig().getAppstoreUrl(); - - String r = client.target(url).request(MediaType.APPLICATION_JSON).get(String.class); - - ObjectMapper mapper = new ObjectMapper(); - List result = mapper.readValue(r, new TypeReference<>() {}); - if (term != null && !term.equals("")) { - return result - .parallelStream() - .filter( - app -> - (app.getName() != null && app.getName().contains(term)) - || (app.getDescription() != null && app.getDescription().contains(term)) - || (app.getImage() != null && app.getImage().contains(term)) - || (app.getId() != null && app.getId().contains(term)) - || (app.getCategories() != null && app.getCategories().contains(term))) - .collect(Collectors.toList()); - } else { - return result; - } - } catch (IOException e) { - throw new InternalServerErrorException(e); - } - } -} diff --git a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/AuthorizationRequired.java b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/AuthorizationRequired.java deleted file mode 100644 index fa8583adf..000000000 --- a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/AuthorizationRequired.java +++ /dev/null @@ -1,31 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-webconsole - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.webconsole.api; - -import javax.ws.rs.NameBinding; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@NameBinding -@Target({ElementType.TYPE, ElementType.METHOD}) -@Retention(value = RetentionPolicy.RUNTIME) -public @interface AuthorizationRequired {} diff --git a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/CORSResponseFilter.java b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/CORSResponseFilter.java deleted file mode 100644 index b1424784f..000000000 --- a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/CORSResponseFilter.java +++ /dev/null @@ -1,54 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-webconsole - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.webconsole.api; - -import org.osgi.service.component.annotations.Component; - -import javax.ws.rs.container.ContainerRequestContext; -import javax.ws.rs.container.ContainerResponseContext; -import javax.ws.rs.container.ContainerResponseFilter; -import javax.ws.rs.core.MultivaluedMap; -import javax.ws.rs.ext.Provider; -import java.io.IOException; - -/** - * This filter adds Cross-Origin Resource Sharing (CORS) headers to each response. - * - * @author Christian Banse - */ -@Provider -@Component(immediate = true) -public class CORSResponseFilter implements ContainerResponseFilter { - - @Override - public void filter( - ContainerRequestContext requestContext, ContainerResponseContext responseContext) - throws IOException { - MultivaluedMap headers = responseContext.getHeaders(); - - // allow AJAX from everywhere - headers.add("Access-Control-Allow-Origin", "*"); - headers.add( - "Access-Control-Allow-Headers", - "origin, content-type, accept, authorization, X-Requested-With"); - headers.add("Access-Control-Allow-Credentials", "true"); - headers.add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD"); - } -} diff --git a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/CertApi.java b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/CertApi.java deleted file mode 100644 index 446fe8803..000000000 --- a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/CertApi.java +++ /dev/null @@ -1,454 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-webconsole - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.webconsole.api; - -import de.fhg.aisec.ids.api.acme.AcmeClient; -import de.fhg.aisec.ids.api.acme.AcmeTermsOfService; -import de.fhg.aisec.ids.api.settings.ConnectorConfig; -import de.fhg.aisec.ids.api.settings.Settings; -import de.fhg.aisec.ids.webconsole.WebConsoleComponent; -import de.fhg.aisec.ids.webconsole.api.data.Cert; -import de.fhg.aisec.ids.webconsole.api.data.Identity; -import de.fhg.aisec.ids.webconsole.api.helper.ProcessExecutor; -import io.swagger.annotations.*; -import org.apache.cxf.jaxrs.ext.multipart.Attachment; -import org.apache.cxf.jaxrs.ext.multipart.Multipart; -import org.checkerframework.checker.nullness.qual.NonNull; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import javax.ws.rs.*; -import javax.ws.rs.core.MediaType; -import java.io.*; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.nio.file.FileSystems; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.cert.Certificate; -import java.security.cert.CertificateException; -import java.security.cert.CertificateFactory; -import java.security.cert.X509Certificate; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.List; -import java.util.UUID; - -/** - * REST API interface for managing certificates in the connector. - * - *

The API will be available at http://localhost:8181/cxf/api/v1/certs/. - * - * @author Hamed Rasifard (hamed.rasifard@aisec.fraunhofer.de) - */ -@Component -@Path("/certs") -@Api( - value = "Identities and Certificates", - authorizations = {@Authorization(value = "oauth2")}) -public class CertApi { - private static final Logger LOG = LoggerFactory.getLogger(CertApi.class); - private static final String KEYSTORE_PWD = "password"; - private static final String TRUSTSTORE_FILE = "truststore.p12"; - private static final String KEYSTORE_FILE = "provider-keystore.p12"; - - private final Settings settings; - - public CertApi(@Autowired @NonNull Settings settings) { - this.settings = settings; - } - - @GET - @ApiOperation(value = "Starts ACME renewal over X509v3 certificates") - @Path("acme_renew/{target}") - @AuthorizationRequired - public boolean getAcmeCert( - @ApiParam( - value = - "Identifier of the component to renew. Currently, the only valid value is __webconsole__") - @PathParam("target") - String target) { - ConnectorConfig config = settings.getConnectorConfig(); - AcmeClient acmeClient = WebConsoleComponent.getAcmeClient(); - if ("webconsole".equals(target) && acmeClient != null) { - acmeClient.renewCertificate( - FileSystems.getDefault().getPath("etc", "tls-webconsole"), - URI.create(config.getAcmeServerWebcon()), - config.getAcmeDnsWebcon().trim().split("\\s*,\\s*"), - config.getAcmePortWebcon()); - - return true; - } else { - LOG.warn("ACME renewal for services other than WebConsole is not yet implemented!"); - - return false; - } - } - - @GET - @ApiOperation( - value = "Retrieves the Terms of Service (tos) of the ACME endpoint", - response = AcmeTermsOfService.class) - @Path("acme_tos") - @AuthorizationRequired - public AcmeTermsOfService getAcmeTermsOfService( - @ApiParam(value = "URI to retrieve the TOS from") @QueryParam("uri") String uri) { - AcmeClient acmeClient = WebConsoleComponent.getAcmeClient(); - if (acmeClient == null) { - return null; - } - return acmeClient.getTermsOfService(URI.create(uri.trim())); - } - - @GET - @Path("list_certs") - @ApiOperation( - value = "List installed certificates from trust store.", - notes = "Certificates in this list refer to public keys that are trusted by this connector.") - @ApiResponses({ - @ApiResponse(code = 200, message = "List of certificates"), - @ApiResponse(code = 500, message = "_Truststore not found_: If no trust store available"), - }) - @Produces(MediaType.APPLICATION_JSON) - @AuthorizationRequired - public List listCerts() { - File truststore = getKeystoreFile(TRUSTSTORE_FILE); - return getKeystoreEntries(truststore); - } - - @GET - @Path("list_identities") - @ApiOperation( - value = "List installed certificates from the private key store.", - notes = - "Certificates in this list refer to private keys that can be used as identities by the connector.") - @Produces(MediaType.APPLICATION_JSON) - @AuthorizationRequired - public List listIdentities() { - File keystoreFile = getKeystoreFile(KEYSTORE_FILE); - return getKeystoreEntries(keystoreFile); - } - - @POST - @Path("create_identity") - @Produces(MediaType.APPLICATION_JSON) - @Consumes(MediaType.APPLICATION_JSON) - @AuthorizationRequired - public String createIdentity( - @ApiParam(value = "Specification of the identity to create a key pair for") Identity spec) { - String alias = UUID.randomUUID().toString(); - try { - this.doGenKeyPair(alias, spec, "RSA", 2048, "SHA1WITHRSA", getKeystoreFile(KEYSTORE_FILE)); - } catch (Exception e) { - throw new InternalServerErrorException(e); - } - return alias; - } - - /** Delete a private/public key pair. */ - @POST - @Path("delete_identity") - @ApiOperation(value = "Deletes a public/private key pair") - @Produces(MediaType.APPLICATION_JSON) - @AuthorizationRequired - public String deleteIdentity(String alias) { - File keyStoreFile = getKeystoreFile(KEYSTORE_FILE); - boolean success = delete(alias, keyStoreFile); - if (success) { - return alias; - } else { - throw new InternalServerErrorException(); - } - } - - /** Deletes a trusted certificate. */ - @POST - @Path("delete_cert") - @ApiOperation(value = "Deletes a trusted certificate") - @Produces(MediaType.APPLICATION_JSON) - @AuthorizationRequired - public String deleteCert(String alias) { - File keyStoreFile = getKeystoreFile(TRUSTSTORE_FILE); - boolean success = delete(alias, keyStoreFile); - if (success) { - return alias; - } else { - throw new InternalServerErrorException(); - } - } - - @POST - @Path("/install_trusted_cert") - @ApiOperation(value = "Installs a new trusted public key certificate.") - @ApiImplicitParams({ - @ApiImplicitParam(dataType = "java.io.File", name = "attachment", paramType = "formData") - }) - @Produces(MediaType.TEXT_HTML) - @Consumes(MediaType.MULTIPART_FORM_DATA) - @AuthorizationRequired - public String installTrustedCert( - @ApiParam(hidden = true, name = "attachment") @Multipart("upfile") Attachment attachment) - throws IOException { - - String filename = attachment.getContentDisposition().getParameter("filename"); - File tempPath = File.createTempFile(filename, "cert"); - try (OutputStream out = new FileOutputStream(tempPath); - InputStream in = attachment.getObject(InputStream.class)) { - int read; - byte[] bytes = new byte[1024]; - while ((read = in.read(bytes)) != -1) { - out.write(bytes, 0, read); - } - } - - boolean success = storeCert(getKeystoreFile(TRUSTSTORE_FILE), tempPath); - if (success) { - if (!tempPath.delete()) { - LOG.warn("Failed to delete temporary file " + tempPath); - } - return "Trusted certificate has been uploaded to " + TRUSTSTORE_FILE; - } - - return "Error: certificate has NOT been uploaded to " + TRUSTSTORE_FILE; - } - - /** Stores a certificate in a JKS truststore. */ - private boolean storeCert(File trustStoreFile, File certFile) { - CertificateFactory cf; - String alias = certFile.getName().replace(".", "_"); - try { - cf = CertificateFactory.getInstance("X.509"); - InputStream certstream = fullStream(certFile.getAbsolutePath()); - Certificate certs = cf.generateCertificate(certstream); - - try (FileInputStream fis = new FileInputStream(trustStoreFile); - FileOutputStream fos = new FileOutputStream(trustStoreFile)) { - KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType()); - String password = KEYSTORE_PWD; - keystore.load(fis, password.toCharArray()); - - // Add the certificate - keystore.setCertificateEntry(alias, certs); - - keystore.store(fos, password.toCharArray()); - } - - return true; - } catch (CertificateException | KeyStoreException | NoSuchAlgorithmException | IOException e) { - LOG.error(e.getMessage(), e); - return false; - } - } - - private static InputStream fullStream(String fname) throws IOException { - FileInputStream fis = new FileInputStream(fname); - DataInputStream dis = new DataInputStream(fis); - byte[] bytes = new byte[dis.available()]; - dis.readFully(bytes); - ByteArrayInputStream bais = new ByteArrayInputStream(bytes); - dis.close(); - return bais; - } - - /** - * Retrieve a keystore file. - * - *

This method will first try to load keystores from Karaf's ./etc dir, then checks if a path - * has been given by -Dkeystore.dir=.. and finally just lets the classloader load the file from - * classpath. - * - *

If the file cannot be found, this method returns null. - */ - private File getKeystoreFile(String fileName) { - // If we run in karaf platform, we expect the keystore to be in - // KARAF_BASE/etc - String etcDir = System.getProperty("karaf.etc"); - if (etcDir != null) { - File f = new File(etcDir + File.separator + fileName); - if (f.exists()) { - return f; - } - } - - // Otherwise, we allow setting the directory to search for by - // -Dkeystore.dir=... - String keystoreDir = System.getProperty("keystore.dir"); - if (keystoreDir != null) { - File f = new File(keystoreDir + File.separator + fileName); - if (f.exists()) { - return f; - } - } - - // In case of unit tests, we expect resources to be "somehow" available in current working dir - File f = new File(fileName); - if (f.exists()) { - return f; - } - - // Last resort: let the classloader find the file - URL clFile = Thread.currentThread().getContextClassLoader().getResource(fileName); - try { - if (clFile != null) { - return new File(clFile.toURI()); - } - } catch (URISyntaxException e) { - LOG.error(e.getMessage(), e); - } - - throw new NotFoundException( - "Keystore/truststore file could not be found. Cannot continue. Given filename: " - + fileName); - } - - /** Returns all entries (private keys and certificates) from a Java keystore. */ - private List getKeystoreEntries(File keystoreFile) { - List certs = new ArrayList<>(); - try (FileInputStream fis = new FileInputStream(keystoreFile)) { - KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType()); - keystore.load(fis, KEYSTORE_PWD.toCharArray()); - - Enumeration enumeration = keystore.aliases(); - while (enumeration.hasMoreElements()) { - String alias = enumeration.nextElement(); - Certificate certificate = keystore.getCertificate(alias); - Cert cert = new Cert(); - cert.alias = alias; - cert.file = keystoreFile.getName().replaceFirst("[.][^.]+$", ""); - cert.certificate = certificate.toString(); - if (!(certificate instanceof X509Certificate)) { - continue; - } - - X509Certificate c = (X509Certificate) certificate; - cert.subjectAltNames = c.getSubjectAlternativeNames(); - // Get distinguished name - String dn = c.getSubjectX500Principal().getName(); - for (String entry : dn.split(",")) { - String[] kv = entry.split("="); - if (kv.length < 2) { - continue; - } - switch (kv[0]) { - case "CN": - cert.subjectCN = kv[1]; - break; - case "OU": - cert.subjectOU = kv[1]; - break; - case "O": - cert.subjectO = kv[1]; - break; - case "L": - cert.subjectL = kv[1]; - break; - case "S": - cert.subjectS = kv[1]; - break; - case "C": - cert.subjectC = kv[1]; - break; - default: - break; - } - } - - certs.add(cert); - } - } catch (java.security.cert.CertificateException - | KeyStoreException - | NoSuchAlgorithmException - | IOException e) { - LOG.error(e.getMessage(), e); - } - return certs; - } - - @SuppressWarnings("SameParameterValue") - private void doGenKeyPair( - String alias, - Identity spec, - String keyAlgName, - int keySize, - String sigAlgName, - File keyStoreFile) - throws InterruptedException, IOException { - /* - * We call the keystore binary programmatically. This is portable, in - * contrast to creating key pairs and self-signed certificates - * programmatically, which depends on internal classes of the JVM, such - * as sun.security.* or oracle.*. - */ - String[] keytoolCmd = - new String[] { - "/bin/sh", - "-c", - "keytool", - "-genkey", - "-alias", - alias, - "-keyalg", - keyAlgName, - "-keysize", - Integer.toString(keySize), - "-sigalg", - sigAlgName, - "-keystore", - keyStoreFile.getAbsolutePath(), - "-dname", - "CN=" + spec.cn + ", OU=" + spec.ou + ", O=" + spec.o + ", L=" + spec.l + ", S=" + spec.s - + ", C=" + spec.c, - "-storepass", - KEYSTORE_PWD, - "-keypass", - KEYSTORE_PWD - }; - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - new ProcessExecutor().execute(keytoolCmd, bos, bos); - LOG.debug("Keytool: " + new String(bos.toByteArray(), StandardCharsets.UTF_8)); - } - - protected boolean delete(String alias, File file) { - try (FileInputStream fis = new FileInputStream(file)) { - KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType()); - keystore.load(fis, KEYSTORE_PWD.toCharArray()); - if (keystore.containsAlias(alias)) { - keystore.deleteEntry(alias); - try (FileOutputStream fos = new FileOutputStream(file)) { - keystore.store(fos, KEYSTORE_PWD.toCharArray()); - } - } else { - LOG.warn("Alias not available. Cannot delete it: " + alias); - } - } catch (java.security.cert.CertificateException - | NoSuchAlgorithmException - | KeyStoreException - | IOException e) { - LOG.error(e.getMessage(), e); - return false; - } - return true; - } -} diff --git a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/ConfigApi.java b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/ConfigApi.java deleted file mode 100644 index d13290c10..000000000 --- a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/ConfigApi.java +++ /dev/null @@ -1,254 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-webconsole - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.webconsole.api; - -import de.fhg.aisec.ids.api.Constants; -import de.fhg.aisec.ids.api.conm.ConnectionManager; -import de.fhg.aisec.ids.api.conm.IDSCPServerEndpoint; -import de.fhg.aisec.ids.api.endpointconfig.EndpointConfigManager; -import de.fhg.aisec.ids.api.router.RouteManager; -import de.fhg.aisec.ids.api.router.RouteObject; -import de.fhg.aisec.ids.api.settings.ConnectionSettings; -import de.fhg.aisec.ids.api.settings.ConnectorConfig; -import de.fhg.aisec.ids.api.settings.Settings; -import de.fhg.aisec.ids.webconsole.WebConsoleComponent; -import io.swagger.annotations.*; -import org.checkerframework.checker.nullness.qual.NonNull; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import javax.ws.rs.*; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import java.util.*; -import java.util.function.Function; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.stream.Collectors; - -/** - * REST API interface for configurations in the connector. - * - *

The API will be available at http://localhost:8181/cxf/api/v1/config/. - * - * @author Julian Schuette (julian.schuette@aisec.fraunhofer.de) - * @author Gerd Brost (gerd.brost@aisec.fraunhofer.de) - * @author Michael Lux (michael.lux@aisec.fraunhofer.de) - */ -@Component -@Path("/config") -@Api( - value = "Connector Configuration", - authorizations = {@Authorization(value = "oauth2")} -) -public class ConfigApi { - private static final Pattern CONNECTION_CONFIG_PATTERN = Pattern.compile(".* - ([^ ]+)$"); - - private Settings settings; - private RouteManager routeManager; - - public ConfigApi(@Autowired @NonNull Settings settings,@Autowired @NonNull RouteManager routeManager) { - this.settings = settings; - this.routeManager = routeManager; - } - - @GET - @ApiOperation(value = "Retrieves the current configuration", response = ConnectorConfig.class) - @Path("/connectorConfig") - @Produces(MediaType.APPLICATION_JSON) - @AuthorizationRequired - public ConnectorConfig get() { - return settings.getConnectorConfig(); - } - - @POST - //@OPTIONS - @Path("/connectorConfig") - @ApiOperation(value = "Sets the overall configuration of the connector") - @ApiResponses( - @ApiResponse( - code = 500, - message = - "_No valid preferences received_: If incorrect configuration parameter is provided" - )) - @Consumes(MediaType.APPLICATION_JSON) - @AuthorizationRequired - public String set(ConnectorConfig config) { - if (config == null) { - throw new BadRequestException("No valid preferences received!"); - } - - settings.setConnectorConfig(config); - - return "OK"; - } - - /** - * Save connection configuration of a particular connection. - * - * @param connection The name of the connection - * @param conSettings The connection configuration of the connection - */ - @POST - @Path("/connectionConfigs/{con}") - @ApiOperation(value = "Save connection configuration of a particular connection") - @ApiResponses( - @ApiResponse( - code = 500, - message = - "_No valid connection settings received!_: If incorrect connection settings parameter is provided" - )) - @Consumes(MediaType.APPLICATION_JSON) - @AuthorizationRequired - public Response setConnectionConfigurations( - @PathParam("con") String connection, ConnectionSettings conSettings) { - if (conSettings == null) { - Response.serverError().entity("No valid connection settings received!").build(); - } - - //connection has format " - host:port" - //store only "host:port" in database to make connection available in other parts of the application - // where rout_id is not available - - Matcher m = CONNECTION_CONFIG_PATTERN.matcher(connection); - if (!m.matches()){ - //GENERAL_CONFIG has changed - settings.setConnectionSettings(connection, conSettings); - } else { - // specific endpoint config has changed - settings.setConnectionSettings(m.group(1), conSettings); - - //notify EndpointConfigurationListeners that some endpointConfig has changed - EndpointConfigManager dynEndConManager = WebConsoleComponent.getEndpointConfigManager(); - if (dynEndConManager != null){ - dynEndConManager.notify(m.group(1)); - } - } - - return Response.ok().build(); - } - - /** - * Sends configuration of a connection - * - * @param connection Connection identifier - * @return The connection configuration of the requested connection - */ - @GET - @Path("/connectionConfigs/{con}") - @ApiOperation(value = "Sends configuration of a connection", response = ConnectionSettings.class) - @Produces(MediaType.APPLICATION_JSON) - @AuthorizationRequired - public ConnectionSettings getConnectionConfigurations(@PathParam("con") String connection) { - return settings.getConnectionSettings(connection); - } - - /** - * Sends configurations of all connections - * - * @return Map of connection names/configurations - */ - @GET - @Path("/connectionConfigs") - @ApiOperation(value = "Retrieves configurations of all connections") - @ApiResponses( - @ApiResponse( - code = 200, - message = "Map of connections and configurations", - response = ConnectionSettings.class, - responseContainer = "Map" - )) - @Produces(MediaType.APPLICATION_JSON) - @AuthorizationRequired - public Map getAllConnectionConfigurations() { - ConnectionManager connectionManager = WebConsoleComponent.getConnectionManager(); - if (settings == null || connectionManager == null || routeManager == null) { - return Collections.emptyMap(); - } - - // Set of all connection configurations, properly ordered - Map allSettings = - new TreeMap<>( - (o1, o2) -> { - if (Constants.GENERAL_CONFIG.equals(o1)) { - return -1; - } else if (Constants.GENERAL_CONFIG.equals(o2)) { - return 1; - } else { - return o1.compareTo(o2); - } - }); - // Load all existing entries - allSettings.putAll(settings.getAllConnectionSettings()); - // Assert global configuration entry - allSettings.putIfAbsent(Constants.GENERAL_CONFIG, new ConnectionSettings()); - - Map> routeInputs = - routeManager - .getRoutes() - .stream() - .map(RouteObject::getId) - .collect(Collectors.toMap(Function.identity(), routeManager::getRouteInputUris)); - - //add all available endpoints - for (IDSCPServerEndpoint endpoint : connectionManager.listAvailableEndpoints()) { - // For every currently available endpoint, go through all preferences and check - // if the id is already there. If not, create empty config. - String hostIdentifier = endpoint.getHost() + ":" + endpoint.getPort(); - - //create missing endpoint configurations - if (allSettings.keySet().stream().noneMatch(hostIdentifier::equals)){ - allSettings.put(hostIdentifier, new ConnectionSettings()); - } - } - - //add route id before host identifier for web console view - Map retAllSettings = new HashMap<>(); - for (Map.Entry entry : allSettings.entrySet()){ - - if (entry.getKey().equals(Constants.GENERAL_CONFIG)){ - retAllSettings.put(entry.getKey(), entry.getValue()); - } else { - - List endpointIdentifiers = - routeInputs - .entrySet() - .stream() - .filter(e -> e.getValue().stream().anyMatch(u -> u.startsWith("idsserver://" + entry.getKey()))) - .map(e -> e.getKey() + " - " + entry.getKey()) - .collect(Collectors.toList()); - - if (endpointIdentifiers.isEmpty()) { - endpointIdentifiers = - Collections.singletonList("" + " - " + entry.getKey()); - } - - // add endpoint configurations - endpointIdentifiers.forEach( - endpointIdentifier -> { - if (retAllSettings.keySet().stream().noneMatch(endpointIdentifier::equals)) { - retAllSettings.put(endpointIdentifier, entry.getValue()); - }}); - } - } - - return retAllSettings; - } -} diff --git a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/ConnectionAPI.java b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/ConnectionAPI.java deleted file mode 100644 index edbc34fd0..000000000 --- a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/ConnectionAPI.java +++ /dev/null @@ -1,104 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-webconsole - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.webconsole.api; - -import de.fhg.aisec.ids.api.conm.ConnectionManager; -import de.fhg.aisec.ids.api.conm.IDSCPIncomingConnection; -import de.fhg.aisec.ids.api.conm.IDSCPOutgoingConnection; -import de.fhg.aisec.ids.api.conm.IDSCPServerEndpoint; -import de.fhg.aisec.ids.webconsole.WebConsoleComponent; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.Authorization; -import org.springframework.stereotype.Component; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; -import java.util.ArrayList; -import java.util.List; - -/** - * REST API interface for managing connections from and to the connector. - * - *

The API will be available at st/. - * - * @author Gerd Brost (gerd.brost@aisec.fraunhofer.de) - */ -@Component -@Path("/connections") -@Api( - value = "IDSCP Connections", - authorizations = {@Authorization(value = "oauth2")} -) -public class ConnectionAPI { - - @GET - @Path("/incoming") - @ApiOperation( - value = "Returns a list of all inbound connections", - response = IDSCPIncomingConnection.class, - responseContainer = "List" - ) - @Produces(MediaType.APPLICATION_JSON) - @AuthorizationRequired - public List getIncoming() { - ConnectionManager cm = WebConsoleComponent.getConnectionManager(); - if (cm == null) { - return new ArrayList<>(); - } - return cm.listIncomingConnections(); - } - - @GET - @Path("/outgoing") - @ApiOperation( - value = "Returns a list of all outbound connections", - response = IDSCPOutgoingConnection.class, - responseContainer = "List" - ) - @Produces(MediaType.APPLICATION_JSON) - @AuthorizationRequired - public List getOutgoing() { - ConnectionManager cm = WebConsoleComponent.getConnectionManager(); - if (cm == null) { - return new ArrayList<>(); - } - return cm.listOutgoingConnections(); - } - - @GET - @Path("/endpoints") - @ApiOperation( - value = "Returns a list of all endpoints provided by this connector", - response = IDSCPServerEndpoint.class, - responseContainer = "List" - ) - @Produces(MediaType.APPLICATION_JSON) - @AuthorizationRequired - public List getAvailableEndpoints() { - ConnectionManager cm = WebConsoleComponent.getConnectionManager(); - if (cm == null) { - return new ArrayList<>(); - } - return cm.listAvailableEndpoints(); - } -} diff --git a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/JWTRestAPIFilter.java b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/JWTRestAPIFilter.java deleted file mode 100644 index 393d04745..000000000 --- a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/JWTRestAPIFilter.java +++ /dev/null @@ -1,74 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-webconsole - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.webconsole.api; - -import com.auth0.jwt.JWT; -import com.auth0.jwt.JWTVerifier; -import com.auth0.jwt.algorithms.Algorithm; -import com.auth0.jwt.interfaces.DecodedJWT; -import org.osgi.service.component.annotations.Component; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.ws.rs.container.ContainerRequestContext; -import javax.ws.rs.container.ContainerRequestFilter; -import javax.ws.rs.core.Response; -import javax.ws.rs.ext.Provider; - -/** - * This filter verifies JWT bearer tokens provided by HTTP "Authorization" header. - * - *

- * - * @author Hendrik Meyer zum Felde hendrik.meyerzumfelde@aisec.fraunhofer.de - */ -@Provider -@Component(immediate = true) -@AuthorizationRequired -public class JWTRestAPIFilter implements ContainerRequestFilter { - private static final Logger LOG = LoggerFactory.getLogger(JWTRestAPIFilter.class); - - @Override - public void filter(ContainerRequestContext requestContext) { - try { - // Get JWT Bearer token from HTTP Authorization header - String authorizationHeader = requestContext.getHeaderString("Authorization"); - if (authorizationHeader == null) { - requestContext.abortWith( - Response.status(Response.Status.UNAUTHORIZED) - .entity("Authorization token missing.") - .build()); - return; - } - - // Verify token - String jwt = authorizationHeader.substring(7).trim(); - Algorithm algorithm = Algorithm.HMAC256(UserApi.key.getEncoded()); - JWTVerifier verifier = - JWT.require(algorithm).withIssuer("ids-connector").build(); // Reusable verifier instance - DecodedJWT validToken = verifier.verify(jwt); - } catch (Exception e) { - LOG.warn("Invalid JWT token in request for " + requestContext.getUriInfo().getPath()); - // On token validation error (or other), return HTTP 403. - requestContext.abortWith( - Response.status(Response.Status.UNAUTHORIZED).entity("Invalid token.").build()); - } - } -} diff --git a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/MetricAPI.java b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/MetricAPI.java deleted file mode 100644 index 41f3be297..000000000 --- a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/MetricAPI.java +++ /dev/null @@ -1,99 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-webconsole - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.webconsole.api; - -import io.swagger.annotations.*; -import org.springframework.stereotype.Component; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; -import java.lang.management.*; -import java.text.DecimalFormat; -import java.util.HashMap; -import java.util.Map; - -/** - * REST API interface for platform metrics. - * - *

The API will be available at http://localhost:8181/cxf/api/v1/metric/. - * - * @author Julian Schuette (julian.schuette@aisec.fraunhofer.de) - */ -@Component -@Path("/metric") -@Api( - value = "Runtime Metrics", - authorizations = {@Authorization(value = "oauth2")} -) -public class MetricAPI { - - private static final DecimalFormat loadAvgFormat = new DecimalFormat("###.##"); - - /** - * Returns map of metrics. - * - * @return Map with system metrics - */ - @GET - @Path("get") - @ApiOperation(value = "Returns metrics values") - @ApiResponses( - @ApiResponse( - code = 200, - message = "Map of metrics values", - response = String.class, - responseContainer = "Map" - )) - @Produces(MediaType.APPLICATION_JSON) - @AuthorizationRequired - public Map getMetrics() { - HashMap result = new HashMap<>(); - - OperatingSystemMXBean os = ManagementFactory.getOperatingSystemMXBean(); - MemoryMXBean mem = ManagementFactory.getMemoryMXBean(); - ThreadMXBean threads = ManagementFactory.getThreadMXBean(); - ClassLoadingMXBean cl = ManagementFactory.getClassLoadingMXBean(); - - double loadAvg = os.getSystemLoadAverage(); - - result.put( - "cpu.availableprocessors", String.valueOf(Runtime.getRuntime().availableProcessors())); - result.put("cpu.loadavg", loadAvg >= 0 ? loadAvgFormat.format(loadAvg) : "N/A"); - result.put("mem.free", String.valueOf(Runtime.getRuntime().freeMemory())); - result.put("mem.max", String.valueOf(Runtime.getRuntime().maxMemory())); - result.put("mem.total", String.valueOf(Runtime.getRuntime().totalMemory())); - result.put("mem.heapusage", String.valueOf(mem.getHeapMemoryUsage())); - result.put("mem.nonheapusage", String.valueOf(mem.getNonHeapMemoryUsage())); - result.put("mem.objfinalizationcount", String.valueOf(mem.getObjectPendingFinalizationCount())); - result.put("thread.peakcount", String.valueOf(threads.getPeakThreadCount())); - result.put("thread.count", String.valueOf(threads.getThreadCount())); - result.put("thread.totalstartedcount", String.valueOf(threads.getTotalStartedThreadCount())); - result.put("cl.currentcount", String.valueOf(cl.getLoadedClassCount())); - result.put("cl.totalcount", String.valueOf(cl.getTotalLoadedClassCount())); - result.put("cl.unloadedcount", String.valueOf(cl.getUnloadedClassCount())); - result.put("os.arch", os.getArch()); - result.put("os.version", os.getVersion()); - result.put("os.name", String.valueOf(os.getName())); - - return result; - } -} diff --git a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/PolicyApi.java b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/PolicyApi.java deleted file mode 100644 index 95dd77df6..000000000 --- a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/PolicyApi.java +++ /dev/null @@ -1,106 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-webconsole - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.webconsole.api; - -import de.fhg.aisec.ids.api.policy.PAP; -import de.fhg.aisec.ids.webconsole.WebConsoleComponent; -import io.swagger.annotations.*; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; - -import javax.ws.rs.*; -import javax.ws.rs.core.MediaType; -import java.util.ArrayList; -import java.util.List; - -/** - * REST API interface for managing usage control policies in the connector. - * - *

The API will be available at http://localhost:8181/cxf/api/v1/policies/. - * - * @author Julian Schuette (julian.schuette@aisec.fraunhofer.de) - */ -@Component -@Path("/policies") -@Api( - value = "Usage Control Policies", - authorizations = {@Authorization(value = "oauth2")} -) -public class PolicyApi { - private static final Logger LOG = LoggerFactory.getLogger(PolicyApi.class); - - @GET - @Path("list") - @ApiOperation(value = "Lists active usage control rules", responseContainer = "List") - @ApiResponses( - @ApiResponse( - code = 200, - message = "List of usage control rules", - response = String.class, - responseContainer = "List" - )) - @Produces(MediaType.APPLICATION_JSON) - @AuthorizationRequired - public List list() { - PAP pap = WebConsoleComponent.getPolicyAdministrationPoint(); - if (pap == null) { - return new ArrayList<>(); - } - return pap.listRules(); - } - - /** - * Returns the Prolog theory of all policies. Could be removed in later version. - * - * @return Policy Prolog - */ - @GET - @Path("policyProlog") - @Produces(MediaType.TEXT_PLAIN) - @ApiOperation(value = "Returns the full usage control policy as a Prolog theory") - @AuthorizationRequired - public String getPolicyProlog() { - PAP pap = WebConsoleComponent.getPolicyAdministrationPoint(); - if (pap == null) { - return ""; - } - return pap.getPolicy(); - } - - @POST - //@OPTIONS - @Path("install") - @ApiOperation(value = "Installs a new usage control policy as a Prolog theory file") - @Consumes(MediaType.MULTIPART_FORM_DATA) - @AuthorizationRequired - public String install( - @FormParam(value = "policy_name") @DefaultValue(value = "default policy") String policyName, - @FormParam(value = "policy_description") @DefaultValue(value = "") String policyDescription, - @FormParam(value = "policy_file") String policy) { - LOG.info("Received policy file. name: {}, desc: {}", policyName, policyDescription); - PAP pap = WebConsoleComponent.getPolicyAdministrationPoint(); - if (pap == null) { - return "No PAP available"; - } - pap.loadPolicy(policy); - return "OK"; - } -} diff --git a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/RouteApi.java b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/RouteApi.java deleted file mode 100644 index d53407662..000000000 --- a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/RouteApi.java +++ /dev/null @@ -1,285 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-webconsole - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.webconsole.api; - -import de.fhg.aisec.ids.api.Result; -import de.fhg.aisec.ids.api.policy.PAP; -import de.fhg.aisec.ids.api.router.*; -import de.fhg.aisec.ids.webconsole.WebConsoleComponent; -import de.fhg.aisec.ids.webconsole.api.data.ValidationInfo; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import io.swagger.annotations.Authorization; -import org.checkerframework.checker.nullness.qual.NonNull; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import javax.ws.rs.*; -import javax.ws.rs.core.MediaType; -import java.util.Collection; -import java.util.List; -import java.util.Map; - -/** - * REST API interface for "data pipes" in the connector. - * - *

This implementation uses Camel Routes as data pipes, i.e. the API methods allow inspection of - * camel routes in different camel contexts. - * - *

The API will be available at http://localhost:8181/cxf/api/v1/routes/. - * - * @author Julian Schuette (julian.schuette@aisec.fraunhofer.de) - */ -@Component -@Path("/routes") -@Api( - value = "Message Routing", - authorizations = {@Authorization(value = "oauth2")} -) -public class RouteApi { - private static final Logger LOG = LoggerFactory.getLogger(RouteApi.class); - - private @NonNull RouteManager rm; - - public RouteApi(@Autowired @NonNull RouteManager rm) { - this.rm = rm; - } - - /** - * Returns map from camel context to list of camel routes. - * - *

Example: - * - *

{"camel-1":["Route(demo-route)[[From[timer://simpleTimer?period\u003d10000]] -\u003e - * [SetBody[simple{This is a demo body!}], Log[The message contains ${body}]]]"]} - * - * @return The resulting route objects - */ - @GET - @Path("list") - @ApiOperation( - value = "Returns map from camel context to list of camel routes.", - response = RouteObject.class, - responseContainer = "List" - ) - @Produces(MediaType.APPLICATION_JSON) - @AuthorizationRequired - public List list() { - return rm.getRoutes(); - } - - @GET - @Path("/get/{id}") - @ApiOperation(value = "Get a Camel route", response = RouteObject.class) - @Produces(MediaType.APPLICATION_JSON) - @AuthorizationRequired - public RouteObject get(@ApiParam(value = "Route ID") @PathParam("id") @NonNull String id) { - RouteObject oRoute = rm.getRoute(id); - if (oRoute == null) { - throw new NotFoundException("Route not found"); - } - return oRoute; - } - - @GET - @Path("/getAsString/{id}") - @ApiOperation(value = "Gets an XML representation of a Camel route.") - @Produces(MediaType.TEXT_PLAIN) - @AuthorizationRequired - public String getAsString(@ApiParam(value = "Route ID") @PathParam("id") String id) { - String routeAsString = rm.getRouteAsString(id); - if (routeAsString == null) { - throw new NotFoundException("Route not found"); - } - return routeAsString; - } - - /** Stop a route based on an id. */ - @GET - @Path("/startroute/{id}") - @ApiOperation(value = "Starts a Camel route. The route will start to process messages.") - @Produces(MediaType.APPLICATION_JSON) - @AuthorizationRequired - public Result startRoute(@PathParam("id") String id) { - try { - rm.startRoute(id); - return new Result(); - } catch (Exception e) { - LOG.warn(e.getMessage(), e); - return new Result(false, e.getMessage()); - } - } - - @POST - @Path("/save/{id}") - @ApiOperation(value = "Save changes to a route. ") - @Consumes(MediaType.TEXT_PLAIN) - @Produces(MediaType.APPLICATION_JSON) - @AuthorizationRequired - public Result saveRoute(@PathParam("id") @NonNull String id, @NonNull String routeDefinition) { - try { - rm.saveRoute(id, routeDefinition); - return new Result(); - } catch (Exception e) { - LOG.warn(e.getMessage(), e); - return new Result(false, e.getMessage()); - } - } - - @PUT - @Path("/add") - @ApiOperation(value = "Adds a new route, provided as Camel XML.") - @Consumes(MediaType.TEXT_PLAIN) - @Produces(MediaType.APPLICATION_JSON) - @AuthorizationRequired - public Result addRoute(@NonNull String routeDefinition) { - try { - rm.addRoute(routeDefinition); - return new Result(); - } catch (Exception e) { - LOG.warn(e.getMessage(), e); - return new Result(false, e.getMessage()); - } - } - - /** Stop a route based on its id. */ - @GET - @Path("/stoproute/{id}") - @ApiOperation( - value = - "Stops a Camel route. The route will remain installed but it will not process any messages." - ) - @Produces(MediaType.APPLICATION_JSON) - @AuthorizationRequired - public Result stopRoute(@PathParam("id") String id) { - try { - rm.stopRoute(id); - return new Result(); - } catch (Exception e) { - LOG.warn(e.getMessage(), e); - return new Result(false, e.getMessage()); - } - } - - /** Get runtime metrics of a route */ - @GET - @ApiOperation(value = "Get runtime metrics of a route", response = RouteMetrics.class) - @Path("/metrics/{id}") - @AuthorizationRequired - public RouteMetrics getMetrics(@PathParam("id") String routeId) { - return rm.getRouteMetrics().get(routeId); - } - - /** Get aggregated runtime metrics of all routes */ - @GET - @ApiOperation( - value = "Get aggregated runtime metrics of all routes", - response = RouteMetrics.class - ) - @Path("/metrics") - @AuthorizationRequired - public RouteMetrics getMetrics() { - return aggregateMetrics(rm.getRouteMetrics().values()); - } - - /** - * Aggregates metrics of several rules - * - * @param currentMetrics List of RouteMetrics to process - * @return The aggregated RouteMetrics object - */ - private RouteMetrics aggregateMetrics(Collection currentMetrics) { - RouteMetrics metrics = new RouteMetrics(); - metrics.setCompleted(currentMetrics.stream().mapToLong(RouteMetrics::getCompleted).sum()); - metrics.setFailed(currentMetrics.stream().mapToLong(RouteMetrics::getFailed).sum()); - metrics.setFailuresHandled( - currentMetrics.stream().mapToLong(RouteMetrics::getFailuresHandled).sum()); - metrics.setInflight(currentMetrics.stream().mapToLong(RouteMetrics::getInflight).sum()); - metrics.setMaxProcessingTime( - currentMetrics.stream().mapToLong(RouteMetrics::getMaxProcessingTime).max().orElse(0)); - // This is technically nonsense, as average values of average values are not really - // the average values of the single elements, but it's the best aggregation we can get. - metrics.setMeanProcessingTime( - (long) - currentMetrics - .stream() - .mapToLong(RouteMetrics::getMeanProcessingTime) - .filter(i -> i >= 0) - .average() - .orElse(.0)); - metrics.setMinProcessingTime( - currentMetrics.stream().mapToLong(RouteMetrics::getMinProcessingTime).min().orElse(0)); - metrics.setCompleted(currentMetrics.stream().mapToLong(RouteMetrics::getCompleted).sum()); - return metrics; - } - - /** - * Retrieve list of supported components (aka protocols which can be addressed by Camel) - * - * @return List of supported protocols - */ - @GET - @Path("/components") - @Produces(MediaType.APPLICATION_JSON) - @AuthorizationRequired - public List getComponents() { - return rm.listComponents(); - } - - /** Retrieve list of currently installed endpoints (aka URIs to/from which routes exist) */ - @GET - @Path("/list_endpoints") - @AuthorizationRequired - public Map listEndpoints() { - return rm.listEndpoints(); - } - - @GET - @Path("/validate/{routeId}") - @Produces(MediaType.APPLICATION_JSON) - @AuthorizationRequired - public ValidationInfo validate(@PathParam("routeId") String routeId) { - PAP pap = WebConsoleComponent.getPolicyAdministrationPoint(); - if (pap == null) { - throw new InternalServerErrorException(); - } - RouteVerificationProof rvp = pap.verifyRoute(routeId); - if (rvp == null) { - throw new InternalServerErrorException(); - } - ValidationInfo vi = new ValidationInfo(); - vi.valid = rvp.isValid(); - if (!rvp.isValid()) { - vi.counterExamples = rvp.getCounterExamples(); - } - return vi; - } - - @GET - @Path("/prolog/{routeId}") - @Produces(MediaType.TEXT_PLAIN) - @AuthorizationRequired - public String getRouteProlog(@PathParam("routeId") @NonNull String routeId) { - return rm.getRouteAsProlog(routeId); - } -} diff --git a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/SettingsApi.java b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/SettingsApi.java deleted file mode 100644 index bf9f995c0..000000000 --- a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/SettingsApi.java +++ /dev/null @@ -1,138 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-webconsole - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.webconsole.api; - -import de.fhg.aisec.ids.api.infomodel.ConnectorProfile; -import de.fhg.aisec.ids.api.infomodel.InfoModel; -import de.fraunhofer.iais.eis.Connector; -import de.fraunhofer.iais.eis.util.TypedLiteral; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.Authorization; -import org.checkerframework.checker.nullness.qual.NonNull; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import javax.ws.rs.*; -import javax.ws.rs.core.MediaType; -import java.util.stream.Collectors; - -/** - * REST API interface for Connector settings in the connector. - * - *

The API will be available at http://localhost:8181/cxf/api/v1/settings/. - */ - -// ConnectorProfile will be processed by custom Jackson deserializer -@Component -@Path("/settings") -@Api( - value = "Self-Description and Connector Profiles", - authorizations = {@Authorization(value = "oauth2")}) -public class SettingsApi { - private static final Logger LOG = LoggerFactory.getLogger(SettingsApi.class); - - private @NonNull InfoModel im; - - public SettingsApi(@Autowired @NonNull InfoModel im) { - this.im = im; - } - - @POST - @Path("/connectorProfile") - @ApiOperation(value = "Configure the connector's self-description (\"Connector Profile\").") - @Consumes(MediaType.APPLICATION_JSON) - @AuthorizationRequired - public String postConnectorProfile(ConnectorProfile profile) { - if (im.setConnector(profile)) { - return "ConnectorProfile successfully stored."; - } else { - throw new InternalServerErrorException("Error while storing ConnectorProfile"); - } - } - - /** Returns Connector profile based on currently stored preferences or empty Connector profile */ - @GET - @Path("/connectorProfile") - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation( - value = "Returns this connector's self-description (\"Connector Profile\")", - response = ConnectorProfile.class) - @AuthorizationRequired - public ConnectorProfile getConnectorProfile() { - Connector c = im.getConnector(); - if (c == null) { - return new ConnectorProfile(); - } else { - return new ConnectorProfile( - c.getSecurityProfile(), - c.getId(), - c.getMaintainer(), - c.getDescription().stream().map(TypedLiteral.class::cast).collect(Collectors.toList())); - } - } - - /** - * Returns connector profile based on currently stored preferences or statically provided JSON-LD - * model, or empty connector profile if none of those are available. - */ - @GET - @Path("/selfInformation") - @Produces("application/ld+json") - // TODO Document ApiOperation - public String getSelfInformation() { - try { - return im.getConnectorAsJsonLd(); - } catch (NullPointerException e) { - LOG.warn("Connector description build failed, building empty description.", e); - return null; - } - } - - /** Set static connector profile based on passed JSON-LD data */ - @POST - @Path("/selfInformation") - // TODO Document ApiOperation - @Consumes("application/ld+json") - @AuthorizationRequired - public void setSelfInformation(String selfInformation) { - try { - im.setConnectorByJsonLd(selfInformation); - } catch (NullPointerException e) { - LOG.warn("Connector description build failed, building empty description.", e); - } - } - - /** Remove static connector profile based on JSON-LD data */ - @DELETE - @Path("/selfInformation") - // TODO Document ApiOperation - @Consumes("application/ld+json") - @AuthorizationRequired - public void removeSelfInformation() { - try { - im.setConnectorByJsonLd(null); - } catch (NullPointerException e) { - LOG.warn("Connector description build failed, building empty description.", e); - } - } -} diff --git a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/UserApi.java b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/UserApi.java deleted file mode 100644 index aa76a3343..000000000 --- a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/UserApi.java +++ /dev/null @@ -1,138 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-webconsole - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.webconsole.api; - -import com.auth0.jwt.JWT; -import com.auth0.jwt.algorithms.Algorithm; -import de.fhg.aisec.ids.webconsole.api.data.User; -import io.swagger.annotations.Api; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; - -import javax.crypto.KeyGenerator; -import javax.security.auth.callback.Callback; -import javax.security.auth.callback.NameCallback; -import javax.security.auth.callback.PasswordCallback; -import javax.security.auth.login.Configuration; -import javax.security.auth.login.LoginContext; -import javax.security.auth.login.LoginException; -import javax.ws.rs.Consumes; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import java.security.Key; -import java.security.NoSuchAlgorithmException; -import java.util.Calendar; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; - -import static javax.ws.rs.core.MediaType.APPLICATION_JSON; -import static javax.ws.rs.core.Response.Status.UNAUTHORIZED; - -@Component -@Path("/user") -@Api(value = "User Authentication") -@Produces(APPLICATION_JSON) -@Consumes(APPLICATION_JSON) -public class UserApi { - private static final Logger LOG = LoggerFactory.getLogger(UserApi.class); - static Key key; - - static { - try { - key = KeyGenerator.getInstance("HmacSHA256").generateKey(); - } catch (NoSuchAlgorithmException e) { - e.printStackTrace(); - } - } - - /** - * Given a correct username/password, this method returns a JWT token that is valid for one day. - * - * @param user Username/password. - * @return A JSON object of the form { "token" : } if successful, 401 UNAUTHORIZED if not. - */ - @POST - @Path("/login") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - public Response authenticateUser(User user) { - try { - // Authenticate the user using the credentials provided - if (!authenticate(user.username, user.password)) { - return Response.status(UNAUTHORIZED).build(); - } - - // Issue a token for the user - String token = issueToken(user.username); - - // Return the token on the response - Map result = new HashMap<>(); - result.put("token", token); - return Response.ok().entity(result).build(); - } catch (Throwable e) { - e.printStackTrace(); - return Response.status(UNAUTHORIZED).build(); - } - } - - private String issueToken(String username) { - Calendar cal = Calendar.getInstance(); - cal.setTimeInMillis(cal.getTimeInMillis() + 86_400_000); - Date tomorrow = cal.getTime(); - - return JWT.create() - .withClaim("user", username) - .withExpiresAt(tomorrow) - .withIssuer("ids-connector") - .sign(Algorithm.HMAC256(UserApi.key.getEncoded())); - } - - private boolean authenticate(String user, String password) throws LoginException { - /* Login with JaaS. We use the default realm "karaf". When using default PropertiesLoginModule, users are - configured in karaf-assembly/src/main/resources/etc/users.properties. Other modules such as OAuth, LDAP, JDBC - can be configured as needed without changing this code here. - */ - if (Configuration.getConfiguration().getAppConfigurationEntry("karaf") == null) { - LOG.warn("No LoginModules configured for karaf. This is okay if running as unit test. " + - "If this message appears in Karaf container, make sure that JAAS is available."); - return "ids".equals(user) && "ids".equals(password); - } - LoginContext ctx = - new LoginContext( - "karaf", - callbacks -> { - for (Callback cb : callbacks) { - if (cb instanceof PasswordCallback) { - ((PasswordCallback) cb).setPassword(password.toCharArray()); - } - if (cb instanceof NameCallback) { - ((NameCallback) cb).setName(user); - } - } - }); - ctx.login(); - return true; - } -} diff --git a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/helper/ProcessExecutor.java b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/helper/ProcessExecutor.java deleted file mode 100644 index 11a6e2176..000000000 --- a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/helper/ProcessExecutor.java +++ /dev/null @@ -1,44 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-webconsole - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.webconsole.api.helper; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.io.OutputStream; - -public class ProcessExecutor { - private static final Logger LOG = LoggerFactory.getLogger(ProcessExecutor.class); - - public int execute(String[] cmd, OutputStream stdout, OutputStream stderr) - throws InterruptedException, IOException { - Runtime rt = Runtime.getRuntime(); - Process proc = rt.exec(cmd); - - StreamGobbler errorGobbler = new StreamGobbler(proc.getErrorStream(), stderr); - StreamGobbler outputGobbler = new StreamGobbler(proc.getInputStream(), stdout); - - errorGobbler.start(); - outputGobbler.start(); - - return proc.waitFor(); - } -} diff --git a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/helper/StreamGobbler.java b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/helper/StreamGobbler.java deleted file mode 100644 index 51e06bf89..000000000 --- a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/helper/StreamGobbler.java +++ /dev/null @@ -1,60 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-webconsole - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.webconsole.api.helper; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.*; -import java.nio.charset.StandardCharsets; - -class StreamGobbler extends Thread { - private static final Logger LOG = LoggerFactory.getLogger(StreamGobbler.class); - InputStream is; - OutputStream out; - - public StreamGobbler(InputStream is, OutputStream out) { - this.is = is; - this.out = out; - } - - @Override - public void run() { - try (InputStreamReader isr = new InputStreamReader(is, StandardCharsets.UTF_8); - BufferedReader br = new BufferedReader(isr)) { - if (out != null) { - try (BufferedWriter bw = - new BufferedWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8))) { - String line; - while ((line = br.readLine()) != null) { - bw.write(line); - bw.newLine(); - } - } - } else { - while (true) { - if (br.readLine() == null) break; - } - } - } catch (IOException ioe) { - LOG.error(ioe.getMessage(), ioe); - } - } -} diff --git a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/Controller.kt b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/Controller.kt similarity index 100% rename from ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/Controller.kt rename to ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/Controller.kt diff --git a/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/WebConsole.kt b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/WebConsole.kt new file mode 100644 index 000000000..292d69eac --- /dev/null +++ b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/WebConsole.kt @@ -0,0 +1,63 @@ +/*- + * ========================LICENSE_START================================= + * ids-webconsole + * %% + * Copyright (C) 2021 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.webconsole + +import de.fhg.aisec.ids.webconsole.api.AppApi +import de.fhg.aisec.ids.webconsole.api.CORSResponseFilter +import de.fhg.aisec.ids.webconsole.api.CertApi +import de.fhg.aisec.ids.webconsole.api.ConfigApi +import de.fhg.aisec.ids.webconsole.api.ConnectionAPI +import de.fhg.aisec.ids.webconsole.api.JWTRestAPIFilter +import de.fhg.aisec.ids.webconsole.api.MetricAPI +import de.fhg.aisec.ids.webconsole.api.PolicyApi +import de.fhg.aisec.ids.webconsole.api.RouteApi +import de.fhg.aisec.ids.webconsole.api.SettingsApi +import de.fhg.aisec.ids.webconsole.api.UserApi +import org.glassfish.jersey.server.ResourceConfig +import org.slf4j.LoggerFactory +import org.springframework.stereotype.Component +import javax.ws.rs.ApplicationPath + +@Component +@ApplicationPath("cxf/api/v1") +class WebConsole : ResourceConfig() { + private fun registerEndpoints() { + LOG.info("Registering WebConsole classes") + register(AppApi::class.java) + register(CertApi::class.java) + register(ConfigApi::class.java) + register(ConnectionAPI::class.java) + register(MetricAPI::class.java) + register(PolicyApi::class.java) + register(RouteApi::class.java) + register(SettingsApi::class.java) + register(UserApi::class.java) + register(CORSResponseFilter::class.java) + register(JWTRestAPIFilter::class.java) + } + + companion object { + private val LOG = LoggerFactory.getLogger(WebConsole::class.java) + } + + init { + registerEndpoints() + } +} diff --git a/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/AppApi.kt b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/AppApi.kt new file mode 100644 index 000000000..a3ba2a1f0 --- /dev/null +++ b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/AppApi.kt @@ -0,0 +1,318 @@ +/*- + * ========================LICENSE_START================================= + * ids-webconsole + * %% + * Copyright (C) 2019 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.webconsole.api + +import com.fasterxml.jackson.core.type.TypeReference +import com.fasterxml.jackson.databind.ObjectMapper +import de.fhg.aisec.ids.api.cm.ApplicationContainer +import de.fhg.aisec.ids.api.cm.ContainerManager +import de.fhg.aisec.ids.api.cm.NoContainerExistsException +import de.fhg.aisec.ids.api.settings.Settings +import de.fhg.aisec.ids.webconsole.api.data.AppSearchRequest +import io.swagger.annotations.Api +import io.swagger.annotations.ApiOperation +import io.swagger.annotations.ApiParam +import io.swagger.annotations.ApiResponse +import io.swagger.annotations.ApiResponses +import io.swagger.annotations.Authorization +import org.slf4j.LoggerFactory +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.stereotype.Component +import java.io.IOException +import java.time.ZonedDateTime +import java.util.concurrent.Executors +import java.util.concurrent.TimeUnit +import java.util.stream.Collectors +import javax.ws.rs.Consumes +import javax.ws.rs.GET +import javax.ws.rs.InternalServerErrorException +import javax.ws.rs.POST +import javax.ws.rs.Path +import javax.ws.rs.PathParam +import javax.ws.rs.Produces +import javax.ws.rs.QueryParam +import javax.ws.rs.ServiceUnavailableException +import javax.ws.rs.client.ClientBuilder +import javax.ws.rs.core.MediaType + +/** + * REST API interface for managing "apps" in the connector. + * + * + * In this implementation, apps are either docker or trustX containers. + * + * + * The API will be available at http://localhost:8181/cxf/api/v1/apps/. + * + * @author Julian Schuette (julian.schuette@aisec.fraunhofer.de) + */ +@Component +@Path("app") +@Api(value = "Applications", authorizations = [Authorization(value = "oauth2")]) +class AppApi { + + @Autowired private lateinit var cml: ContainerManager + @Autowired private lateinit var settings: Settings + + @GET + @Path("list") + @ApiOperation( + value = "List all applications installed in the connector", + notes = "Returns an empty list if no apps are installed", + response = ApplicationContainer::class, + responseContainer = "List" + ) + @ApiResponses(ApiResponse(code = 200, message = "List of apps")) + @Produces( + MediaType.APPLICATION_JSON + ) + @AuthorizationRequired + fun list(): List { + return cml.list(false).sortedWith( + java.util.Comparator { app1: ApplicationContainer, app2: ApplicationContainer -> + try { + val date1 = ZonedDateTime.parse(app1.created) + val date2 = ZonedDateTime.parse(app2.created) + return@Comparator date1.compareTo(date2) + } catch (t: Exception) { + LOG.warn("Unexpected app creation date/time. Cannot sort. {}", t.message) + } + 0 + } + ) + } + + @GET + @Path("start/{containerId}") + @ApiOperation( + value = "Start an application", + notes = "Starting an application may take some time. " + + "This method will start the app asynchronously and return immediately. " + + "This method starts the latest version of the app.", + response = Boolean::class + ) + @ApiResponses( + ApiResponse( + code = 200, + message = "true if the app has been requested to be started. " + + "false if no container management layer is available" + ) + ) + @Produces(MediaType.APPLICATION_JSON) + @AuthorizationRequired + fun start( + @ApiParam(value = "ID of the app to start") @PathParam("containerId") containerId: String? + ): Boolean { + return start(containerId, null) + } + + @GET + @Path("start/{containerId}/{key}") + @ApiOperation( + value = "Start an application", + notes = "Starting an application may take some time. This method will start the app asynchronously and return immediately. This methods starts a specific version of the app.", + response = Boolean::class + ) + @ApiResponses( + ApiResponse( + code = 200, + message = "true if the app has been requested to be started. " + + "false if no container management layer is available" + ) + ) + @Produces(MediaType.APPLICATION_JSON) + @AuthorizationRequired + fun start( + @ApiParam(value = "ID of the app to start") @PathParam("containerId") containerId: String?, + @ApiParam(value = "Key for user token (required for trustX containers)") @PathParam("key") key: String? + ): Boolean { + return try { + cml.startContainer(containerId, key) + true + } catch (e: NoContainerExistsException) { + LOG.error("Error starting container", e) + false + } catch (e: ServiceUnavailableException) { + LOG.error("Error starting container", e) + false + } + } + + @GET + @Path("stop/{containerId}") + @ApiOperation( + value = "Stop an app", + notes = "Stops an application. The application will remain installed and can be re-started later. All temporary data will be lost, however.", + response = Boolean::class + ) + @ApiResponses( + ApiResponse( + code = 200, + message = "true if the app has been requested to be stopped. " + + "false if no container management layer is available" + ) + ) + @Produces(MediaType.APPLICATION_JSON) + @AuthorizationRequired + fun stop( + @ApiParam(value = "ID of the app to stop") @PathParam("containerId") containerId: String? + ): Boolean { + return try { + cml.stopContainer(containerId) + true + } catch (e: NoContainerExistsException) { + LOG.error(e.message, e) + false + } catch (e: ServiceUnavailableException) { + LOG.error(e.message, e) + false + } + } + + @POST // @OPTIONS + @Path("install") + @ApiOperation(value = "Install an app", notes = "Requests to install an app.", response = Boolean::class) + @ApiResponses( + ApiResponse( + code = 200, + message = "If the app has been requested to be installed. " + + "The actual installation takes place asynchronously in the background " + + "and will terminate after a timeout of 20 minutes", + response = Boolean::class + ), + ApiResponse( + code = 500, + message = "_No cmld_: If no container management layer is available", + response = String::class + ), + ApiResponse(code = 500, message = "_Null image_: If imageID not given", response = String::class) + ) + @Produces( + MediaType.APPLICATION_JSON + ) + @AuthorizationRequired + fun install( + @ApiParam(value = "String with imageID", collectionFormat = "Map") apps: Map + ): String { + val app = apps["app"] + LOG.debug("Request to load {}", app!!.image) + val image = app.image + if (image == null) { + LOG.warn("Null image") + throw InternalServerErrorException("Null image") + } + LOG.debug("Pulling app {}", image) + val executor = Executors.newScheduledThreadPool(Runtime.getRuntime().availableProcessors()) + + // Pull image asynchronously and create new container + val handler = executor.submit { + val containerId = cml.pullImage(app) + containerId.orElse(null) + } + // Cancel pulling after 20 minutes, just in case. + executor.schedule({ handler.cancel(true) }, PULL_TIMEOUT_MINUTES, TimeUnit.MINUTES) + return "OK" + } + + @GET + @Path("wipe") + @ApiOperation(value = "Wipes an app and all its data") + @ApiResponses( + ApiResponse(code = 200, message = "If the app is being wiped"), + ApiResponse(code = 500, message = "_No cmld_ if no container management layer is available") + ) + @AuthorizationRequired + fun wipe( + @ApiParam(value = "ID of the app to wipe") @QueryParam("containerId") containerId: String? + ): String { + try { + cml.wipe(containerId) + } catch (e: NullPointerException) { + LOG.error(e.message, e) + } catch (e: NoContainerExistsException) { + LOG.error(e.message, e) + } + return "OK" + } + + @GET + @Path("cml_version") + @ApiOperation( + value = "Returns the version of the currently active container management layer", + response = MutableMap::class + ) + @Produces( + MediaType.APPLICATION_JSON + ) + @AuthorizationRequired + fun getCml(): Map { + return try { + val result: MutableMap = HashMap() + result["cml_version"] = cml.version + result + } catch (sue: ServiceUnavailableException) { + emptyMap() + } + } + + @POST + @Path("search") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @AuthorizationRequired + fun search(searchRequest: AppSearchRequest): List { + val term = searchRequest.searchTerm + return try { + val client = ClientBuilder.newBuilder().build() + val url = settings.connectorConfig.appstoreUrl + val r = client.target(url).request(MediaType.APPLICATION_JSON).get( + String::class.java + ) + val mapper = ObjectMapper() + val result: List = mapper.readValue( + r, + object : TypeReference>() {} + ) + if (term != "") { + result + .parallelStream() + .filter { app: ApplicationContainer -> + ( + app.name != null && app.name.contains(term) || + app.description != null && app.description.contains(term) || + app.image != null && app.image.contains(term) || + app.id != null && app.id.contains(term) || + app.categories != null && app.categories.contains(term) + ) + } + .collect(Collectors.toList()) + } else { + result + } + } catch (e: IOException) { + throw InternalServerErrorException(e) + } + } + + companion object { + private const val PULL_TIMEOUT_MINUTES: Long = 20 + private val LOG = LoggerFactory.getLogger(AppApi::class.java) + } +} diff --git a/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/AuthorizationRequired.kt b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/AuthorizationRequired.kt new file mode 100644 index 000000000..17c896f6f --- /dev/null +++ b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/AuthorizationRequired.kt @@ -0,0 +1,33 @@ +/*- + * ========================LICENSE_START================================= + * ids-webconsole + * %% + * Copyright (C) 2019 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.webconsole.api + +import javax.ws.rs.NameBinding + +@NameBinding +@Target( + AnnotationTarget.ANNOTATION_CLASS, + AnnotationTarget.CLASS, + AnnotationTarget.FUNCTION, + AnnotationTarget.PROPERTY_GETTER, + AnnotationTarget.PROPERTY_SETTER +) +@Retention(AnnotationRetention.RUNTIME) +annotation class AuthorizationRequired diff --git a/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/CORSResponseFilter.kt b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/CORSResponseFilter.kt new file mode 100644 index 000000000..7ec1d2494 --- /dev/null +++ b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/CORSResponseFilter.kt @@ -0,0 +1,51 @@ +/*- + * ========================LICENSE_START================================= + * ids-webconsole + * %% + * Copyright (C) 2019 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.webconsole.api + +import java.io.IOException +import javax.ws.rs.container.ContainerRequestContext +import javax.ws.rs.container.ContainerResponseContext +import javax.ws.rs.container.ContainerResponseFilter +import javax.ws.rs.ext.Provider + +/** + * This filter adds Cross-Origin Resource Sharing (CORS) headers to each response. + * + * @author Christian Banse + */ +@Provider +class CORSResponseFilter : ContainerResponseFilter { + @Throws(IOException::class) + override fun filter( + requestContext: ContainerRequestContext, + responseContext: ContainerResponseContext + ) { + val headers = responseContext.headers + + // allow AJAX from everywhere + headers.add("Access-Control-Allow-Origin", "*") + headers.add( + "Access-Control-Allow-Headers", + "origin, content-type, accept, authorization, X-Requested-With" + ) + headers.add("Access-Control-Allow-Credentials", "true") + headers.add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD") + } +} diff --git a/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/CertApi.kt b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/CertApi.kt new file mode 100644 index 000000000..6d723a0e9 --- /dev/null +++ b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/CertApi.kt @@ -0,0 +1,475 @@ +/*- + * ========================LICENSE_START================================= + * ids-webconsole + * %% + * Copyright (C) 2019 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.webconsole.api + +import de.fhg.aisec.ids.api.acme.AcmeClient +import de.fhg.aisec.ids.api.acme.AcmeTermsOfService +import de.fhg.aisec.ids.api.settings.Settings +import de.fhg.aisec.ids.webconsole.api.data.Cert +import de.fhg.aisec.ids.webconsole.api.data.Identity +import de.fhg.aisec.ids.webconsole.api.helper.ProcessExecutor +import io.swagger.annotations.Api +import io.swagger.annotations.ApiImplicitParam +import io.swagger.annotations.ApiImplicitParams +import io.swagger.annotations.ApiOperation +import io.swagger.annotations.ApiParam +import io.swagger.annotations.ApiResponse +import io.swagger.annotations.ApiResponses +import io.swagger.annotations.Authorization +import org.apache.cxf.jaxrs.ext.multipart.Attachment +import org.apache.cxf.jaxrs.ext.multipart.Multipart +import org.slf4j.LoggerFactory +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.stereotype.Component +import java.io.ByteArrayInputStream +import java.io.ByteArrayOutputStream +import java.io.DataInputStream +import java.io.File +import java.io.FileInputStream +import java.io.FileOutputStream +import java.io.IOException +import java.io.InputStream +import java.net.URI +import java.net.URISyntaxException +import java.nio.charset.StandardCharsets +import java.nio.file.FileSystems +import java.security.KeyStore +import java.security.KeyStoreException +import java.security.NoSuchAlgorithmException +import java.security.cert.CertificateException +import java.security.cert.CertificateFactory +import java.security.cert.X509Certificate +import java.util.UUID +import javax.ws.rs.Consumes +import javax.ws.rs.GET +import javax.ws.rs.InternalServerErrorException +import javax.ws.rs.NotFoundException +import javax.ws.rs.POST +import javax.ws.rs.Path +import javax.ws.rs.PathParam +import javax.ws.rs.Produces +import javax.ws.rs.QueryParam +import javax.ws.rs.core.MediaType + +/** + * REST API interface for managing certificates in the connector. + * + * + * The API will be available at http://localhost:8181/cxf/api/v1/certs/. + * + * @author Hamed Rasifard (hamed.rasifard@aisec.fraunhofer.de) + */ +@Component +@Path("/certs") +@Api(value = "Identities and Certificates", authorizations = [Authorization(value = "oauth2")]) +class CertApi { + + @Autowired(required = false) + private var acmeClient: AcmeClient? = null + + @Autowired + private lateinit var settings: Settings + + @GET + @ApiOperation(value = "Starts ACME renewal over X509v3 certificates") + @Path("acme_renew/{target}") + @AuthorizationRequired + fun getAcmeCert( + @ApiParam(value = "Identifier of the component to renew. Currently, the only valid value is __webconsole__") + @PathParam("target") target: String + ): Boolean { + val config = settings.connectorConfig + return if ("webconsole" == target && acmeClient != null) { + acmeClient?.renewCertificate( + FileSystems.getDefault().getPath("etc", "tls-webconsole"), + URI.create(config.acmeServerWebcon), + config.acmeDnsWebcon.trim { it <= ' ' }.split("\\s*,\\s*".toRegex()).toTypedArray(), + config.acmePortWebcon + ) + true + } else { + LOG.warn("ACME renewal for services other than WebConsole is not yet implemented!") + false + } + } + + @GET + @ApiOperation( + value = "Retrieves the Terms of Service (tos) of the ACME endpoint", + response = AcmeTermsOfService::class + ) + @Path("acme_tos") + @AuthorizationRequired + fun getAcmeTermsOfService( + @ApiParam(value = "URI to retrieve the TOS from") @QueryParam("uri") uri: String + ): AcmeTermsOfService? { + return acmeClient?.getTermsOfService(URI.create(uri.trim { it <= ' ' })) + } + + @GET + @Path("list_certs") + @ApiOperation( + value = "List installed certificates from trust store.", + notes = "Certificates in this list refer to public keys that are trusted by this connector." + ) + @ApiResponses( + ApiResponse(code = 200, message = "List of certificates"), + ApiResponse(code = 500, message = "_Truststore not found_: If no trust store available") + ) + @Produces( + MediaType.APPLICATION_JSON + ) + @AuthorizationRequired + fun listCerts(): List { + val truststore = getKeystoreFile(settings.connectorConfig.truststoreName) + return getKeystoreEntries(truststore) + } + + @GET + @Path("list_identities") + @ApiOperation( + value = "List installed certificates from the private key store.", + notes = "Certificates in this list refer to private keys that can be used as identities by the connector." + ) + @Produces( + MediaType.APPLICATION_JSON + ) + @AuthorizationRequired + fun listIdentities(): List { + val keystoreFile = getKeystoreFile(settings.connectorConfig.keystoreName) + return getKeystoreEntries(keystoreFile) + } + + @POST + @Path("create_identity") + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + @AuthorizationRequired + fun createIdentity( + @ApiParam(value = "Specification of the identity to create a key pair for") spec: Identity + ): String { + val alias = UUID.randomUUID().toString() + try { + doGenKeyPair( + alias, spec, "RSA", 2048, "SHA1WITHRSA", + getKeystoreFile(settings.connectorConfig.keystoreName) + ) + } catch (e: Exception) { + throw InternalServerErrorException(e) + } + return alias + } + + /** Delete a private/public key pair. */ + @POST + @Path("delete_identity") + @ApiOperation(value = "Deletes a public/private key pair") + @Produces(MediaType.APPLICATION_JSON) + @AuthorizationRequired + fun deleteIdentity(alias: String): String { + val keyStoreFile = getKeystoreFile(settings.connectorConfig.keystoreName) + val success = delete(alias, keyStoreFile) + return if (success) { + alias + } else { + throw InternalServerErrorException() + } + } + + /** Deletes a trusted certificate. */ + @POST + @Path("delete_cert") + @ApiOperation(value = "Deletes a trusted certificate") + @Produces(MediaType.APPLICATION_JSON) + @AuthorizationRequired + fun deleteCert(alias: String): String { + val keyStoreFile = getKeystoreFile(settings.connectorConfig.keystoreName) + val success = delete(alias, keyStoreFile) + return if (success) { + alias + } else { + throw InternalServerErrorException() + } + } + + @POST + @Path("/install_trusted_cert") + @ApiOperation(value = "Installs a new trusted public key certificate.") + @ApiImplicitParams(ApiImplicitParam(dataType = "java.io.File", name = "attachment", paramType = "formData")) + @Produces( + MediaType.TEXT_HTML + ) + @Consumes(MediaType.MULTIPART_FORM_DATA) + @AuthorizationRequired + @Throws( + IOException::class + ) + fun installTrustedCert( + @ApiParam(hidden = true, name = "attachment") @Multipart("upfile") attachment: Attachment + ): String { + val filename = attachment.contentDisposition.getParameter("filename") + val tempPath = File.createTempFile(filename, "cert") + FileOutputStream(tempPath).use { out -> + attachment.getObject(InputStream::class.java).use { `in` -> + var read: Int + val bytes = ByteArray(1024) + while (`in`.read(bytes).also { read = it } != -1) { + out.write(bytes, 0, read) + } + } + } + val trustStoreName = settings.connectorConfig.truststoreName + val success = storeCert(getKeystoreFile(trustStoreName), tempPath) + if (success) { + if (!tempPath.delete()) { + LOG.warn("Failed to delete temporary file $tempPath") + } + return "Trusted certificate has been uploaded to $trustStoreName" + } + return "Error: certificate has NOT been uploaded to $trustStoreName" + } + + /** Stores a certificate in a JKS truststore. */ + private fun storeCert(trustStoreFile: File, certFile: File): Boolean { + val cf: CertificateFactory + val alias = certFile.name.replace(".", "_") + return try { + cf = CertificateFactory.getInstance("X.509") + val certStream = fullStream(certFile.absolutePath) + val certs = cf.generateCertificate(certStream) + FileInputStream(trustStoreFile).use { fis -> + FileOutputStream(trustStoreFile).use { fos -> + val keystore = KeyStore.getInstance(KeyStore.getDefaultType()) + val password = KEYSTORE_PWD + keystore.load(fis, password.toCharArray()) + + // Add the certificate + keystore.setCertificateEntry(alias, certs) + keystore.store(fos, password.toCharArray()) + } + } + true + } catch (e: CertificateException) { + LOG.error(e.message, e) + false + } catch (e: KeyStoreException) { + LOG.error(e.message, e) + false + } catch (e: NoSuchAlgorithmException) { + LOG.error(e.message, e) + false + } catch (e: IOException) { + LOG.error(e.message, e) + false + } + } + + /** + * Retrieve a keystore file. + * + * + * This method will first try to load keystores from Karaf's ./etc dir, then checks if a path + * has been given by -Dkeystore.dir=.. and finally just lets the classloader load the file from + * classpath. + * + * + * If the file cannot be found, this method returns null. + */ + private fun getKeystoreFile(fileName: String): File { + // If we run in karaf platform, we expect the keystore to be in + // KARAF_BASE/etc + val etcDir = System.getProperty("karaf.etc") + if (etcDir != null) { + val f = File(etcDir + File.separator + fileName) + if (f.exists()) { + return f + } + } + + // Otherwise, we allow setting the directory to search for by + // -Dkeystore.dir=... + val keystoreDir = System.getProperty("keystore.dir") + if (keystoreDir != null) { + val f = File(keystoreDir + File.separator + fileName) + if (f.exists()) { + return f + } + } + + // In case of unit tests, we expect resources to be "somehow" available in current working dir + val f = File(fileName) + if (f.exists()) { + return f + } + + // Last resort: let the classloader find the file + val clFile = Thread.currentThread().contextClassLoader.getResource(fileName) + try { + if (clFile != null) { + return File(clFile.toURI()) + } + } catch (e: URISyntaxException) { + LOG.error(e.message, e) + } + throw NotFoundException( + "Keystore/truststore file could not be found. Cannot continue. Given filename: " + + fileName + ) + } + + /** Returns all entries (private keys and certificates) from a Java keystore. */ + private fun getKeystoreEntries(keystoreFile: File): List { + val certs: MutableList = ArrayList() + try { + FileInputStream(keystoreFile).use { fis -> + val keystore = KeyStore.getInstance(KeyStore.getDefaultType()) + keystore.load(fis, KEYSTORE_PWD.toCharArray()) + val enumeration = keystore.aliases() + while (enumeration.hasMoreElements()) { + val alias = enumeration.nextElement() + val certificate = keystore.getCertificate(alias) + val cert = Cert() + cert.alias = alias + cert.file = keystoreFile.name.replaceFirst("[.][^.]+$".toRegex(), "") + cert.certificate = certificate.toString() + if (certificate !is X509Certificate) { + continue + } + cert.subjectAltNames = certificate.subjectAlternativeNames + // Get distinguished name + val dn = certificate.subjectX500Principal.name + for (entry in dn.split(",".toRegex()).toTypedArray()) { + val kv = entry.split("=".toRegex()).toTypedArray() + if (kv.size < 2) { + continue + } + when (kv[0]) { + "CN" -> cert.subjectCN = kv[1] + "OU" -> cert.subjectOU = kv[1] + "O" -> cert.subjectO = kv[1] + "L" -> cert.subjectL = kv[1] + "S" -> cert.subjectS = kv[1] + "C" -> cert.subjectC = kv[1] + else -> { + } + } + } + certs.add(cert) + } + } + } catch (e: CertificateException) { + LOG.error(e.message, e) + } catch (e: KeyStoreException) { + LOG.error(e.message, e) + } catch (e: NoSuchAlgorithmException) { + LOG.error(e.message, e) + } catch (e: IOException) { + LOG.error(e.message, e) + } + return certs + } + + /** + * We call the keystore binary programmatically. This is portable, in + * contrast to creating key pairs and self-signed certificates + * programmatically, which depends on internal classes of the JVM, such + * as sun.security.* or oracle.*. + */ + @Suppress("SameParameterValue") + @Throws(InterruptedException::class, IOException::class) + private fun doGenKeyPair( + alias: String, + spec: Identity, + keyAlgName: String, + keySize: Int, + sigAlgName: String, + keyStoreFile: File + ) { + val keytoolCmd = arrayOf( + "/bin/sh", + "-c", + "keytool", + "-genkey", + "-alias", + alias, + "-keyalg", + keyAlgName, + "-keysize", + keySize.toString(), + "-sigalg", + sigAlgName, + "-keystore", + keyStoreFile.absolutePath, + "-dname", + "CN=" + spec.cn + ", OU=" + spec.ou + ", O=" + spec.o + ", L=" + spec.l + ", S=" + spec.s + + ", C=" + spec.c, + "-storepass", + KEYSTORE_PWD, + "-keypass", + KEYSTORE_PWD + ) + val bos = ByteArrayOutputStream() + ProcessExecutor().execute(keytoolCmd, bos, bos) + LOG.debug("Keytool: {}", bos.toString(StandardCharsets.UTF_8)) + } + + private fun delete(alias: String, file: File): Boolean { + try { + FileInputStream(file).use { fis -> + val keystore = KeyStore.getInstance(KeyStore.getDefaultType()) + keystore.load(fis, KEYSTORE_PWD.toCharArray()) + if (keystore.containsAlias(alias)) { + keystore.deleteEntry(alias) + FileOutputStream(file).use { fos -> keystore.store(fos, KEYSTORE_PWD.toCharArray()) } + } else { + LOG.warn("Alias not available. Cannot delete it: $alias") + } + } + } catch (e: CertificateException) { + LOG.error(e.message, e) + return false + } catch (e: NoSuchAlgorithmException) { + LOG.error(e.message, e) + return false + } catch (e: KeyStoreException) { + LOG.error(e.message, e) + return false + } catch (e: IOException) { + LOG.error(e.message, e) + return false + } + return true + } + + companion object { + private val LOG = LoggerFactory.getLogger(CertApi::class.java) + private const val KEYSTORE_PWD = "password" + @Throws(IOException::class) + private fun fullStream(fname: String): InputStream { + val fis = FileInputStream(fname) + val dis = DataInputStream(fis) + val bytes = ByteArray(dis.available()) + dis.readFully(bytes) + val bais = ByteArrayInputStream(bytes) + dis.close() + return bais + } + } +} diff --git a/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/ConfigApi.kt b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/ConfigApi.kt new file mode 100644 index 000000000..73bfce049 --- /dev/null +++ b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/ConfigApi.kt @@ -0,0 +1,271 @@ +/*- + * ========================LICENSE_START================================= + * ids-webconsole + * %% + * Copyright (C) 2019 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.webconsole.api + +import de.fhg.aisec.ids.api.Constants +import de.fhg.aisec.ids.api.conm.ConnectionManager +import de.fhg.aisec.ids.api.endpointconfig.EndpointConfigManager +import de.fhg.aisec.ids.api.router.RouteManager +import de.fhg.aisec.ids.api.settings.ConnectionSettings +import de.fhg.aisec.ids.api.settings.ConnectorConfig +import de.fhg.aisec.ids.api.settings.Settings +import io.swagger.annotations.Api +import io.swagger.annotations.ApiOperation +import io.swagger.annotations.ApiResponse +import io.swagger.annotations.ApiResponses +import io.swagger.annotations.Authorization +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.stereotype.Component +import java.util.TreeMap +import java.util.function.Consumer +import java.util.regex.Pattern +import java.util.stream.Collectors +import javax.ws.rs.BadRequestException +import javax.ws.rs.Consumes +import javax.ws.rs.GET +import javax.ws.rs.POST +import javax.ws.rs.Path +import javax.ws.rs.PathParam +import javax.ws.rs.Produces +import javax.ws.rs.core.MediaType +import javax.ws.rs.core.Response + +/** + * REST API interface for configurations in the connector. + * + * + * The API will be available at http://localhost:8181/cxf/api/v1/config/. + * + * @author Julian Schuette (julian.schuette@aisec.fraunhofer.de) + * @author Gerd Brost (gerd.brost@aisec.fraunhofer.de) + * @author Michael Lux (michael.lux@aisec.fraunhofer.de) + */ +@Component +@Path("/config") +@Api(value = "Connector Configuration", authorizations = [Authorization(value = "oauth2")]) +class ConfigApi { + + @Autowired + private lateinit var settings: Settings + @Autowired + private lateinit var routeManager: RouteManager + @Autowired(required = false) + private var connectionManager: ConnectionManager? = null + @Autowired(required = false) + private var endpointConfigManager: EndpointConfigManager? = null + + @GET + @ApiOperation(value = "Retrieves the current configuration", response = ConnectorConfig::class) + @Path("/connectorConfig") + @Produces( + MediaType.APPLICATION_JSON + ) + @AuthorizationRequired + fun get(): ConnectorConfig { + return settings.connectorConfig + } + + @POST // @OPTIONS + @Path("/connectorConfig") + @ApiOperation(value = "Sets the overall configuration of the connector") + @ApiResponses( + ApiResponse( + code = 500, + message = "_No valid preferences received_: If incorrect configuration parameter is provided" + ) + ) + @Consumes( + MediaType.APPLICATION_JSON + ) + @AuthorizationRequired + fun set(config: ConnectorConfig?): String { + if (config == null) { + throw BadRequestException("No valid preferences received!") + } + settings.connectorConfig = config + return "OK" + } + + /** + * Save connection configuration of a particular connection. + * + * @param connection The name of the connection + * @param conSettings The connection configuration of the connection + */ + @POST + @Path("/connectionConfigs/{con}") + @ApiOperation(value = "Save connection configuration of a particular connection") + @ApiResponses( + ApiResponse( + code = 500, + message = "_No valid connection settings received!_: If incorrect connection settings parameter is provided" + ) + ) + @Consumes( + MediaType.APPLICATION_JSON + ) + @AuthorizationRequired + fun setConnectionConfigurations( + @PathParam("con") connection: String, + conSettings: ConnectionSettings? + ): Response { + if (conSettings == null) { + Response.serverError().entity("No valid connection settings received!").build() + } + + // connection has format " - host:port" + // store only "host:port" in database to make connection available in other parts of the application + // where rout_id is not available + val m = CONNECTION_CONFIG_PATTERN.matcher(connection) + if (!m.matches()) { + // GENERAL_CONFIG has changed + settings.setConnectionSettings(connection, conSettings) + } else { + // specific endpoint config has changed + settings.setConnectionSettings(m.group(1), conSettings) + + // notify EndpointConfigurationListeners that some endpointConfig has changed + endpointConfigManager?.notify(m.group(1)) + } + return Response.ok().build() + } + + /** + * Sends configuration of a connection + * + * @param connection Connection identifier + * @return The connection configuration of the requested connection + */ + @GET + @Path("/connectionConfigs/{con}") + @ApiOperation(value = "Sends configuration of a connection", response = ConnectionSettings::class) + @Produces( + MediaType.APPLICATION_JSON + ) + @AuthorizationRequired + fun getConnectionConfigurations(@PathParam("con") connection: String?): ConnectionSettings { + return settings.getConnectionSettings(connection) + } // add endpoint configurations// For every currently available endpoint, go through all preferences and check + // if the id is already there. If not, create empty config. + + // create missing endpoint configurations + + // add route id before host identifier for web console view +// Set of all connection configurations, properly ordered + // Load all existing entries + // Assert global configuration entry + + // add all available endpoints + /** + * Sends configurations of all connections + * + * @return Map of connection names/configurations + */ + @get:AuthorizationRequired + @get:Produces(MediaType.APPLICATION_JSON) + @get:ApiResponses( + ApiResponse( + code = 200, + message = "Map of connections and configurations", + response = ConnectionSettings::class, + responseContainer = "Map" + ) + ) + @get:ApiOperation(value = "Retrieves configurations of all connections") + @get:Path("/connectionConfigs") + @get:GET + val allConnectionConfigurations: Map + get() { + val connectionManager = connectionManager ?: return emptyMap() + + // Set of all connection configurations, properly ordered + val allSettings: MutableMap = TreeMap( + Comparator { o1: String, o2: String -> + when (Constants.GENERAL_CONFIG) { + o1 -> { + return@Comparator -1 + } + o2 -> { + return@Comparator 1 + } + else -> { + return@Comparator o1.compareTo(o2) + } + } + } + ) + // Load all existing entries + allSettings.putAll(settings.allConnectionSettings) + // Assert global configuration entry + allSettings.putIfAbsent(Constants.GENERAL_CONFIG, ConnectionSettings()) + val routeInputs = routeManager + .routes + .map { it.id } + .associateWith { routeManager.getRouteInputUris(it) } + + // add all available endpoints + for (endpoint in connectionManager.listAvailableEndpoints()) { + // For every currently available endpoint, go through all preferences and check + // if the id is already there. If not, create empty config. + val hostIdentifier = endpoint.host + ":" + endpoint.port + + // create missing endpoint configurations + if (allSettings.keys.stream().noneMatch { anObject: String? -> hostIdentifier == anObject }) { + allSettings[hostIdentifier] = ConnectionSettings() + } + } + + // add route id before host identifier for web console view + val retAllSettings: MutableMap = HashMap() + for ((key, value) in allSettings) { + if (key == Constants.GENERAL_CONFIG) { + retAllSettings[key] = value + } else { + var endpointIdentifiers = routeInputs + .entries + .stream() + .filter { (_, value1) -> + value1.stream().anyMatch { u: String -> u.startsWith("idsserver://$key") } + } + .map { (key1) -> "$key1 - $key" } + .collect(Collectors.toList()) + if (endpointIdentifiers.isEmpty()) { + endpointIdentifiers = listOf(" - $key") + } + + // add endpoint configurations + endpointIdentifiers.forEach( + Consumer { endpointIdentifier: String -> + if (retAllSettings.keys.stream() + .noneMatch { anObject: String? -> endpointIdentifier == anObject } + ) { + retAllSettings[endpointIdentifier] = value + } + } + ) + } + } + return retAllSettings + } + + companion object { + private val CONNECTION_CONFIG_PATTERN = Pattern.compile(".* - ([^ ]+)$") + } +} diff --git a/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/ConnectionAPI.kt b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/ConnectionAPI.kt new file mode 100644 index 000000000..c9274fb1e --- /dev/null +++ b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/ConnectionAPI.kt @@ -0,0 +1,87 @@ +/*- + * ========================LICENSE_START================================= + * ids-webconsole + * %% + * Copyright (C) 2019 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.webconsole.api + +import de.fhg.aisec.ids.api.conm.ConnectionManager +import de.fhg.aisec.ids.api.conm.IDSCPIncomingConnection +import de.fhg.aisec.ids.api.conm.IDSCPOutgoingConnection +import de.fhg.aisec.ids.api.conm.IDSCPServerEndpoint +import io.swagger.annotations.Api +import io.swagger.annotations.ApiOperation +import io.swagger.annotations.Authorization +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.stereotype.Component +import javax.ws.rs.GET +import javax.ws.rs.Path +import javax.ws.rs.Produces +import javax.ws.rs.core.MediaType + +/** + * REST API interface for managing connections from and to the connector. + * + * + * The API will be available at st/. + * + * @author Gerd Brost (gerd.brost@aisec.fraunhofer.de) + */ +@Component +@Path("/connections") +@Api(value = "IDSCP Connections", authorizations = [Authorization(value = "oauth2")]) +class ConnectionAPI { + + @Autowired(required = false) + private var connectionManager: ConnectionManager? = null + + @get:AuthorizationRequired + @get:Produces(MediaType.APPLICATION_JSON) + @get:ApiOperation( + value = "Returns a list of all inbound connections", + response = IDSCPIncomingConnection::class, + responseContainer = "List" + ) + @get:Path("/incoming") + @get:GET + val incoming: List + get() = connectionManager?.listIncomingConnections() ?: emptyList() + + @get:AuthorizationRequired + @get:Produces(MediaType.APPLICATION_JSON) + @get:ApiOperation( + value = "Returns a list of all outbound connections", + response = IDSCPOutgoingConnection::class, + responseContainer = "List" + ) + @get:Path("/outgoing") + @get:GET + val outgoing: List + get() = connectionManager?.listOutgoingConnections() ?: emptyList() + + @get:AuthorizationRequired + @get:Produces(MediaType.APPLICATION_JSON) + @get:ApiOperation( + value = "Returns a list of all endpoints provided by this connector", + response = IDSCPServerEndpoint::class, + responseContainer = "List" + ) + @get:Path("/endpoints") + @get:GET + val availableEndpoints: List + get() = connectionManager?.listAvailableEndpoints() ?: emptyList() +} diff --git a/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/JWTRestAPIFilter.kt b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/JWTRestAPIFilter.kt new file mode 100644 index 000000000..dc2f18967 --- /dev/null +++ b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/JWTRestAPIFilter.kt @@ -0,0 +1,71 @@ +/*- + * ========================LICENSE_START================================= + * ids-webconsole + * %% + * Copyright (C) 2019 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.webconsole.api + +import com.auth0.jwt.JWT +import com.auth0.jwt.algorithms.Algorithm +import org.slf4j.LoggerFactory +import javax.ws.rs.container.ContainerRequestContext +import javax.ws.rs.container.ContainerRequestFilter +import javax.ws.rs.core.Response +import javax.ws.rs.ext.Provider + +/** + * This filter verifies JWT bearer tokens provided by HTTP "Authorization" header. + * + * + * + * + * @author Hendrik Meyer zum Felde hendrik.meyerzumfelde@aisec.fraunhofer.de + */ +@Provider +@AuthorizationRequired +class JWTRestAPIFilter : ContainerRequestFilter { + override fun filter(requestContext: ContainerRequestContext) { + try { + // Get JWT Bearer token from HTTP Authorization header + val authorizationHeader = requestContext.getHeaderString("Authorization") + if (authorizationHeader == null) { + requestContext.abortWith( + Response.status(Response.Status.UNAUTHORIZED) + .entity("Authorization token missing.") + .build() + ) + return + } + + // Verify token + val jwt = authorizationHeader.substring(7).trim { it <= ' ' } + val algorithm: Algorithm = Algorithm.HMAC256(UserApi.key!!.encoded) + val verifier = JWT.require(algorithm).withIssuer("ids-connector").build() // Reusable verifier instance + verifier.verify(jwt) + } catch (e: Exception) { + LOG.warn("Invalid JWT token in request for " + requestContext.uriInfo.path) + // On token validation error (or other), return HTTP 403. + requestContext.abortWith( + Response.status(Response.Status.UNAUTHORIZED).entity("Invalid token.").build() + ) + } + } + + companion object { + private val LOG = LoggerFactory.getLogger(JWTRestAPIFilter::class.java) + } +} diff --git a/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/MetricAPI.kt b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/MetricAPI.kt new file mode 100644 index 000000000..4a691f0d6 --- /dev/null +++ b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/MetricAPI.kt @@ -0,0 +1,96 @@ +/*- + * ========================LICENSE_START================================= + * ids-webconsole + * %% + * Copyright (C) 2019 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.webconsole.api + +import io.swagger.annotations.Api +import io.swagger.annotations.ApiOperation +import io.swagger.annotations.ApiResponse +import io.swagger.annotations.ApiResponses +import io.swagger.annotations.Authorization +import org.springframework.stereotype.Component +import java.lang.management.ManagementFactory +import java.text.DecimalFormat +import javax.ws.rs.GET +import javax.ws.rs.Path +import javax.ws.rs.Produces +import javax.ws.rs.core.MediaType + +/** + * REST API interface for platform metrics. + * + * + * The API will be available at http://localhost:8181/cxf/api/v1/metric/. + * + * @author Julian Schuette (julian.schuette@aisec.fraunhofer.de) + */ +@Component +@Path("/metric") +@Api(value = "Runtime Metrics", authorizations = [Authorization(value = "oauth2")]) +class MetricAPI { + /** + * Returns map of metrics. + * + * @return Map with system metrics + */ + @get:AuthorizationRequired + @get:Produces(MediaType.APPLICATION_JSON) + @get:ApiResponses( + ApiResponse( + code = 200, + message = "Map of metrics values", + response = String::class, + responseContainer = "Map" + ) + ) + @get:ApiOperation(value = "Returns metrics values") + @get:Path("get") + @get:GET + val metrics: Map + get() { + val result = HashMap() + val os = ManagementFactory.getOperatingSystemMXBean() + val mem = ManagementFactory.getMemoryMXBean() + val threads = ManagementFactory.getThreadMXBean() + val cl = ManagementFactory.getClassLoadingMXBean() + val loadAvg = os.systemLoadAverage + result["cpu.availableprocessors"] = Runtime.getRuntime().availableProcessors().toString() + result["cpu.loadavg"] = if (loadAvg >= 0) loadAvgFormat.format(loadAvg) else "N/A" + result["mem.free"] = Runtime.getRuntime().freeMemory().toString() + result["mem.max"] = Runtime.getRuntime().maxMemory().toString() + result["mem.total"] = Runtime.getRuntime().totalMemory().toString() + result["mem.heapusage"] = mem.heapMemoryUsage.toString() + result["mem.nonheapusage"] = mem.nonHeapMemoryUsage.toString() + result["mem.objfinalizationcount"] = mem.objectPendingFinalizationCount.toString() + result["thread.peakcount"] = threads.peakThreadCount.toString() + result["thread.count"] = threads.threadCount.toString() + result["thread.totalstartedcount"] = threads.totalStartedThreadCount.toString() + result["cl.currentcount"] = cl.loadedClassCount.toString() + result["cl.totalcount"] = cl.totalLoadedClassCount.toString() + result["cl.unloadedcount"] = cl.unloadedClassCount.toString() + result["os.arch"] = os.arch + result["os.version"] = os.version + result["os.name"] = os.name.toString() + return result + } + + companion object { + private val loadAvgFormat = DecimalFormat("###.##") + } +} diff --git a/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/PolicyApi.kt b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/PolicyApi.kt new file mode 100644 index 000000000..acb9633c1 --- /dev/null +++ b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/PolicyApi.kt @@ -0,0 +1,108 @@ +/*- + * ========================LICENSE_START================================= + * ids-webconsole + * %% + * Copyright (C) 2019 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.webconsole.api + +import de.fhg.aisec.ids.api.policy.PAP +import io.swagger.annotations.Api +import io.swagger.annotations.ApiOperation +import io.swagger.annotations.ApiResponse +import io.swagger.annotations.ApiResponses +import io.swagger.annotations.Authorization +import org.slf4j.LoggerFactory +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.stereotype.Component +import javax.ws.rs.Consumes +import javax.ws.rs.DefaultValue +import javax.ws.rs.FormParam +import javax.ws.rs.GET +import javax.ws.rs.POST +import javax.ws.rs.Path +import javax.ws.rs.Produces +import javax.ws.rs.core.MediaType + +/** + * REST API interface for managing usage control policies in the connector. + * + * + * The API will be available at http://localhost:8181/cxf/api/v1/policies/. + * + * @author Julian Schuette (julian.schuette@aisec.fraunhofer.de) + */ +@Component +@Path("/policies") +@Api(value = "Usage Control Policies", authorizations = [Authorization(value = "oauth2")]) +class PolicyApi { + + @Autowired(required = false) + private var policyAdministrationPoint: PAP? = null + + @GET + @Path("list") + @ApiOperation(value = "Lists active usage control rules", responseContainer = "List") + @ApiResponses( + ApiResponse( + code = 200, + message = "List of usage control rules", + response = String::class, + responseContainer = "List" + ) + ) + @Produces( + MediaType.APPLICATION_JSON + ) + @AuthorizationRequired + fun list() = policyAdministrationPoint?.listRules() ?: emptyList() + + /** + * Returns the Prolog theory of all policies. Could be removed in later version. + * + * @return Policy Prolog + */ + @get:AuthorizationRequired + @get:ApiOperation(value = "Returns the full usage control policy as a Prolog theory") + @get:Produces(MediaType.TEXT_PLAIN) + @get:Path("policyProlog") + @get:GET + val policyProlog: String + get() = policyAdministrationPoint?.policy ?: "No PAP available" + + @POST + @Path("install") + @ApiOperation(value = "Installs a new usage control policy as a Prolog theory file") + @Consumes( + MediaType.MULTIPART_FORM_DATA + ) + @AuthorizationRequired + fun install( + @FormParam(value = "policy_name") @DefaultValue(value = "default policy") policyName: String?, + @FormParam(value = "policy_description") @DefaultValue(value = "") policyDescription: String?, + @FormParam(value = "policy_file") policy: String? + ): String { + LOG.info("Received policy file. name: {}, desc: {}", policyName, policyDescription) + return policyAdministrationPoint?.let { pap -> + pap.loadPolicy(policy) + "OK" + } ?: "No PAP available" + } + + companion object { + private val LOG = LoggerFactory.getLogger(PolicyApi::class.java) + } +} diff --git a/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/RouteApi.kt b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/RouteApi.kt new file mode 100644 index 000000000..2a7eefee7 --- /dev/null +++ b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/RouteApi.kt @@ -0,0 +1,278 @@ +/*- + * ========================LICENSE_START================================= + * ids-webconsole + * %% + * Copyright (C) 2019 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.webconsole.api + +import de.fhg.aisec.ids.api.Result +import de.fhg.aisec.ids.api.policy.PAP +import de.fhg.aisec.ids.api.router.RouteComponent +import de.fhg.aisec.ids.api.router.RouteManager +import de.fhg.aisec.ids.api.router.RouteMetrics +import de.fhg.aisec.ids.api.router.RouteObject +import de.fhg.aisec.ids.webconsole.api.data.ValidationInfo +import io.swagger.annotations.Api +import io.swagger.annotations.ApiOperation +import io.swagger.annotations.ApiParam +import io.swagger.annotations.Authorization +import org.slf4j.LoggerFactory +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.stereotype.Component +import javax.ws.rs.Consumes +import javax.ws.rs.GET +import javax.ws.rs.InternalServerErrorException +import javax.ws.rs.NotFoundException +import javax.ws.rs.POST +import javax.ws.rs.PUT +import javax.ws.rs.Path +import javax.ws.rs.PathParam +import javax.ws.rs.Produces +import javax.ws.rs.core.MediaType + +/** + * REST API interface for "data pipes" in the connector. + * + * + * This implementation uses Camel Routes as data pipes, i.e. the API methods allow inspection of + * camel routes in different camel contexts. + * + * + * The API will be available at http://localhost:8181/cxf/api/v1/routes/. + * + * @author Julian Schuette (julian.schuette@aisec.fraunhofer.de) + */ +@Component +@Path("/routes") +@Api(value = "Message Routing", authorizations = [Authorization(value = "oauth2")]) +class RouteApi { + + @Autowired + private lateinit var rm: RouteManager + @Autowired(required = false) + private var policyAdministrationPoint: PAP? = null + + /** + * Returns map from camel context to list of camel routes. + * + * + * Example: + * + * + * {"camel-1":["Route(demo-route)[[From[timer://simpleTimer?period\u003d10000]] -\u003e + * [SetBody[simple{This is a demo body!}], Log[The message contains ${body}]]]"]} + * + * @return The resulting route objects + */ + @GET + @Path("list") + @ApiOperation( + value = "Returns map from camel context to list of camel routes.", + response = RouteObject::class, + responseContainer = "List" + ) + @Produces( + MediaType.APPLICATION_JSON + ) + @AuthorizationRequired + fun list(): List { + return rm.routes + } + + @GET + @Path("/get/{id}") + @ApiOperation(value = "Get a Camel route", response = RouteObject::class) + @Produces(MediaType.APPLICATION_JSON) + @AuthorizationRequired + operator fun get(@ApiParam(value = "Route ID") @PathParam("id") id: String): RouteObject { + return rm.getRoute(id) ?: throw NotFoundException("Route not found") + } + + @GET + @Path("/getAsString/{id}") + @ApiOperation(value = "Gets an XML representation of a Camel route.") + @Produces(MediaType.TEXT_PLAIN) + @AuthorizationRequired + fun getAsString(@ApiParam(value = "Route ID") @PathParam("id") id: String?): String { + return rm.getRouteAsString(id!!) ?: throw NotFoundException("Route not found") + } + + /** Stop a route based on an id. */ + @GET + @Path("/startroute/{id}") + @ApiOperation(value = "Starts a Camel route. The route will start to process messages.") + @Produces( + MediaType.APPLICATION_JSON + ) + @AuthorizationRequired + fun startRoute(@PathParam("id") id: String?): Result { + return try { + rm.startRoute(id!!) + Result() + } catch (e: Exception) { + LOG.warn(e.message, e) + Result(false, e.message!!) + } + } + + @POST + @Path("/save/{id}") + @ApiOperation(value = "Save changes to a route. ") + @Consumes(MediaType.TEXT_PLAIN) + @Produces( + MediaType.APPLICATION_JSON + ) + @AuthorizationRequired + fun saveRoute(@PathParam("id") id: String, routeDefinition: String): Result { + return try { + rm.saveRoute(id, routeDefinition) + Result() + } catch (e: Exception) { + LOG.warn(e.message, e) + Result(false, e.message!!) + } + } + + @PUT + @Path("/add") + @ApiOperation(value = "Adds a new route, provided as Camel XML.") + @Consumes(MediaType.TEXT_PLAIN) + @Produces( + MediaType.APPLICATION_JSON + ) + @AuthorizationRequired + fun addRoute(routeDefinition: String): Result { + return try { + rm.addRoute(routeDefinition) + Result() + } catch (e: Exception) { + LOG.warn(e.message, e) + Result(false, e.message!!) + } + } + + /** Stop a route based on its id. */ + @GET + @Path("/stoproute/{id}") + @ApiOperation(value = "Stops a Camel route. The route will remain installed but it will not process any messages.") + @Produces( + MediaType.APPLICATION_JSON + ) + @AuthorizationRequired + fun stopRoute(@PathParam("id") id: String?): Result { + return try { + rm.stopRoute(id!!) + Result() + } catch (e: Exception) { + LOG.warn(e.message, e) + Result(false, e.message!!) + } + } + + /** Get runtime metrics of a route */ + @GET + @ApiOperation(value = "Get runtime metrics of a route", response = RouteMetrics::class) + @Path("/metrics/{id}") + @AuthorizationRequired + fun getMetrics(@PathParam("id") routeId: String?): RouteMetrics? { + return rm.routeMetrics[routeId] + } + + /** Get aggregated runtime metrics of all routes */ + @get:AuthorizationRequired + @get:Path("/metrics") + @get:ApiOperation(value = "Get aggregated runtime metrics of all routes", response = RouteMetrics::class) + @get:GET + val metrics: RouteMetrics + get() = aggregateMetrics(rm.routeMetrics.values) + + /** + * Aggregates metrics of several rules + * + * @param currentMetrics List of RouteMetrics to process + * @return The aggregated RouteMetrics object + */ + private fun aggregateMetrics(currentMetrics: Collection): RouteMetrics { + val metrics = RouteMetrics() + metrics.completed = currentMetrics.stream().mapToLong { obj: RouteMetrics -> obj.completed }.sum() + metrics.failed = currentMetrics.stream().mapToLong { obj: RouteMetrics -> obj.failed }.sum() + metrics.failuresHandled = currentMetrics.stream().mapToLong { obj: RouteMetrics -> obj.failuresHandled }.sum() + metrics.inflight = currentMetrics.stream().mapToLong { obj: RouteMetrics -> obj.inflight }.sum() + metrics.maxProcessingTime = + currentMetrics.stream().mapToLong { obj: RouteMetrics -> obj.maxProcessingTime }.max().orElse(0) + // This is technically nonsense, as average values of average values are not really + // the average values of the single elements, but it's the best aggregation we can get. + metrics.meanProcessingTime = currentMetrics + .stream() + .mapToLong { obj: RouteMetrics -> obj.meanProcessingTime } + .filter { i: Long -> i >= 0 } + .average() + .orElse(.0).toLong() + metrics.minProcessingTime = + currentMetrics.stream().mapToLong { obj: RouteMetrics -> obj.minProcessingTime }.min().orElse(0) + metrics.completed = currentMetrics.stream().mapToLong { obj: RouteMetrics -> obj.completed }.sum() + return metrics + } + + /** + * Retrieve list of supported components (aka protocols which can be addressed by Camel) + * + * @return List of supported protocols + */ + @get:AuthorizationRequired + @get:Produces(MediaType.APPLICATION_JSON) + @get:Path("/components") + @get:GET + val components: List + get() = rm.listComponents() + + /** Retrieve list of currently installed endpoints (aka URIs to/from which routes exist) */ + @GET + @Path("/list_endpoints") + @AuthorizationRequired + fun listEndpoints(): Map { + return rm.listEndpoints() + } + + @GET + @Path("/validate/{routeId}") + @Produces(MediaType.APPLICATION_JSON) + @AuthorizationRequired + fun validate(@PathParam("routeId") routeId: String?): ValidationInfo { + val pap: PAP = policyAdministrationPoint + ?: throw InternalServerErrorException() + val rvp = pap.verifyRoute(routeId!!) ?: throw InternalServerErrorException() + val vi = ValidationInfo() + vi.valid = rvp.isValid + if (!rvp.isValid) { + vi.counterExamples = rvp.counterExamples + } + return vi + } + + @GET + @Path("/prolog/{routeId}") + @Produces(MediaType.TEXT_PLAIN) + @AuthorizationRequired + fun getRouteProlog(@PathParam("routeId") routeId: String): String { + return rm.getRouteAsProlog(routeId) + } + + companion object { + private val LOG = LoggerFactory.getLogger(RouteApi::class.java) + } +} diff --git a/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/SettingsApi.kt b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/SettingsApi.kt new file mode 100644 index 000000000..58a700bde --- /dev/null +++ b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/SettingsApi.kt @@ -0,0 +1,141 @@ +/*- + * ========================LICENSE_START================================= + * ids-webconsole + * %% + * Copyright (C) 2019 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.webconsole.api + +import de.fhg.aisec.ids.api.infomodel.ConnectorProfile +import de.fhg.aisec.ids.api.infomodel.InfoModel +import de.fraunhofer.iais.eis.util.TypedLiteral +import io.swagger.annotations.Api +import io.swagger.annotations.ApiOperation +import io.swagger.annotations.Authorization +import org.slf4j.LoggerFactory +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.stereotype.Component +import java.util.stream.Collectors +import javax.ws.rs.Consumes +import javax.ws.rs.DELETE +import javax.ws.rs.GET +import javax.ws.rs.InternalServerErrorException +import javax.ws.rs.POST +import javax.ws.rs.Path +import javax.ws.rs.Produces +import javax.ws.rs.core.MediaType + +/** + * REST API interface for Connector settings in the connector. + * + * + * The API will be available at http://localhost:8181/cxf/api/v1/settings/. + */ +// ConnectorProfile will be processed by custom Jackson deserializer +@Component +@Path("/settings") +@Api(value = "Self-Description and Connector Profiles", authorizations = [Authorization(value = "oauth2")]) +class SettingsApi { + + @Autowired + private lateinit var im: InfoModel + + @POST + @Path("/connectorProfile") + @ApiOperation(value = "Configure the connector's self-description (\"Connector Profile\").") + @Consumes( + MediaType.APPLICATION_JSON + ) + @AuthorizationRequired + fun postConnectorProfile(profile: ConnectorProfile?): String { + return if (im.setConnector(profile!!)) { + "ConnectorProfile successfully stored." + } else { + throw InternalServerErrorException("Error while storing ConnectorProfile") + } + } + + /** Returns Connector profile based on currently stored preferences or empty Connector profile */ + @get:AuthorizationRequired + @get:ApiOperation( + value = "Returns this connector's self-description (\"Connector Profile\")", + response = ConnectorProfile::class + ) + @get:Produces(MediaType.APPLICATION_JSON) + @get:Path("/connectorProfile") + @get:GET + val connectorProfile: ConnectorProfile + get() { + val c = im.connector + return if (c == null) { + ConnectorProfile() + } else { + ConnectorProfile( + c.securityProfile, + c.id, + c.maintainer, + c.description.stream().map { obj: Any? -> TypedLiteral::class.java.cast(obj) } + .collect(Collectors.toList()) + ) + } + } + + /** + * Returns connector profile based on currently stored preferences or statically provided JSON-LD + * model, or empty connector profile if none of those are available. + */ + @get:Produces("application/ld+json") + @get:Path("/selfInformation") + @get:GET + @set:AuthorizationRequired + @set:Consumes("application/ld+json") + @set:Path("/selfInformation") + @set:POST + var selfInformation: String? + // TODO Document ApiOperation + get() = try { + im.connectorAsJsonLd + } catch (e: NullPointerException) { + LOG.warn("Connector description build failed, building empty description.", e) + null + } + // TODO Document ApiOperation + set(selfInformation) { + try { + im.setConnectorByJsonLd(selfInformation) + } catch (e: NullPointerException) { + LOG.warn("Connector description build failed, building empty description.", e) + } + } + + /** Remove static connector profile based on JSON-LD data */ + // TODO Document ApiOperation + @DELETE + @Path("/selfInformation") + @Consumes("application/ld+json") + @AuthorizationRequired + fun removeSelfInformation() { + try { + im.setConnectorByJsonLd(null) + } catch (e: NullPointerException) { + LOG.warn("Connector description build failed, building empty description.", e) + } + } + + companion object { + private val LOG = LoggerFactory.getLogger(SettingsApi::class.java) + } +} diff --git a/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/UserApi.kt b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/UserApi.kt new file mode 100644 index 000000000..f9422cf9e --- /dev/null +++ b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/UserApi.kt @@ -0,0 +1,134 @@ +/*- + * ========================LICENSE_START================================= + * ids-webconsole + * %% + * Copyright (C) 2019 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.webconsole.api + +import com.auth0.jwt.JWT +import com.auth0.jwt.algorithms.Algorithm +import de.fhg.aisec.ids.webconsole.api.data.User +import io.swagger.annotations.Api +import org.slf4j.LoggerFactory +import org.springframework.stereotype.Component +import java.security.Key +import java.security.NoSuchAlgorithmException +import java.util.Calendar +import javax.crypto.KeyGenerator +import javax.security.auth.callback.Callback +import javax.security.auth.callback.NameCallback +import javax.security.auth.callback.PasswordCallback +import javax.security.auth.login.Configuration +import javax.security.auth.login.LoginContext +import javax.security.auth.login.LoginException +import javax.ws.rs.Consumes +import javax.ws.rs.POST +import javax.ws.rs.Path +import javax.ws.rs.Produces +import javax.ws.rs.core.MediaType +import javax.ws.rs.core.Response + +@Component +@Path("/user") +@Api(value = "User Authentication") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +class UserApi { + companion object { + private val LOG = LoggerFactory.getLogger(UserApi::class.java) + var key: Key? = null + + init { + try { + key = KeyGenerator.getInstance("HmacSHA256").generateKey() + } catch (e: NoSuchAlgorithmException) { + e.printStackTrace() + } + } + } + + /** + * Given a correct username/password, this method returns a JWT token that is valid for one day. + * + * @param user Username/password. + * @return A JSON object of the form `{ "token" : }` if successful, 401 UNAUTHORIZED if not. + */ + @POST + @Path("/login") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + fun authenticateUser(user: User): Response { + return try { + // Authenticate the user using the credentials provided + if (!authenticate(user.username, user.password)) { + return Response.status(Response.Status.UNAUTHORIZED).build() + } + + // Issue a token for the user + val token = issueToken(user.username) + + // Return the token on the response + val result: MutableMap = HashMap() + result["token"] = token + Response.ok().entity(result).build() + } catch (e: Throwable) { + e.printStackTrace() + Response.status(Response.Status.UNAUTHORIZED).build() + } + } + + private fun issueToken(username: String?): String { + val cal = Calendar.getInstance() + cal.timeInMillis = cal.timeInMillis + 86400000 + val tomorrow = cal.time + return JWT.create() + .withClaim("user", username) + .withExpiresAt(tomorrow) + .withIssuer("ids-connector") + .sign(Algorithm.HMAC256(key!!.encoded)) + } + + /** + * Login with JaaS. We use the default realm "karaf". When using default PropertiesLoginModule, users are + * configured in karaf-assembly/src/main/resources/etc/users.properties. Other modules such as OAuth, LDAP, JDBC + * can be configured as needed without changing this code here. + */ + @Throws(LoginException::class) + private fun authenticate(user: String?, password: String?): Boolean { + if (Configuration.getConfiguration().getAppConfigurationEntry("karaf") == null) { + LOG.warn( + "No LoginModules configured for karaf. This is okay if running as unit test. " + + "If this message appears in Karaf container, make sure that JAAS is available." + ) + return "ids" == user && "ids" == password + } + val ctx = LoginContext( + "karaf" + ) { callbacks: Array -> + for (cb in callbacks) { + if (cb is PasswordCallback) { + cb.password = password?.toCharArray() + } + if (cb is NameCallback) { + cb.name = user + } + } + } + ctx.login() + return true + } +} diff --git a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/data/Account.java b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/data/Account.kt similarity index 86% rename from ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/data/Account.java rename to ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/data/Account.kt index b1747d606..1308baa3d 100644 --- a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/data/Account.java +++ b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/data/Account.kt @@ -17,9 +17,9 @@ * limitations under the License. * =========================LICENSE_END================================== */ -package de.fhg.aisec.ids.webconsole.api.data; +package de.fhg.aisec.ids.webconsole.api.data -public class Account { - public String username; - public String password; +class Account { + var username: String? = null + var password: String? = null } diff --git a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/data/User.java b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/data/AppSearchRequest.kt similarity index 86% rename from ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/data/User.java rename to ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/data/AppSearchRequest.kt index c7cc3e86b..f2606deb5 100644 --- a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/data/User.java +++ b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/data/AppSearchRequest.kt @@ -17,9 +17,8 @@ * limitations under the License. * =========================LICENSE_END================================== */ -package de.fhg.aisec.ids.webconsole.api.data; +package de.fhg.aisec.ids.webconsole.api.data -public class User { - public String username; - public String password; +class AppSearchRequest { + val searchTerm = "" } diff --git a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/data/Cert.java b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/data/Cert.kt similarity index 64% rename from ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/data/Cert.java rename to ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/data/Cert.kt index 23150dec5..a781445f4 100644 --- a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/data/Cert.java +++ b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/data/Cert.kt @@ -17,20 +17,18 @@ * limitations under the License. * =========================LICENSE_END================================== */ -package de.fhg.aisec.ids.webconsole.api.data; +package de.fhg.aisec.ids.webconsole.api.data -import java.util.Collection; -import java.util.List; - -public class Cert { - public String subjectC; - public String subjectS; - public String subjectL; - public String subjectO; - public String subjectOU; - public Collection> subjectAltNames; - public String subjectCN; - public String alias; - public String file; - public String certificate; +class Cert { + var subjectC: String? = null + var subjectS: String? = null + var subjectL: String? = null + var subjectO: String? = null + var subjectOU: String? = null + var subjectAltNames: Collection>? = null + var subjectCN: String? = null + @kotlin.jvm.JvmField + var alias: String? = null + var file: String? = null + var certificate: String? = null } diff --git a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/data/AppSearchRequest.java b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/data/Identity.kt similarity index 71% rename from ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/data/AppSearchRequest.java rename to ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/data/Identity.kt index 8398295f6..8c0e05069 100644 --- a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/data/AppSearchRequest.java +++ b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/data/Identity.kt @@ -17,16 +17,17 @@ * limitations under the License. * =========================LICENSE_END================================== */ -package de.fhg.aisec.ids.webconsole.api.data; +package de.fhg.aisec.ids.webconsole.api.data -public class AppSearchRequest { - private final String searchTerm; - - public AppSearchRequest() { - searchTerm = ""; - } - - public String getSearchTerm() { - return searchTerm; - } +class Identity { + @kotlin.jvm.JvmField + var cn: String? = null + var ou: String? = null + var o: String? = null + @kotlin.jvm.JvmField + var l: String? = null + @kotlin.jvm.JvmField + var s: String? = null + @kotlin.jvm.JvmField + var c: String? = null } diff --git a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/data/Identity.java b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/data/User.kt similarity index 80% rename from ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/data/Identity.java rename to ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/data/User.kt index d2f094019..fe829d118 100644 --- a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/data/Identity.java +++ b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/data/User.kt @@ -17,13 +17,11 @@ * limitations under the License. * =========================LICENSE_END================================== */ -package de.fhg.aisec.ids.webconsole.api.data; +package de.fhg.aisec.ids.webconsole.api.data -public class Identity { - public String cn; - public String ou; - public String o; - public String l; - public String s; - public String c; +class User { + @kotlin.jvm.JvmField + var username: String? = null + @kotlin.jvm.JvmField + var password: String? = null } diff --git a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/data/ValidationInfo.java b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/data/ValidationInfo.kt similarity index 77% rename from ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/data/ValidationInfo.java rename to ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/data/ValidationInfo.kt index 57377707e..97d8560df 100644 --- a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/data/ValidationInfo.java +++ b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/data/ValidationInfo.kt @@ -17,13 +17,11 @@ * limitations under the License. * =========================LICENSE_END================================== */ -package de.fhg.aisec.ids.webconsole.api.data; +package de.fhg.aisec.ids.webconsole.api.data -import de.fhg.aisec.ids.api.router.CounterExample; +import de.fhg.aisec.ids.api.router.CounterExample -import java.util.List; - -public class ValidationInfo { - public boolean valid; - public List counterExamples = null; +class ValidationInfo { + var valid = false + var counterExamples: List? = null } diff --git a/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/helper/ProcessExecutor.kt b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/helper/ProcessExecutor.kt new file mode 100644 index 000000000..5db57ab7c --- /dev/null +++ b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/helper/ProcessExecutor.kt @@ -0,0 +1,41 @@ +/*- + * ========================LICENSE_START================================= + * ids-webconsole + * %% + * Copyright (C) 2019 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.webconsole.api.helper + +import org.slf4j.LoggerFactory +import java.io.IOException +import java.io.OutputStream + +class ProcessExecutor { + @Throws(InterruptedException::class, IOException::class) + fun execute(cmd: Array?, stdout: OutputStream?, stderr: OutputStream?): Int { + val rt = Runtime.getRuntime() + val proc = rt.exec(cmd) + val errorGobbler = StreamGobbler(proc.errorStream, stderr) + val outputGobbler = StreamGobbler(proc.inputStream, stdout) + errorGobbler.start() + outputGobbler.start() + return proc.waitFor() + } + + companion object { + private val LOG = LoggerFactory.getLogger(ProcessExecutor::class.java) + } +} diff --git a/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/helper/StreamGobbler.kt b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/helper/StreamGobbler.kt new file mode 100644 index 000000000..df1b5ecdb --- /dev/null +++ b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/helper/StreamGobbler.kt @@ -0,0 +1,57 @@ +/*- + * ========================LICENSE_START================================= + * ids-webconsole + * %% + * Copyright (C) 2019 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.webconsole.api.helper + +import org.slf4j.LoggerFactory +import java.io.BufferedReader +import java.io.BufferedWriter +import java.io.IOException +import java.io.InputStream +import java.io.InputStreamReader +import java.io.OutputStream +import java.io.OutputStreamWriter +import java.nio.charset.StandardCharsets + +internal class StreamGobbler(var `is`: InputStream, var out: OutputStream?) : Thread() { + override fun run() { + try { + InputStreamReader(`is`, StandardCharsets.UTF_8).use { isr -> + BufferedReader(isr).use { br -> + out?.let { + BufferedWriter(OutputStreamWriter(it, StandardCharsets.UTF_8)).use { bw -> + br.lines().forEach { line -> + bw.write(line) + bw.newLine() + } + } + } ?: { + br.lines().forEach { /* no-op */ } + } + } + } + } catch (ioe: IOException) { + LOG.error(ioe.message, ioe) + } + } + + companion object { + private val LOG = LoggerFactory.getLogger(StreamGobbler::class.java) + } +} diff --git a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/packageinfo b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/packageinfo similarity index 100% rename from ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/packageinfo rename to ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/packageinfo From 08fb7e83e316bc119a14ba957408af71b484d498 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Tue, 11 May 2021 16:22:51 +0200 Subject: [PATCH 36/54] Removed OSGi leftovers, some cleanup --- build.gradle.kts | 24 +-------- camel-multipart-processor/build.gradle.kts | 19 +++---- .../ids/camel/multipart/MultiPartComponent.kt | 13 ++--- example-idscp2-client-server/build.gradle.kts | 5 +- .../docker-compose.yaml | 4 +- ids-acme/build.gradle.kts | 7 ++- .../fhg/aisec/ids/acme/AcmeClientService.kt | 26 +++++----- ids-api/build.gradle.kts | 14 ++---- ids-connector/build.gradle.kts | 3 +- ids-container-manager/build.gradle.kts | 18 ++----- .../aisec/ids/cm/ContainerManagerService.java | 22 ++------- ids-dataflow-control/build.gradle.kts | 15 ++---- .../dataflowcontrol/PolicyDecisionPoint.kt | 18 +------ ids-dynamic-tls/build.gradle.kts | 7 +-- ids-endpoint-config/build.gradle.kts | 4 +- ids-infomodel-manager/build.gradle.kts | 17 ++----- .../InfoModelService.kt | 5 -- ids-route-manager/build.gradle.kts | 17 ++----- .../de/fhg/aisec/ids/rm/CamelInterceptor.kt | 22 +++------ ids-settings/build.gradle.kts | 8 +-- ids-webconsole/build.gradle.kts | 30 ++---------- .../fhg/aisec/ids/webconsole/api/CertApi.kt | 49 ++++--------------- 22 files changed, 90 insertions(+), 257 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index b8375cd49..7cc5c49dc 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -41,7 +41,7 @@ val libraryVersions: Map = extra.set("libraryVersions", libraryVersions) licenseReport { - configurations = arrayOf("compile", "providedByFeature", "providedByBundle") + configurations = arrayOf("compile") } allprojects { @@ -74,29 +74,9 @@ subprojects { } } - // Configuration for dependencies that will be provided through features in the OSGi environment - val providedByFeature by configurations.creating - - // Configurations for dependencies that will be provided through bundles in the OSGi environment - // Separate configurations are required when two bundles depend on different versions of the same bundle! - val providedByBundle by configurations.creating - val unixSocketBundle by configurations.creating - val infomodelBundle by configurations.creating - - // OSGi core dependencies which will just be there during runtime - val osgiCore by configurations.creating - - // For artifacts that should be included as "compile" dependencies into published maven artifacts - val publishCompile by configurations.creating - - configurations["compile"].extendsFrom( - providedByFeature, providedByBundle, unixSocketBundle, infomodelBundle, - osgiCore, publishCompile - ) - dependencies { // Logging API - providedByBundle("org.slf4j", "slf4j-api", libraryVersions["slf4j"]) + implementation("org.slf4j", "slf4j-api", libraryVersions["slf4j"]) val compileOnly by configurations diff --git a/camel-multipart-processor/build.gradle.kts b/camel-multipart-processor/build.gradle.kts index 59cf9dc80..bc4a5bb1f 100644 --- a/camel-multipart-processor/build.gradle.kts +++ b/camel-multipart-processor/build.gradle.kts @@ -2,18 +2,13 @@ dependencies { @Suppress("UNCHECKED_CAST") val libraryVersions = rootProject.extra.get("libraryVersions") as Map - providedByBundle(project(":ids-api")) { isTransitive = false } - - providedByFeature("org.apache.camel", "camel-core", libraryVersions["camel"]) - providedByFeature("org.apache.camel", "camel-http4", libraryVersions["camelHttp4"]) - - providedByBundle("org.apache.httpcomponents", "httpcore-osgi", libraryVersions["httpcore"]) - providedByBundle("org.apache.httpcomponents", "httpclient-osgi", libraryVersions["httpclient"]) - - providedByBundle("commons-fileupload", "commons-fileupload", libraryVersions["commonsFileUpload"]) - - osgiCore("org.apache.felix", "org.apache.felix.framework", libraryVersions["felixFramework"]) - osgiCore("org.osgi", "osgi.cmpn", libraryVersions["osgiCompendium"]) + implementation(project(":ids-api")) { isTransitive = false } + implementation("org.springframework.boot:spring-boot-starter") + implementation("org.apache.camel", "camel-core", libraryVersions["camel"]) + implementation("org.apache.camel", "camel-http4", libraryVersions["camelHttp4"]) + implementation("org.apache.httpcomponents", "httpcore-osgi", libraryVersions["httpcore"]) + implementation("org.apache.httpcomponents", "httpclient-osgi", libraryVersions["httpclient"]) + implementation("commons-fileupload", "commons-fileupload", libraryVersions["commonsFileUpload"]) testImplementation("junit", "junit", libraryVersions["junit4"]) testImplementation("org.mockito", "mockito-core", libraryVersions["mockito"]) diff --git a/camel-multipart-processor/src/main/kotlin/de/fhg/aisec/ids/camel/multipart/MultiPartComponent.kt b/camel-multipart-processor/src/main/kotlin/de/fhg/aisec/ids/camel/multipart/MultiPartComponent.kt index 598833d25..8daad6efa 100644 --- a/camel-multipart-processor/src/main/kotlin/de/fhg/aisec/ids/camel/multipart/MultiPartComponent.kt +++ b/camel-multipart-processor/src/main/kotlin/de/fhg/aisec/ids/camel/multipart/MultiPartComponent.kt @@ -20,10 +20,8 @@ package de.fhg.aisec.ids.camel.multipart import de.fhg.aisec.ids.api.infomodel.InfoModel -import org.osgi.service.component.annotations.Activate -import org.osgi.service.component.annotations.Component -import org.osgi.service.component.annotations.Reference -import org.osgi.service.component.annotations.ReferenceCardinality +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.stereotype.Component /** * The only purpose of this OSGi component is to connect to the InfoModelManager. @@ -33,13 +31,12 @@ import org.osgi.service.component.annotations.ReferenceCardinality * * @author Julian Schütte (julian.schuette@aisec.fraunhofer.de) */ -@Component(name = "ids-multipart-component") +@Component("idsMultipartComponent") class MultiPartComponent { - @Reference(cardinality = ReferenceCardinality.MANDATORY) + @Autowired lateinit var infoModelManager: InfoModel - @Activate - fun activate() { + init { instance = this } diff --git a/example-idscp2-client-server/build.gradle.kts b/example-idscp2-client-server/build.gradle.kts index d33b2b7d7..475c794a1 100644 --- a/example-idscp2-client-server/build.gradle.kts +++ b/example-idscp2-client-server/build.gradle.kts @@ -4,12 +4,11 @@ plugins { } springBoot { - mainClassName = "de.fhg.aisec.ids.ExampleConnector" + mainClass.set("de.fhg.aisec.ids.ExampleConnector") } dependencies { - // can and should be replaced by a reference to a maven published artifact later + // Can and should be replaced by a reference to a maven published artifact later implementation(project(":ids-connector")) - implementation("org.springframework.boot:spring-boot-starter") } diff --git a/examples/example-getting-started/docker-compose.yaml b/examples/example-getting-started/docker-compose.yaml index ca8e16f62..74c99da8c 100644 --- a/examples/example-getting-started/docker-compose.yaml +++ b/examples/example-getting-started/docker-compose.yaml @@ -15,9 +15,7 @@ services: - ../cert-stores/truststore.p12:/root/etc/truststore.p12 - ./example-idscp2-localloop.xml:/root/deploy/example-idscp2-localloop.xml ports: - - "5005:5005" - - "9292:9292" - - "8181:8181" + - "8080:8080" - "8443:8443" networks: example-internal: diff --git a/ids-acme/build.gradle.kts b/ids-acme/build.gradle.kts index 38b0e5064..4a139b3f7 100644 --- a/ids-acme/build.gradle.kts +++ b/ids-acme/build.gradle.kts @@ -2,12 +2,11 @@ dependencies { @Suppress("UNCHECKED_CAST") val libraryVersions = rootProject.extra.get("libraryVersions") as Map - providedByBundle(project(":ids-api")) { isTransitive = false } + implementation(project(":ids-api")) { isTransitive = false } - providedByFeature("org.eclipse.jetty", "jetty-util", libraryVersions["jetty"]) - providedByFeature("org.apache.karaf.scheduler", "org.apache.karaf.scheduler.core", libraryVersions["karaf"]) + implementation("org.springframework.boot:spring-boot-starter") - osgiCore("org.osgi", "osgi.cmpn", libraryVersions["osgiCompendium"]) + implementation("org.eclipse.jetty", "jetty-util", libraryVersions["jetty"]) implementation("org.shredzone.acme4j", "acme4j-client", libraryVersions["acme"]) implementation("org.shredzone.acme4j", "acme4j-utils", libraryVersions["acme"]) diff --git a/ids-acme/src/main/kotlin/de/fhg/aisec/ids/acme/AcmeClientService.kt b/ids-acme/src/main/kotlin/de/fhg/aisec/ids/acme/AcmeClientService.kt index bcd173b27..0b59dac73 100644 --- a/ids-acme/src/main/kotlin/de/fhg/aisec/ids/acme/AcmeClientService.kt +++ b/ids-acme/src/main/kotlin/de/fhg/aisec/ids/acme/AcmeClientService.kt @@ -24,10 +24,6 @@ import de.fhg.aisec.ids.api.acme.AcmeTermsOfService import de.fhg.aisec.ids.api.acme.SslContextFactoryReloadable import de.fhg.aisec.ids.api.settings.Settings import org.apache.karaf.scheduler.Scheduler -import org.osgi.service.component.annotations.Activate -import org.osgi.service.component.annotations.Component -import org.osgi.service.component.annotations.Reference -import org.osgi.service.component.annotations.ReferenceCardinality import org.shredzone.acme4j.Account import org.shredzone.acme4j.AccountBuilder import org.shredzone.acme4j.Order @@ -57,17 +53,18 @@ import java.util.Collections import java.util.Date @Component( - immediate = true, - name = "ids-acme-client", + "idsAcmeClient" + // TODO: Scheduling in Spring // Every day at 3:00 (3 am) - property = [Scheduler.PROPERTY_SCHEDULER_EXPRESSION + "=0 0 3 * * ?"] + // property = [Scheduler.PROPERTY_SCHEDULER_EXPRESSION + "=0 0 3 * * ?"] ) class AcmeClientService : AcmeClient, Runnable { /* * The following block subscribes this component to the Settings Service */ - @Reference(cardinality = ReferenceCardinality.OPTIONAL) private var settings: Settings? = null + @Autowired(required = false) + private var settings: Settings? = null private val sslReloadables = Collections.synchronizedSet(HashSet()) /* @@ -76,12 +73,13 @@ class AcmeClientService : AcmeClient, Runnable { * A SslContextFactoryReloader is expected to refresh all TLS connections with new * certificates from the key store. */ - @Reference( - name = "dynamic-tls-reload-service", - service = SslContextFactoryReloadable::class, - cardinality = ReferenceCardinality.MULTIPLE, - unbind = "unbindSslContextFactoryReloadable" - ) + // TODO: Adapt for Spring + // @Reference( + // name = "dynamic-tls-reload-service", + // service = SslContextFactoryReloadable::class, + // cardinality = ReferenceCardinality.MULTIPLE, + // unbind = "unbindSslContextFactoryReloadable" + // ) private fun bindSslContextFactoryReloadable(reloadable: SslContextFactoryReloadable) { LOG.info("Bound SslContextFactoryReloadable in AcmeClientService") this.sslReloadables.add(reloadable) diff --git a/ids-api/build.gradle.kts b/ids-api/build.gradle.kts index dd2c645b8..99fbb1b16 100644 --- a/ids-api/build.gradle.kts +++ b/ids-api/build.gradle.kts @@ -31,16 +31,12 @@ configure { } dependencies { - providedByBundle("com.google.protobuf", "protobuf-java", libraryVersions["protobuf"]) + implementation("com.google.protobuf", "protobuf-java", libraryVersions["protobuf"]) + implementation("com.fasterxml.jackson.core", "jackson-annotations", libraryVersions["jackson"]) + implementation("de.fraunhofer.iais.eis.ids.infomodel", "java", libraryVersions["infomodel"]) + implementation("org.apache.camel", "camel-core", libraryVersions["camel"]) - providedByBundle("com.fasterxml.jackson.core", "jackson-annotations", libraryVersions["jackson"]) - - publishCompile("org.checkerframework", "checker-qual", libraryVersions["checkerQual"]) - - // Actual implementation must be provided by ids-infomodel-manager - publishCompile("de.fraunhofer.iais.eis.ids.infomodel", "java", libraryVersions["infomodel"]) - - publishCompile("org.apache.camel", "camel-core", libraryVersions["camel"]) + compileOnly("org.checkerframework", "checker-qual", libraryVersions["checkerQual"]) testImplementation("junit", "junit", libraryVersions["junit4"]) testImplementation("org.mockito", "mockito-core", libraryVersions["mockito"]) diff --git a/ids-connector/build.gradle.kts b/ids-connector/build.gradle.kts index 86724a7ba..1c43fff74 100644 --- a/ids-connector/build.gradle.kts +++ b/ids-connector/build.gradle.kts @@ -55,6 +55,7 @@ configure { } dependencies { + api(project(":ids-api")) api(project(":ids-webconsole")) api(project(":ids-settings")) api(project(":ids-container-manager")) @@ -64,12 +65,10 @@ dependencies { // Camel Spring Boot integration implementation("org.apache.camel.springboot:camel-spring-boot-starter") - // Camel components implementation("org.apache.camel.springboot:camel-rest-starter") implementation("org.apache.camel.springboot:camel-http-starter") implementation("de.fhg.aisec.ids", "camel-idscp2", libraryVersions["idscp2"]) - // Spring Boot implementation("org.springframework.boot:spring-boot-starter") implementation("org.springframework.boot:spring-boot-starter-web") diff --git a/ids-container-manager/build.gradle.kts b/ids-container-manager/build.gradle.kts index b4de670e0..fbd41de3f 100644 --- a/ids-container-manager/build.gradle.kts +++ b/ids-container-manager/build.gradle.kts @@ -31,24 +31,14 @@ configure { } dependencies { - providedByBundle(project(":ids-api")) { isTransitive = false } - + implementation(project(":ids-api")) implementation("org.springframework.boot:spring-boot-starter") - // Provided dependency of docker-java-api - providedByBundle("org.glassfish", "javax.json", libraryVersions["javaxJson"]) + implementation("org.glassfish", "javax.json", libraryVersions["javaxJson"]) // Required until our library PR has been accepted - providedByBundle("com.amihaiemil.web", "docker-java-api", libraryVersions["dockerJavaApi"]) { - exclude("com.github.jnr", "jnr-unixsocket") - } - - // implementation(project(":jnr-unixsocket-wrapper")) + implementation("com.amihaiemil.web", "docker-java-api", libraryVersions["dockerJavaApi"]) implementation("com.github.jnr", "jnr-unixsocket", libraryVersions["jnrunix"]) - implementation("com.github.jnr", "jnr-ffi", libraryVersions["jnrffi"]) - - providedByBundle("com.google.protobuf", "protobuf-java", libraryVersions["protobuf"]) - - osgiCore("org.osgi", "osgi.cmpn", libraryVersions["osgiCompendium"]) + implementation("com.google.protobuf", "protobuf-java", libraryVersions["protobuf"]) testImplementation("junit", "junit", libraryVersions["junit4"]) testImplementation("org.mockito", "mockito-core", libraryVersions["mockito"]) diff --git a/ids-container-manager/src/main/java/de/fhg/aisec/ids/cm/ContainerManagerService.java b/ids-container-manager/src/main/java/de/fhg/aisec/ids/cm/ContainerManagerService.java index b8b83d447..e0c65f9f3 100644 --- a/ids-container-manager/src/main/java/de/fhg/aisec/ids/cm/ContainerManagerService.java +++ b/ids-container-manager/src/main/java/de/fhg/aisec/ids/cm/ContainerManagerService.java @@ -23,15 +23,11 @@ import de.fhg.aisec.ids.cm.impl.docker.DockerCM; import de.fhg.aisec.ids.cm.impl.dummy.DummyCM; import de.fhg.aisec.ids.cm.impl.trustx.TrustXCM; -import org.osgi.service.component.ComponentContext; -import org.osgi.service.component.annotations.Activate; -import org.osgi.service.component.annotations.Component; -import org.osgi.service.component.annotations.Deactivate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; import java.util.List; -import java.util.Map; import java.util.Optional; /** @@ -42,29 +38,17 @@ * * @author Julian Schütte (julian.schuette@aisec.fraunhofer.de) */ -@Component(name = "ids-cml", immediate = true) -@org.springframework.stereotype.Component +@Component("idsContainerManager") public class ContainerManagerService implements ContainerManager { private static final Logger LOG = LoggerFactory.getLogger(ContainerManagerService.class); - private ContainerManager containerManager = null; + private final ContainerManager containerManager; public ContainerManagerService() { - activate(); - } - - @Activate - protected void activate() { - LOG.info("Activating Container Manager"); // When activated, try to set container management instance containerManager = getDefaultCM(); LOG.info("Default container management is {}", containerManager); } - @Deactivate - protected void deactivate(ComponentContext cContext, Map properties) { - containerManager = null; - } - private ContainerManager getDefaultCM() { ContainerManager result; if (TrustXCM.isSupported()) { diff --git a/ids-dataflow-control/build.gradle.kts b/ids-dataflow-control/build.gradle.kts index a2d1d66df..7524c27d5 100644 --- a/ids-dataflow-control/build.gradle.kts +++ b/ids-dataflow-control/build.gradle.kts @@ -4,20 +4,15 @@ dependencies { @Suppress("UNCHECKED_CAST") val libraryVersions = rootProject.extra.get("libraryVersions") as Map - providedByBundle(project(":ids-api")) { isTransitive = false } - + implementation(project(":ids-api")) { isTransitive = false } implementation("org.springframework.boot:spring-boot-starter") - - providedByBundle("com.google.guava", "guava", libraryVersions["guava"]) - + implementation("com.google.guava", "guava", libraryVersions["guava"]) implementation("it.unibo.alice.tuprolog", "2p-core", libraryVersions["2p"]) implementation("it.unibo.alice.tuprolog", "2p-parser", libraryVersions["2p"]) // implementation("it.unibo.alice.tuprolog", "2p-presentation", libraryVersions["2p"]) - providedByBundle("org.apache.commons", "commons-text", libraryVersions["commonsText"]) - providedByBundle("com.codepoetics", "protonpack", libraryVersions["protonpack"]) - providedByBundle("org.antlr", "antlr4-runtime", libraryVersions["antlr4"]) - - osgiCore("org.osgi", "osgi.cmpn", libraryVersions["osgiCompendium"]) + implementation("org.apache.commons", "commons-text", libraryVersions["commonsText"]) + implementation("com.codepoetics", "protonpack", libraryVersions["protonpack"]) + implementation("org.antlr", "antlr4-runtime", libraryVersions["antlr4"]) testImplementation("junit", "junit", libraryVersions["junit4"]) testImplementation("org.mockito", "mockito-core", libraryVersions["mockito"]) diff --git a/ids-dataflow-control/src/main/kotlin/de/fhg/aisec/ids/dataflowcontrol/PolicyDecisionPoint.kt b/ids-dataflow-control/src/main/kotlin/de/fhg/aisec/ids/dataflowcontrol/PolicyDecisionPoint.kt index 88c083455..c3a874f69 100644 --- a/ids-dataflow-control/src/main/kotlin/de/fhg/aisec/ids/dataflowcontrol/PolicyDecisionPoint.kt +++ b/ids-dataflow-control/src/main/kotlin/de/fhg/aisec/ids/dataflowcontrol/PolicyDecisionPoint.kt @@ -39,14 +39,9 @@ import de.fhg.aisec.ids.api.router.RouteVerificationProof import de.fhg.aisec.ids.dataflowcontrol.lucon.LuconEngine import de.fhg.aisec.ids.dataflowcontrol.lucon.TuPrologHelper.escape import de.fhg.aisec.ids.dataflowcontrol.lucon.TuPrologHelper.listStream -import org.osgi.service.component.ComponentContext -import org.osgi.service.component.annotations.Activate -import org.osgi.service.component.annotations.Component -import org.osgi.service.component.annotations.Reference -import org.osgi.service.component.annotations.ReferenceCardinality -import org.osgi.service.component.annotations.ReferencePolicy import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired +import org.springframework.stereotype.Component import java.io.File import java.util.LinkedList import java.util.concurrent.ExecutionException @@ -59,16 +54,13 @@ import javax.annotation.PostConstruct * * @author Julian Schuette (julian.schuette@aisec.fraunhofer.de) */ -@Component(immediate = true, name = "ids-dataflow-control") -@org.springframework.stereotype.Component +@Component("idsDataflowControl") class PolicyDecisionPoint : PDP, PAP { // Convenience val for this thread's LuconEngine instance private val engine: LuconEngine get() = threadEngine.get() - @Reference(cardinality = ReferenceCardinality.OPTIONAL, policy = ReferencePolicy.DYNAMIC) - @Volatile @Autowired(required = false) private var routeManager: RouteManager? = null @@ -153,12 +145,6 @@ class PolicyDecisionPoint : PDP, PAP { return sb.toString() } - @Activate - @Suppress("UNUSED_PARAMETER") - private fun activate(ignored: ComponentContext) { - loadPolicies() - } - @PostConstruct fun loadPolicies() { // Try to load existing policies from deploy dir at activation diff --git a/ids-dynamic-tls/build.gradle.kts b/ids-dynamic-tls/build.gradle.kts index e5e6bb3c5..eece002b5 100644 --- a/ids-dynamic-tls/build.gradle.kts +++ b/ids-dynamic-tls/build.gradle.kts @@ -2,9 +2,6 @@ val libraryVersions = rootProject.extra.get("libraryVersions") as Map dependencies { - providedByBundle(project(":ids-api")) { isTransitive = false } - - osgiCore("org.osgi", "org.osgi.core", libraryVersions["osgi"]) - - providedByFeature("org.eclipse.jetty", "jetty-util", libraryVersions["jetty"]) + implementation(project(":ids-api")) { isTransitive = false } + implementation("org.eclipse.jetty", "jetty-util", libraryVersions["jetty"]) } diff --git a/ids-endpoint-config/build.gradle.kts b/ids-endpoint-config/build.gradle.kts index 1799fe472..bc7437927 100644 --- a/ids-endpoint-config/build.gradle.kts +++ b/ids-endpoint-config/build.gradle.kts @@ -2,9 +2,7 @@ val libraryVersions = rootProject.extra.get("libraryVersions") as Map dependencies { - providedByBundle(project(":ids-api")) { isTransitive = false } - - osgiCore("org.osgi", "osgi.cmpn", libraryVersions["osgiCompendium"]) + implementation(project(":ids-api")) { isTransitive = false } testImplementation("junit", "junit", libraryVersions["junit4"]) testImplementation("org.mockito", "mockito-core", libraryVersions["mockito"]) diff --git a/ids-infomodel-manager/build.gradle.kts b/ids-infomodel-manager/build.gradle.kts index 9e826571c..5032a72cf 100644 --- a/ids-infomodel-manager/build.gradle.kts +++ b/ids-infomodel-manager/build.gradle.kts @@ -27,19 +27,12 @@ configure { } dependencies { - infomodelBundle(project(":ids-api")) { isTransitive = false } - + implementation(project(":ids-api")) { isTransitive = false } implementation("de.fraunhofer.iais.eis.ids.infomodel", "java", libraryVersions["infomodel"]) implementation("de.fraunhofer.iais.eis.ids", "infomodel-serializer", libraryVersions["infomodel"]) - - infomodelBundle("commons-cli", "commons-cli", libraryVersions["commonsCli"]) - - infomodelBundle("javax.validation", "validation-api", libraryVersions["javaxValidation"]) - - infomodelBundle("com.fasterxml.jackson.core", "jackson-annotations", libraryVersions["jackson"]) - infomodelBundle("com.fasterxml.jackson.core", "jackson-databind", libraryVersions["jackson"]) - - osgiCore("org.osgi", "osgi.cmpn", libraryVersions["osgiCompendium"]) - + implementation("commons-cli", "commons-cli", libraryVersions["commonsCli"]) + implementation("javax.validation", "validation-api", libraryVersions["javaxValidation"]) + implementation("com.fasterxml.jackson.core", "jackson-annotations", libraryVersions["jackson"]) + implementation("com.fasterxml.jackson.core", "jackson-databind", libraryVersions["jackson"]) implementation("org.springframework.boot:spring-boot-starter") } diff --git a/ids-infomodel-manager/src/main/kotlin/de/fhg/aisec/ids/informationmodelmanager/InfoModelService.kt b/ids-infomodel-manager/src/main/kotlin/de/fhg/aisec/ids/informationmodelmanager/InfoModelService.kt index 368988f1d..e3d21047d 100644 --- a/ids-infomodel-manager/src/main/kotlin/de/fhg/aisec/ids/informationmodelmanager/InfoModelService.kt +++ b/ids-infomodel-manager/src/main/kotlin/de/fhg/aisec/ids/informationmodelmanager/InfoModelService.kt @@ -35,8 +35,6 @@ import de.fraunhofer.iais.eis.TrustedConnectorBuilder import de.fraunhofer.iais.eis.ids.jsonld.Serializer import de.fraunhofer.iais.eis.util.ConstraintViolationException import de.fraunhofer.iais.eis.util.TypedLiteral -import org.osgi.service.component.annotations.Reference -import org.osgi.service.component.annotations.ReferenceCardinality import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired import java.net.URI @@ -47,11 +45,8 @@ import java.net.URISyntaxException @org.springframework.stereotype.Component class InfoModelService : InfoModel { - @Reference(cardinality = ReferenceCardinality.MANDATORY) @Autowired private lateinit var settings: Settings - - @Reference(cardinality = ReferenceCardinality.OPTIONAL) @Autowired(required = false) private var connectionManager: ConnectionManager? = null diff --git a/ids-route-manager/build.gradle.kts b/ids-route-manager/build.gradle.kts index 764cc338b..626898a50 100644 --- a/ids-route-manager/build.gradle.kts +++ b/ids-route-manager/build.gradle.kts @@ -2,27 +2,20 @@ dependencies { @Suppress("UNCHECKED_CAST") val libraryVersions = rootProject.extra.get("libraryVersions") as Map - providedByBundle(project(":ids-api")) { isTransitive = false } + implementation(project(":ids-api")) { isTransitive = false } implementation("org.apache.camel.springboot:camel-spring-boot-starter") implementation("org.springframework.boot:spring-boot-starter") implementation("org.apache.camel.springboot:camel-spring-boot-starter") - implementation("de.fraunhofer.iais.eis.ids.infomodel", "java", libraryVersions["infomodel"]) - - providedByFeature("javax.xml.bind", "jaxb-api", libraryVersions["jaxbApi"]) - providedByFeature("org.apache.camel", "camel-core", libraryVersions["camel"]) - providedByFeature("org.apache.camel", "camel-management", libraryVersions["camel"]) - - osgiCore("org.apache.felix", "org.apache.felix.framework", libraryVersions["felixFramework"]) - osgiCore("org.osgi", "osgi.cmpn", libraryVersions["osgiCompendium"]) - - providedByBundle("com.google.guava", "guava", libraryVersions["guava"]) + implementation("javax.xml.bind", "jaxb-api", libraryVersions["jaxbApi"]) + implementation("org.apache.camel", "camel-core", libraryVersions["camel"]) + implementation("org.apache.camel", "camel-management", libraryVersions["camel"]) + implementation("com.google.guava", "guava", libraryVersions["guava"]) testImplementation("com.sun.xml.bind", "jaxb-core", libraryVersions["jaxbCore"]) testImplementation("com.sun.xml.bind", "jaxb-impl", libraryVersions["jaxbImpl"]) testImplementation("com.sun.activation", "javax.activation", libraryVersions["jaxActivation"]) - testImplementation("junit", "junit", libraryVersions["junit4"]) testImplementation("org.mockito", "mockito-core", libraryVersions["mockito"]) testImplementation("org.apache.camel", "camel-test", libraryVersions["camel"]) diff --git a/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/CamelInterceptor.kt b/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/CamelInterceptor.kt index 08566a272..5901e7779 100644 --- a/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/CamelInterceptor.kt +++ b/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/CamelInterceptor.kt @@ -26,26 +26,20 @@ import org.apache.camel.CamelContext import org.apache.camel.NamedNode import org.apache.camel.Processor import org.apache.camel.spi.InterceptStrategy -import org.osgi.service.component.annotations.Activate -import org.osgi.service.component.annotations.Component -import org.osgi.service.component.annotations.Reference -import org.osgi.service.component.annotations.ReferenceCardinality -import org.osgi.service.component.annotations.ReferencePolicy +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.stereotype.Component -@Component(immediate = true, name = "ids-camel-interceptor") +@Component("idsCamelInterceptor") class CamelInterceptor : InterceptStrategy { - @Reference(cardinality = ReferenceCardinality.OPTIONAL, policy = ReferencePolicy.DYNAMIC) - @Volatile + + @Autowired(required = false) private var pdp: PDP? = null - @Reference(cardinality = ReferenceCardinality.OPTIONAL, policy = ReferencePolicy.DYNAMIC) - @Volatile + @Autowired(required = false) private var usageControlInterface: Idscp2UsageControlInterface? = null - @Reference(cardinality = ReferenceCardinality.OPTIONAL, policy = ReferencePolicy.DYNAMIC) - @Volatile + @Autowired(required = false) private var containerManager: ContainerManager? = null - @Activate - private fun activate() { + init { instance = this } diff --git a/ids-settings/build.gradle.kts b/ids-settings/build.gradle.kts index e4b8724f2..e90528ec5 100644 --- a/ids-settings/build.gradle.kts +++ b/ids-settings/build.gradle.kts @@ -2,17 +2,13 @@ val libraryVersions = rootProject.extra.get("libraryVersions") as Map dependencies { - infomodelBundle(project(":ids-api")) { isTransitive = false } - + implementation(project(":ids-api")) { isTransitive = false } // Required by MapDB below - providedByBundle("com.google.guava", "guava", libraryVersions["guava"]) + implementation("com.google.guava", "guava", libraryVersions["guava"]) implementation("org.mapdb", "mapdb", libraryVersions["mapdb"]) { // Exclude guava dependency, which is provided by bundle exclude("com.google.guava", "guava") exclude("org.jetbrains.kotlin", "*") } - - osgiCore("org.osgi", "osgi.cmpn", libraryVersions["osgiCompendium"]) - implementation("org.springframework.boot:spring-boot-starter") } diff --git a/ids-webconsole/build.gradle.kts b/ids-webconsole/build.gradle.kts index 150e65437..ee506c3a2 100644 --- a/ids-webconsole/build.gradle.kts +++ b/ids-webconsole/build.gradle.kts @@ -69,37 +69,17 @@ and is used by the default administration dashboard ("web console"). dependencies { implementation(project(":ids-api")) implementation("org.springframework.boot:spring-boot-starter-jersey") - - // Actual implementation must be provided by ids-infomodel-manager - compileOnly("de.fraunhofer.iais.eis.ids.infomodel", "java", libraryVersions["infomodel"]) - - providedByFeature("javax.servlet", "javax.servlet-api", libraryVersions["javaxServlet"]) - - providedByFeature("org.apache.camel", "camel-core", libraryVersions["camel"]) - - providedByFeature("org.apache.cxf", "cxf-rt-frontend-jaxrs", libraryVersions["cxf"]) - providedByFeature("org.apache.cxf", "cxf-rt-rs-extension-providers", libraryVersions["cxf"]) - - // This is required for compilation only, and provided by karaf automatically, likely by some included feature - compileOnly("javax.ws.rs", "javax.ws.rs-api", libraryVersions["wsRsApi"]) - - compileOnly("org.checkerframework", "checker-qual", libraryVersions["checkerQual"]) - - // use our specified version of jackson instead of the cxf-jackson feature - providedByBundle("com.fasterxml.jackson.core", "jackson-core", libraryVersions["jackson"]) - providedByBundle("com.fasterxml.jackson.core", "jackson-databind", libraryVersions["jackson"]) - providedByBundle("com.fasterxml.jackson.core", "jackson-annotations", libraryVersions["jackson"]) - providedByBundle("com.fasterxml.jackson.dataformat", "jackson-dataformat-yaml", libraryVersions["jackson"]) - providedByBundle("com.fasterxml.jackson.jaxrs", "jackson-jaxrs-json-provider", libraryVersions["jackson"]) - - providedByBundle("org.bitbucket.b_c", "jose4j", libraryVersions["jose4j"]) + implementation("de.fraunhofer.iais.eis.ids.infomodel", "java", libraryVersions["infomodel"]) + implementation("org.apache.camel", "camel-core", libraryVersions["camel"]) + implementation("org.apache.cxf", "cxf-rt-rs-extension-providers", libraryVersions["cxf"]) + implementation("org.bitbucket.b_c", "jose4j", libraryVersions["jose4j"]) implementation("com.auth0", "java-jwt", libraryVersions["auth0Jwt"]) + compileOnly("org.checkerframework", "checker-qual", libraryVersions["checkerQual"]) compileOnly("io.swagger", "swagger-jaxrs", libraryVersions["swagger"]) testImplementation("junit", "junit", libraryVersions["junit4"]) testImplementation("org.mockito", "mockito-core", libraryVersions["mockito"]) - testImplementation("org.apache.cxf", "cxf-rt-transports-local", libraryVersions["cxf"]) testImplementation("org.apache.cxf", "cxf-rt-rs-client", libraryVersions["cxf"]) } diff --git a/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/CertApi.kt b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/CertApi.kt index 6d723a0e9..a9cb8cd39 100644 --- a/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/CertApi.kt +++ b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/CertApi.kt @@ -51,9 +51,6 @@ import java.net.URISyntaxException import java.nio.charset.StandardCharsets import java.nio.file.FileSystems import java.security.KeyStore -import java.security.KeyStoreException -import java.security.NoSuchAlgorithmException -import java.security.cert.CertificateException import java.security.cert.CertificateFactory import java.security.cert.X509Certificate import java.util.UUID @@ -266,16 +263,7 @@ class CertApi { } } true - } catch (e: CertificateException) { - LOG.error(e.message, e) - false - } catch (e: KeyStoreException) { - LOG.error(e.message, e) - false - } catch (e: NoSuchAlgorithmException) { - LOG.error(e.message, e) - false - } catch (e: IOException) { + } catch (e: Exception) { LOG.error(e.message, e) false } @@ -374,13 +362,7 @@ class CertApi { certs.add(cert) } } - } catch (e: CertificateException) { - LOG.error(e.message, e) - } catch (e: KeyStoreException) { - LOG.error(e.message, e) - } catch (e: NoSuchAlgorithmException) { - LOG.error(e.message, e) - } catch (e: IOException) { + } catch (e: Exception) { LOG.error(e.message, e) } return certs @@ -437,21 +419,12 @@ class CertApi { keystore.load(fis, KEYSTORE_PWD.toCharArray()) if (keystore.containsAlias(alias)) { keystore.deleteEntry(alias) - FileOutputStream(file).use { fos -> keystore.store(fos, KEYSTORE_PWD.toCharArray()) } + FileOutputStream(file).use { keystore.store(it, KEYSTORE_PWD.toCharArray()) } } else { LOG.warn("Alias not available. Cannot delete it: $alias") } } - } catch (e: CertificateException) { - LOG.error(e.message, e) - return false - } catch (e: NoSuchAlgorithmException) { - LOG.error(e.message, e) - return false - } catch (e: KeyStoreException) { - LOG.error(e.message, e) - return false - } catch (e: IOException) { + } catch (e: Exception) { LOG.error(e.message, e) return false } @@ -461,15 +434,13 @@ class CertApi { companion object { private val LOG = LoggerFactory.getLogger(CertApi::class.java) private const val KEYSTORE_PWD = "password" + @Throws(IOException::class) - private fun fullStream(fname: String): InputStream { - val fis = FileInputStream(fname) - val dis = DataInputStream(fis) - val bytes = ByteArray(dis.available()) - dis.readFully(bytes) - val bais = ByteArrayInputStream(bytes) - dis.close() - return bais + private fun fullStream(fileName: String): InputStream { + DataInputStream(FileInputStream(fileName)).use { dis -> + val bytes = dis.readAllBytes() + return ByteArrayInputStream(bytes) + } } } } From 09883614a5cb15e4a9b971e833cc39ac8a4ad2bc Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Tue, 11 May 2021 17:51:44 +0200 Subject: [PATCH 37/54] Fixed logout on error in web UI --- .../src/app/_interceptors/jwt.interceptor.ts | 33 +++++++++---------- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/ids-webconsole/src/main/angular/src/app/_interceptors/jwt.interceptor.ts b/ids-webconsole/src/main/angular/src/app/_interceptors/jwt.interceptor.ts index 65d32be98..01079b3b5 100644 --- a/ids-webconsole/src/main/angular/src/app/_interceptors/jwt.interceptor.ts +++ b/ids-webconsole/src/main/angular/src/app/_interceptors/jwt.interceptor.ts @@ -11,25 +11,22 @@ import { LoginService } from '../login/login.service'; @Injectable() export class JwtInterceptor implements HttpInterceptor { - constructor(public loginService: LoginService) {} + constructor(public loginService: LoginService) { } - public intercept(request: HttpRequest, next: HttpHandler): Observable> { - // add Authorization header with jwt token to outgoing HTTP request - const currentUser = localStorage.getItem('currentUser'); - if (currentUser) { - request = request.clone({ - setHeaders: { - /* eslint-disable @typescript-eslint/naming-convention */ - Authorization: `Bearer ${currentUser}` - } - }); + public intercept(request: HttpRequest, next: HttpHandler): Observable> { + // add Authorization header with jwt token to outgoing HTTP request + const currentUser = localStorage.getItem('currentUser'); + if (currentUser) { + request = request.clone({ + setHeaders: { + /* eslint-disable @typescript-eslint/naming-convention */ + Authorization: `Bearer ${currentUser}` } - - // If we receive 401 (or other error), log out the user immediately. - return next.handle(request).pipe( - catchError((err: HttpErrorResponse) => { - this.loginService.logout(); - return throwError(err); - })); + }); } + + // If we receive 401 (or other error), log out the user immediately. + return next.handle(request) + .pipe(catchError((err: HttpErrorResponse) => throwError(err))); + } } From 7df30eb2bf3ac67352fdf0a48ae561d260696d58 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Tue, 11 May 2021 18:57:04 +0200 Subject: [PATCH 38/54] More cleanup, TLS support --- camel-influxdb/bnd.bnd | 3 - camel-multipart-processor/bnd.bnd | 4 - .../etc/consumer-core-protocol-test.p12 | Bin 2709 -> 0 bytes .../etc/provider-core-protocol-test.p12 | Bin 2709 -> 0 bytes .../README.md | 0 .../build.gradle.kts | 1 + .../etc/consumer-keystore.p12 | Bin .../etc/provider-keystore.p12 | Bin .../etc/settings.mapdb | Bin .../etc/truststore.p12 | Bin .../de/fhg/aisec/ids/ExampleConnector.kt | 0 .../de/fhg/aisec/ids/ExampleIdscpClient.kt | 0 .../de/fhg/aisec/ids/ExampleIdscpServer.kt | 0 ids-acme/bnd.bnd | 13 -- .../fhg/aisec/ids/acme/AcmeClientService.kt | 66 +++--- ids-api/bnd.bnd | 12 -- ids-connector/build.gradle.kts | 6 +- .../de/fhg/aisec/ids/TlsConfiguration.kt | 54 +++++ .../ids/dynamictls/AcmeSslContextFactory.kt | 73 +++++++ ids-container-manager/bnd.bnd | 6 - ids-dataflow-control/bnd.bnd | 7 - ids-dynamic-tls/.gitignore | 5 - ids-dynamic-tls/LICENSE.txt | 201 ------------------ ids-dynamic-tls/README.md | 1 - ids-dynamic-tls/bnd.bnd | 8 - ids-dynamic-tls/build.gradle.kts | 7 - .../ids/dynamictls/AcmeSslContextFactory.java | 79 ------- ids-endpoint-config/bnd.bnd | 8 - ids-infomodel-manager/bnd.bnd | 26 --- ids-route-manager/bnd.bnd | 9 - ids-settings/bnd.bnd | 11 - settings.gradle.kts | 5 +- 32 files changed, 163 insertions(+), 442 deletions(-) delete mode 100644 camel-influxdb/bnd.bnd delete mode 100644 camel-multipart-processor/bnd.bnd delete mode 100644 example-idscp2-client-server/etc/consumer-core-protocol-test.p12 delete mode 100644 example-idscp2-client-server/etc/provider-core-protocol-test.p12 rename {example-idscp2-client-server => example-route-builder}/README.md (100%) rename {example-idscp2-client-server => example-route-builder}/build.gradle.kts (82%) rename {example-idscp2-client-server => example-route-builder}/etc/consumer-keystore.p12 (100%) rename {example-idscp2-client-server => example-route-builder}/etc/provider-keystore.p12 (100%) rename {example-idscp2-client-server => example-route-builder}/etc/settings.mapdb (100%) rename {example-idscp2-client-server => example-route-builder}/etc/truststore.p12 (100%) rename {example-idscp2-client-server => example-route-builder}/src/main/kotlin/de/fhg/aisec/ids/ExampleConnector.kt (100%) rename {example-idscp2-client-server => example-route-builder}/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpClient.kt (100%) rename {example-idscp2-client-server => example-route-builder}/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpServer.kt (100%) delete mode 100644 ids-acme/bnd.bnd delete mode 100644 ids-api/bnd.bnd create mode 100644 ids-connector/src/main/kotlin/de/fhg/aisec/ids/TlsConfiguration.kt create mode 100644 ids-connector/src/main/kotlin/de/fhg/aisec/ids/dynamictls/AcmeSslContextFactory.kt delete mode 100644 ids-container-manager/bnd.bnd delete mode 100644 ids-dataflow-control/bnd.bnd delete mode 100644 ids-dynamic-tls/.gitignore delete mode 100644 ids-dynamic-tls/LICENSE.txt delete mode 100644 ids-dynamic-tls/README.md delete mode 100644 ids-dynamic-tls/bnd.bnd delete mode 100644 ids-dynamic-tls/build.gradle.kts delete mode 100644 ids-dynamic-tls/src/main/java/de/fhg/aisec/ids/dynamictls/AcmeSslContextFactory.java delete mode 100644 ids-endpoint-config/bnd.bnd delete mode 100644 ids-infomodel-manager/bnd.bnd delete mode 100644 ids-route-manager/bnd.bnd delete mode 100644 ids-settings/bnd.bnd diff --git a/camel-influxdb/bnd.bnd b/camel-influxdb/bnd.bnd deleted file mode 100644 index 9bab4c673..000000000 --- a/camel-influxdb/bnd.bnd +++ /dev/null @@ -1,3 +0,0 @@ -Bundle-Name: IDS :: Camel InfluxDB adapter -Bundle-Description: InfluxDB support for Camel messages -Import-Package: * diff --git a/camel-multipart-processor/bnd.bnd b/camel-multipart-processor/bnd.bnd deleted file mode 100644 index 88bccc6ce..000000000 --- a/camel-multipart-processor/bnd.bnd +++ /dev/null @@ -1,4 +0,0 @@ -Bundle-Name: IDS :: Camel Multipart Processor -Bundle-Description: Mime/Multipart support for Camel messages -Export-Package: de.fhg.aisec.ids.camel.multipart -Import-Package: * diff --git a/example-idscp2-client-server/etc/consumer-core-protocol-test.p12 b/example-idscp2-client-server/etc/consumer-core-protocol-test.p12 deleted file mode 100644 index b9022b7f7b58878a01de63efdf91d0df67d3e00d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2709 zcmV;G3TpK*f(nrW0Ru3C3ReaRDuzgg_YDCD0ic2kNCbikL@M3t zMH4m#0s;sCfPw_D1jn0KTM5L?cD$TEiH*GiT%7LX$$K5YWT3$BM{QQ!UXf65UZmKO znKc*^mEH!eqQ!n{@YC#^!6EdTAHKr9rmEJoeyR~Up(B>SK6I+sibm*N=H+&>`g87O zSO7D}Ie^D0nvxy7fgn=CF9&cA2>02ZoPP2Lv&L9Q<;;Vx$kyoDNf2;Iqwch$fhALw z&W%rZJ5lB@D&%-h=Fw!%oU&HmD~M<XlYK`Qo z1r*r;)$}qyxy3P(MF!?J1XZSmAjM2zJN)}2_cQ1PNO8)0qy>t(Zj%y<=F}%ukI8NCE;3X?cHnLS

-3?R$*)FBmO3H&PfaLGrXlZSY>& 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 P6LsbnYPsWf0s;sC@3->f diff --git a/example-idscp2-client-server/README.md b/example-route-builder/README.md similarity index 100% rename from example-idscp2-client-server/README.md rename to example-route-builder/README.md diff --git a/example-idscp2-client-server/build.gradle.kts b/example-route-builder/build.gradle.kts similarity index 82% rename from example-idscp2-client-server/build.gradle.kts rename to example-route-builder/build.gradle.kts index 475c794a1..e34b2c109 100644 --- a/example-idscp2-client-server/build.gradle.kts +++ b/example-route-builder/build.gradle.kts @@ -11,4 +11,5 @@ dependencies { // Can and should be replaced by a reference to a maven published artifact later implementation(project(":ids-connector")) implementation("org.springframework.boot:spring-boot-starter") + implementation("org.apache.camel.springboot:camel-spring-boot-starter") } diff --git a/example-idscp2-client-server/etc/consumer-keystore.p12 b/example-route-builder/etc/consumer-keystore.p12 similarity index 100% rename from example-idscp2-client-server/etc/consumer-keystore.p12 rename to example-route-builder/etc/consumer-keystore.p12 diff --git a/example-idscp2-client-server/etc/provider-keystore.p12 b/example-route-builder/etc/provider-keystore.p12 similarity index 100% rename from example-idscp2-client-server/etc/provider-keystore.p12 rename to example-route-builder/etc/provider-keystore.p12 diff --git a/example-idscp2-client-server/etc/settings.mapdb b/example-route-builder/etc/settings.mapdb similarity index 100% rename from example-idscp2-client-server/etc/settings.mapdb rename to example-route-builder/etc/settings.mapdb diff --git a/example-idscp2-client-server/etc/truststore.p12 b/example-route-builder/etc/truststore.p12 similarity index 100% rename from example-idscp2-client-server/etc/truststore.p12 rename to example-route-builder/etc/truststore.p12 diff --git a/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleConnector.kt b/example-route-builder/src/main/kotlin/de/fhg/aisec/ids/ExampleConnector.kt similarity index 100% rename from example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleConnector.kt rename to example-route-builder/src/main/kotlin/de/fhg/aisec/ids/ExampleConnector.kt diff --git a/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpClient.kt b/example-route-builder/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpClient.kt similarity index 100% rename from example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpClient.kt rename to example-route-builder/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpClient.kt diff --git a/example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpServer.kt b/example-route-builder/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpServer.kt similarity index 100% rename from example-idscp2-client-server/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpServer.kt rename to example-route-builder/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpServer.kt diff --git a/ids-acme/bnd.bnd b/ids-acme/bnd.bnd deleted file mode 100644 index a34ed438f..000000000 --- a/ids-acme/bnd.bnd +++ /dev/null @@ -1,13 +0,0 @@ -Bundle-Name: IDS :: ACME Client Service -Require-Capability: osgi.extender; filter:="(osgi.extender=osgi.serviceloader.registrar)",\ - osgi.extender; filter:="(osgi.extender=osgi.serviceloader.processor)",\ - osgi.serviceloader; cardinality:=multiple; filter:="(osgi.serviceloader=org.shredzone.acme4j.provider.AcmeProvider)" -Provide-Capability: osgi.serviceloader; osgi.serviceloader=org.shredzone.acme4j.provider.AcmeProvider -# Packages that should be included in the resulting jar file, but *not* exported -Private-Package: \ - fi.iki.elonen*,\ - org.shredzone.acme4j*,\ - org.bouncycastle*,\ - org.jose4j* -Import-Package: \ - * diff --git a/ids-acme/src/main/kotlin/de/fhg/aisec/ids/acme/AcmeClientService.kt b/ids-acme/src/main/kotlin/de/fhg/aisec/ids/acme/AcmeClientService.kt index 0b59dac73..910187248 100644 --- a/ids-acme/src/main/kotlin/de/fhg/aisec/ids/acme/AcmeClientService.kt +++ b/ids-acme/src/main/kotlin/de/fhg/aisec/ids/acme/AcmeClientService.kt @@ -23,7 +23,6 @@ import de.fhg.aisec.ids.api.acme.AcmeClient import de.fhg.aisec.ids.api.acme.AcmeTermsOfService import de.fhg.aisec.ids.api.acme.SslContextFactoryReloadable import de.fhg.aisec.ids.api.settings.Settings -import org.apache.karaf.scheduler.Scheduler import org.shredzone.acme4j.Account import org.shredzone.acme4j.AccountBuilder import org.shredzone.acme4j.Order @@ -35,6 +34,8 @@ import org.shredzone.acme4j.exception.AcmeNetworkException import org.shredzone.acme4j.util.CSRBuilder import org.shredzone.acme4j.util.KeyPairUtils import org.slf4j.LoggerFactory +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.stereotype.Component import java.io.IOException import java.io.InputStreamReader import java.net.URI @@ -48,9 +49,9 @@ import java.security.KeyStore import java.security.cert.X509Certificate import java.time.LocalDateTime import java.time.format.DateTimeFormatter -import java.util.Arrays import java.util.Collections import java.util.Date +import javax.annotation.PostConstruct @Component( "idsAcmeClient" @@ -60,35 +61,8 @@ import java.util.Date ) class AcmeClientService : AcmeClient, Runnable { - /* - * The following block subscribes this component to the Settings Service - */ - @Autowired(required = false) - private var settings: Settings? = null - - private val sslReloadables = Collections.synchronizedSet(HashSet()) - /* - * The following block subscribes this component to any SslContextFactoryReloader. - * - * A SslContextFactoryReloader is expected to refresh all TLS connections with new - * certificates from the key store. - */ - // TODO: Adapt for Spring - // @Reference( - // name = "dynamic-tls-reload-service", - // service = SslContextFactoryReloadable::class, - // cardinality = ReferenceCardinality.MULTIPLE, - // unbind = "unbindSslContextFactoryReloadable" - // ) - private fun bindSslContextFactoryReloadable(reloadable: SslContextFactoryReloadable) { - LOG.info("Bound SslContextFactoryReloadable in AcmeClientService") - this.sslReloadables.add(reloadable) - } - - @Suppress("unused") - private fun unbindSslContextFactoryReloadable(factory: SslContextFactoryReloadable) { - this.sslReloadables.remove(factory) - } + @Autowired + private lateinit var settings: Settings override fun getTermsOfService(acmeServerUri: URI): AcmeTermsOfService { try { @@ -113,7 +87,7 @@ class AcmeClientService : AcmeClient, Runnable { } private fun ensureKeys(targetDirectory: Path) { - Arrays.asList("acme.key", "domain.key").forEach { keyFile -> + listOf("acme.key", "domain.key").forEach { keyFile -> val keyFilePath = targetDirectory.resolve(keyFile) if (!keyFilePath.toFile().exists()) { val keyPair = KeyPairUtils.createKeyPair(4096) @@ -301,9 +275,7 @@ class AcmeClientService : AcmeClient, Runnable { "Reloading of {} SslContextFactoryReloadable implementations...", sslReloadables.size ) - sslReloadables.forEach { r -> - r.reload(keyStorePath.toString()) - } + sslReloadables.forEach { it.reload(keyStorePath.toString()) } } } catch (e: Exception) { LOG.error("Error whilst creating new KeyStore!", e) @@ -333,6 +305,7 @@ class AcmeClientService : AcmeClient, Runnable { } } + @Suppress("MemberVisibilityCanBePrivate") fun renewalCheck( targetDirectory: Path, acmeServerUrl: String, @@ -395,11 +368,11 @@ class AcmeClientService : AcmeClient, Runnable { } } - @Activate + @PostConstruct override fun run() { LOG.info("ACME renewal job has been triggered (once upon start and daily at 3:00).") try { - val config = settings!!.connectorConfig + val config = settings.connectorConfig renewalCheck( FileSystems.getDefault().getPath("etc", "tls-webconsole"), config.acmeServerWebcon, @@ -420,7 +393,24 @@ class AcmeClientService : AcmeClient, Runnable { const val RENEWAL_THRESHOLD = 100.0 / 3.0 const val KEYSTORE_LATEST = "keystore_latest.p12" - private val LOG = LoggerFactory.getLogger(AcmeClientService::class.java)!! + private val LOG = LoggerFactory.getLogger(AcmeClientService::class.java) private val challengeMap = HashMap() + private val sslReloadables = Collections.synchronizedSet(HashSet()) + + /* + * The following block subscribes this component to any SslContextFactoryReloader. + * + * A SslContextFactoryReloader is expected to refresh all TLS connections with new + * certificates from the key store. + */ + fun registerSslContextFactoryReloadable(reloadable: SslContextFactoryReloadable) { + LOG.info("Registered SslContextFactoryReloadable in AcmeClientService") + this.sslReloadables.add(reloadable) + } + + @Suppress("unused") + fun removeSslContextFactoryReloadable(reloadable: SslContextFactoryReloadable) { + this.sslReloadables.remove(reloadable) + } } } diff --git a/ids-api/bnd.bnd b/ids-api/bnd.bnd deleted file mode 100644 index 97e2190e4..000000000 --- a/ids-api/bnd.bnd +++ /dev/null @@ -1,12 +0,0 @@ -Bundle-Name: IDS :: Core Platform API -Bundle-Description: Common APIs for IDS connector components. This bundle can be shared, implementations \ - are found in other bundles -Export-Package: \ - de.fhg.aisec.ids.api*,\ - de.fhg.aisec.ids.messages -Import-Package: \ - de.fraunhofer.iais.eis*,\ - !de.fhg.aisec.ids.messages,\ - !org.checkerframework.checker*,\ - !annotation*,\ - * diff --git a/ids-connector/build.gradle.kts b/ids-connector/build.gradle.kts index 1c43fff74..ee4e2b993 100644 --- a/ids-connector/build.gradle.kts +++ b/ids-connector/build.gradle.kts @@ -56,6 +56,7 @@ configure { dependencies { api(project(":ids-api")) + api(project(":ids-acme")) api(project(":ids-webconsole")) api(project(":ids-settings")) api(project(":ids-container-manager")) @@ -71,5 +72,8 @@ dependencies { implementation("de.fhg.aisec.ids", "camel-idscp2", libraryVersions["idscp2"]) // Spring Boot implementation("org.springframework.boot:spring-boot-starter") - implementation("org.springframework.boot:spring-boot-starter-web") + implementation("org.springframework.boot:spring-boot-starter-web") { + exclude("org.springframework.boot", "spring-boot-starter-tomcat") + } + implementation("org.springframework.boot:spring-boot-starter-jetty") } diff --git a/ids-connector/src/main/kotlin/de/fhg/aisec/ids/TlsConfiguration.kt b/ids-connector/src/main/kotlin/de/fhg/aisec/ids/TlsConfiguration.kt new file mode 100644 index 000000000..d430d3268 --- /dev/null +++ b/ids-connector/src/main/kotlin/de/fhg/aisec/ids/TlsConfiguration.kt @@ -0,0 +1,54 @@ +/*- + * ========================LICENSE_START================================= + * ids-connector + * %% + * Copyright (C) 2021 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids + +import de.fhg.aisec.ids.dynamictls.AcmeSslContextFactory +import org.eclipse.jetty.server.Connector +import org.eclipse.jetty.server.Server +import org.eclipse.jetty.server.ServerConnector +import org.eclipse.jetty.util.ssl.SslContextFactory +import org.springframework.boot.web.embedded.jetty.JettyServerCustomizer +import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory +import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration + +@Configuration +class TlsConfiguration { + + @Bean + fun sslContextFactory(): SslContextFactory.Server { + return AcmeSslContextFactory() + } + + @Bean + fun webServerFactory(sslContextFactory: SslContextFactory.Server): ConfigurableServletWebServerFactory { + return JettyServletWebServerFactory().apply { + port = 8443 + serverCustomizers = listOf( + JettyServerCustomizer { server: Server -> + server.connectors = arrayOf( + ServerConnector(server, sslContextFactory) + ) + } + ) + } + } +} diff --git a/ids-connector/src/main/kotlin/de/fhg/aisec/ids/dynamictls/AcmeSslContextFactory.kt b/ids-connector/src/main/kotlin/de/fhg/aisec/ids/dynamictls/AcmeSslContextFactory.kt new file mode 100644 index 000000000..f99350fcd --- /dev/null +++ b/ids-connector/src/main/kotlin/de/fhg/aisec/ids/dynamictls/AcmeSslContextFactory.kt @@ -0,0 +1,73 @@ +/*- + * ========================LICENSE_START================================= + * ids-connector + * %% + * Copyright (C) 2019 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.dynamictls + +import de.fhg.aisec.ids.acme.AcmeClientService +import de.fhg.aisec.ids.api.acme.SslContextFactoryReloadable +import org.eclipse.jetty.util.ssl.SslContextFactory +import org.slf4j.LoggerFactory + +/** + * This SslContextFactory registers started instances to an OSGi service that allows reloading of + * all active SslContextFactory instances. + * + * @author Michael Lux + */ +class AcmeSslContextFactory : SslContextFactory.Server(), SslContextFactoryReloadable { + + @Throws(Exception::class) + override fun doStart() { + if (LOG.isDebugEnabled) { + LOG.debug("Starting {}", this) + } + AcmeClientService.registerSslContextFactoryReloadable(this) + super.doStart() + } + + @Throws(java.lang.Exception::class) + override fun doStop() { + if (LOG.isDebugEnabled) { + LOG.debug("Stopping {}", this) + } + AcmeClientService.removeSslContextFactoryReloadable(this) + super.doStop() + } + + override fun reload(newKeyStorePath: String) { + try { + if (LOG.isInfoEnabled) { + LOG.info("Reloading {}", this) + } + reload { f: SslContextFactory -> f.keyStorePath = newKeyStorePath } + } catch (e: Exception) { + LOG.error("Error whilst reloading SslContextFactory: $this", e) + } + } + + override fun toString(): String { + return String.format( + "%s@%x (%s)", this.javaClass.simpleName, this.hashCode(), this.keyStorePath + ) + } + + companion object { + private val LOG = LoggerFactory.getLogger(AcmeSslContextFactory::class.java) + } +} diff --git a/ids-container-manager/bnd.bnd b/ids-container-manager/bnd.bnd deleted file mode 100644 index b1657d997..000000000 --- a/ids-container-manager/bnd.bnd +++ /dev/null @@ -1,6 +0,0 @@ -Bundle-Name: IDS :: Container Manager -Export-Package: \ - de.fhg.aisec.ids.cm,\ - com.amihaiemil.docker -Import-Package: \ - * diff --git a/ids-dataflow-control/bnd.bnd b/ids-dataflow-control/bnd.bnd deleted file mode 100644 index 364cacf6a..000000000 --- a/ids-dataflow-control/bnd.bnd +++ /dev/null @@ -1,7 +0,0 @@ -Bundle-Name: IDS :: Dataflow Control Engine -Export-Package: \ - alice*;-split-package:=merge-last,\ - de.fhg.aisec.ids.dataflowcontrol* -Import-Package: \ - !dalvik*,\ - * diff --git a/ids-dynamic-tls/.gitignore b/ids-dynamic-tls/.gitignore deleted file mode 100644 index 9773bdd32..000000000 --- a/ids-dynamic-tls/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -/bin/ -/build/ -/generated/ -/generated-sources/ -/target/ diff --git a/ids-dynamic-tls/LICENSE.txt b/ids-dynamic-tls/LICENSE.txt deleted file mode 100644 index 261eeb9e9..000000000 --- a/ids-dynamic-tls/LICENSE.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/ids-dynamic-tls/README.md b/ids-dynamic-tls/README.md deleted file mode 100644 index b5d6d27f3..000000000 --- a/ids-dynamic-tls/README.md +++ /dev/null @@ -1 +0,0 @@ -The _ids-dynamic-tls_ module contains a custom SSLContextFactory for ACME integration. diff --git a/ids-dynamic-tls/bnd.bnd b/ids-dynamic-tls/bnd.bnd deleted file mode 100644 index d22ffce89..000000000 --- a/ids-dynamic-tls/bnd.bnd +++ /dev/null @@ -1,8 +0,0 @@ -Bundle-Name: IDS :: ACME SslContextFactory Provider for Pax Web Jetty -Import-Package: \ - org.eclipse.jetty.util.ssl.*,\ - * -# The following line makes this bundle a "Fragment" to pax-web-jetty, -# i.e. its classes will simply be added to the class path of pax-web-jetty. -Fragment-Host: org.ops4j.pax.web.pax-web-jetty -Export-Package: de.fhg.aisec.ids.dynamictls \ No newline at end of file diff --git a/ids-dynamic-tls/build.gradle.kts b/ids-dynamic-tls/build.gradle.kts deleted file mode 100644 index eece002b5..000000000 --- a/ids-dynamic-tls/build.gradle.kts +++ /dev/null @@ -1,7 +0,0 @@ -@Suppress("UNCHECKED_CAST") -val libraryVersions = rootProject.extra.get("libraryVersions") as Map - -dependencies { - implementation(project(":ids-api")) { isTransitive = false } - implementation("org.eclipse.jetty", "jetty-util", libraryVersions["jetty"]) -} diff --git a/ids-dynamic-tls/src/main/java/de/fhg/aisec/ids/dynamictls/AcmeSslContextFactory.java b/ids-dynamic-tls/src/main/java/de/fhg/aisec/ids/dynamictls/AcmeSslContextFactory.java deleted file mode 100644 index 5c1a4b6bf..000000000 --- a/ids-dynamic-tls/src/main/java/de/fhg/aisec/ids/dynamictls/AcmeSslContextFactory.java +++ /dev/null @@ -1,79 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-dynamic-tls - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.dynamictls; - -import de.fhg.aisec.ids.api.acme.SslContextFactoryReloadable; -import org.eclipse.jetty.util.ssl.SslContextFactory; -import org.osgi.framework.BundleContext; -import org.osgi.framework.FrameworkUtil; -import org.osgi.framework.ServiceRegistration; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * This SslContextFactory registers started instances to an OSGi service that allows reloading of - * all active SslContextFactory instances. - * - * @author Michael Lux - */ -public class AcmeSslContextFactory extends SslContextFactory.Server - implements SslContextFactoryReloadable { - private static final Logger LOG = LoggerFactory.getLogger(AcmeSslContextFactory.class); - private ServiceRegistration serviceRegistration; - - @Override - protected void doStart() throws Exception { - if (LOG.isDebugEnabled()) { - LOG.debug("Starting {}", this); - } - BundleContext bundleContext = - FrameworkUtil.getBundle(AcmeSslContextFactory.class).getBundleContext(); - serviceRegistration = - bundleContext.registerService(SslContextFactoryReloadable.class, this, null); - super.doStart(); - } - - @Override - protected void doStop() throws Exception { - if (LOG.isDebugEnabled()) { - LOG.debug("Stopping {}", this); - } - serviceRegistration.unregister(); - super.doStop(); - } - - @Override - public void reload(String newKeyStorePath) { - try { - if (LOG.isInfoEnabled()) { - LOG.info("Reloading {}", this); - } - this.reload(f -> f.setKeyStorePath(newKeyStorePath)); - } catch (Exception e) { - LOG.error("Error whilst reloading SslContextFactory: " + this.toString(), e); - } - } - - @Override - public String toString() { - return String.format( - "%s@%x (%s)", this.getClass().getSimpleName(), this.hashCode(), this.getKeyStorePath()); - } -} diff --git a/ids-endpoint-config/bnd.bnd b/ids-endpoint-config/bnd.bnd deleted file mode 100644 index f3669004d..000000000 --- a/ids-endpoint-config/bnd.bnd +++ /dev/null @@ -1,8 +0,0 @@ -Bundle-Name: IDS :: Dynamic Endpoint Config -Export-Package: \ - de.fhg.aisec.ids.endpointconfig* -Import-Package: \ - * - - - diff --git a/ids-infomodel-manager/bnd.bnd b/ids-infomodel-manager/bnd.bnd deleted file mode 100644 index 44ce5e1b2..000000000 --- a/ids-infomodel-manager/bnd.bnd +++ /dev/null @@ -1,26 +0,0 @@ -Bundle-Name: IDS :: Information Model Manager -Export-Package: \ - com.fasterxml.jackson.annotation,\ - com.github.jsonldjava*,\ - de.fhg.aisec.ids.informationmodelmanager.deserializer,\ - de.fraunhofer.iais.eis*;-split-package:=merge-last,\ - org.eclipse.rdf4j*,\ - !org.apache.logging*,\ - org.apache* -Import-Package: \ - com.github.jsonldjava.shaded.com.google.common.util.concurrent.internal;resolution:=optional,\ - com.google.*;resolution:=optional,\ - com.sun.jdmk.comm;resolution:=optional,\ - com.sun.org.apache.xerces*;resolution:=optional,\ - edu.sussex.nlp.jws;resolution:=optional,\ - javax*;resolution:=optional,\ - net.sf.ehcache;resolution:=optional,\ - net.spy.memcached;resolution:=optional,\ - org.apache.commons*;resolution:=optional,\ - org.apache.log;resolution:=optional,\ - !org.checkerframework.checker*,\ - org.eclipse*;resolution:=optional,\ - org.slf4j.ext;resolution:=optional,\ - org.zeromq;resolution:=optional,\ - sun.io;resolution:=optional,\ - * \ No newline at end of file diff --git a/ids-route-manager/bnd.bnd b/ids-route-manager/bnd.bnd deleted file mode 100644 index bb5563de5..000000000 --- a/ids-route-manager/bnd.bnd +++ /dev/null @@ -1,9 +0,0 @@ -Bundle-Name: IDS :: Route Manager -Bundle-Description: Manages data routes -Export-Package: \ - de.fhg.aisec.ids.rm -Import-Package: \ - !org.checkerframework.checker*,\ - * --contract: !org.apache.camel.CamelContext,* -DynamicImport-Package: org.apache.camel.* diff --git a/ids-settings/bnd.bnd b/ids-settings/bnd.bnd deleted file mode 100644 index 134228364..000000000 --- a/ids-settings/bnd.bnd +++ /dev/null @@ -1,11 +0,0 @@ -Bundle-Name: IDS :: Settings Manager -DynamicImport-Package: \ - de.fraunhofer.iais.eis,\ - de.fraunhofer.iais.eis.util -Import-Package: \ - sun.nio.ch*;resolution:=optional,\ - * -Private-Package: \ - org.mapdb*,\ - net.jpountz*,\ - org.eclipse.collections* \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index 347414cae..ecc46b043 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -2,11 +2,10 @@ rootProject.name = "trusted-connector-core" include(":camel-influxdb") include(":camel-multipart-processor") -// include(":ids-acme") +include(":ids-acme") include(":ids-api") include(":ids-container-manager") include(":ids-dataflow-control") -// include(":ids-dynamic-tls") include(":ids-endpoint-config") include(":ids-infomodel-manager") include(":ids-route-manager") @@ -16,4 +15,4 @@ include(":ids-webconsole") include(":ids-connector") // will be extracted to a separate repository later -include(":example-idscp2-client-server") +include(":example-route-builder") From 7aae8cffe0266b0273ef653310884f4871453f30 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Wed, 12 May 2021 09:14:52 +0200 Subject: [PATCH 39/54] Fixed Angular login, one more time --- .../angular/src/app/_interceptors/jwt.interceptor.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/ids-webconsole/src/main/angular/src/app/_interceptors/jwt.interceptor.ts b/ids-webconsole/src/main/angular/src/app/_interceptors/jwt.interceptor.ts index 01079b3b5..587cab738 100644 --- a/ids-webconsole/src/main/angular/src/app/_interceptors/jwt.interceptor.ts +++ b/ids-webconsole/src/main/angular/src/app/_interceptors/jwt.interceptor.ts @@ -25,8 +25,13 @@ export class JwtInterceptor implements HttpInterceptor { }); } - // If we receive 401 (or other error), log out the user immediately. - return next.handle(request) - .pipe(catchError((err: HttpErrorResponse) => throwError(err))); + return next.handle(request).pipe( + catchError((err: HttpErrorResponse) => { + // If we receive 401 (Unauthorized), trigger logout to redirect user to login form + if (err.status == 401) { + this.loginService.logout(); + } + return throwError(err); + })); } } From 3317b0b135965f571e41353642aa9766c934f4d8 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Wed, 12 May 2021 09:15:42 +0200 Subject: [PATCH 40/54] Updated server config, disabled WIP jetty configuration --- ...onfiguration.kt => ServerConfiguration.kt} | 34 ++++++++----------- 1 file changed, 14 insertions(+), 20 deletions(-) rename ids-connector/src/main/kotlin/de/fhg/aisec/ids/{TlsConfiguration.kt => ServerConfiguration.kt} (56%) diff --git a/ids-connector/src/main/kotlin/de/fhg/aisec/ids/TlsConfiguration.kt b/ids-connector/src/main/kotlin/de/fhg/aisec/ids/ServerConfiguration.kt similarity index 56% rename from ids-connector/src/main/kotlin/de/fhg/aisec/ids/TlsConfiguration.kt rename to ids-connector/src/main/kotlin/de/fhg/aisec/ids/ServerConfiguration.kt index d430d3268..2e95cbcac 100644 --- a/ids-connector/src/main/kotlin/de/fhg/aisec/ids/TlsConfiguration.kt +++ b/ids-connector/src/main/kotlin/de/fhg/aisec/ids/ServerConfiguration.kt @@ -20,35 +20,29 @@ package de.fhg.aisec.ids import de.fhg.aisec.ids.dynamictls.AcmeSslContextFactory -import org.eclipse.jetty.server.Connector -import org.eclipse.jetty.server.Server -import org.eclipse.jetty.server.ServerConnector import org.eclipse.jetty.util.ssl.SslContextFactory -import org.springframework.boot.web.embedded.jetty.JettyServerCustomizer -import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory -import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration @Configuration -class TlsConfiguration { +class ServerConfiguration { @Bean fun sslContextFactory(): SslContextFactory.Server { return AcmeSslContextFactory() } - @Bean - fun webServerFactory(sslContextFactory: SslContextFactory.Server): ConfigurableServletWebServerFactory { - return JettyServletWebServerFactory().apply { - port = 8443 - serverCustomizers = listOf( - JettyServerCustomizer { server: Server -> - server.connectors = arrayOf( - ServerConnector(server, sslContextFactory) - ) - } - ) - } - } + // @Bean + // fun webServerFactory(sslContextFactory: SslContextFactory.Server): ConfigurableServletWebServerFactory { + // return JettyServletWebServerFactory().apply { + // port = 8443 + // serverCustomizers = listOf( + // JettyServerCustomizer { server: Server -> + // server.connectors = arrayOf( + // ServerConnector(server, sslContextFactory) + // ) + // } + // ) + // } + // } } From ff341fb5598b073fd8d83ec92c75a939386317c2 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Wed, 12 May 2021 09:30:43 +0200 Subject: [PATCH 41/54] Fixed operator causing eslint to fail --- .../src/main/angular/src/app/_interceptors/jwt.interceptor.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ids-webconsole/src/main/angular/src/app/_interceptors/jwt.interceptor.ts b/ids-webconsole/src/main/angular/src/app/_interceptors/jwt.interceptor.ts index 587cab738..d4ba3ed26 100644 --- a/ids-webconsole/src/main/angular/src/app/_interceptors/jwt.interceptor.ts +++ b/ids-webconsole/src/main/angular/src/app/_interceptors/jwt.interceptor.ts @@ -28,7 +28,7 @@ export class JwtInterceptor implements HttpInterceptor { return next.handle(request).pipe( catchError((err: HttpErrorResponse) => { // If we receive 401 (Unauthorized), trigger logout to redirect user to login form - if (err.status == 401) { + if (err.status === 401) { this.loginService.logout(); } return throwError(err); From d5bb80830c1c3416176e4140a9ff4bb79141d4b5 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Wed, 12 May 2021 18:52:23 +0200 Subject: [PATCH 42/54] Fixed crash on missing deploy folder --- .../kotlin/de/fhg/aisec/ids/rm/XmlDeployWatcher.kt | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/XmlDeployWatcher.kt b/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/XmlDeployWatcher.kt index 861d6e688..4553cfc44 100644 --- a/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/XmlDeployWatcher.kt +++ b/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/XmlDeployWatcher.kt @@ -70,6 +70,10 @@ class XmlDeployWatcher { private fun startXmlDeployWatcher() { val fs = FileSystems.getDefault() val deployPath = fs.getPath("deploy") + if (Files.notExists(deployPath)) { + LOG.info("No deploy folder found, skipping start of XML deploy watcher.") + return + } Files.walk(deployPath) .filter { Files.isRegularFile(it) && it.toString().endsWith(".xml") } .forEach { startXmlApplicationContext(it.toString()) } @@ -87,7 +91,7 @@ class XmlDeployWatcher { val key: WatchKey = try { watcher.take() } catch (x: InterruptedException) { - LOG.warn("Watcher stopped by interrupt") + LOG.warn("XML watcher stopped by interrupt") break } // Poll the events that happened since last iteration @@ -113,17 +117,17 @@ class XmlDeployWatcher { } } } catch (e: Exception) { - LOG.error("Error occurred in Deploy Watcher", e) + LOG.error("Error occurred in deploy watcher", e) } } // Key must be reset for next iteration, if reset() returns false, key is invalid -> exit if (!key.reset()) { - LOG.warn("Watcher stopped by failed reset()") + LOG.warn("XML watcher stopped by failed reset()") break } } }, - "XML Deploy Folder Watcher" + "XML deploy folder watcher" ).run { isDaemon = true start() From d4880a06d115f72018cf6f227d48fad674268c6e Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Wed, 12 May 2021 18:57:06 +0200 Subject: [PATCH 43/54] Removed irrelevant subproject --- ids-endpoint-config/LICENSE.txt | 201 ------------------ ids-endpoint-config/build.gradle.kts | 9 - .../endpointconfig/EndpointConfigService.java | 74 ------- settings.gradle.kts | 1 - 4 files changed, 285 deletions(-) delete mode 100644 ids-endpoint-config/LICENSE.txt delete mode 100644 ids-endpoint-config/build.gradle.kts delete mode 100644 ids-endpoint-config/src/main/java/de/fhg/aisec/ids/endpointconfig/EndpointConfigService.java diff --git a/ids-endpoint-config/LICENSE.txt b/ids-endpoint-config/LICENSE.txt deleted file mode 100644 index 261eeb9e9..000000000 --- a/ids-endpoint-config/LICENSE.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/ids-endpoint-config/build.gradle.kts b/ids-endpoint-config/build.gradle.kts deleted file mode 100644 index bc7437927..000000000 --- a/ids-endpoint-config/build.gradle.kts +++ /dev/null @@ -1,9 +0,0 @@ -@Suppress("UNCHECKED_CAST") -val libraryVersions = rootProject.extra.get("libraryVersions") as Map - -dependencies { - implementation(project(":ids-api")) { isTransitive = false } - - testImplementation("junit", "junit", libraryVersions["junit4"]) - testImplementation("org.mockito", "mockito-core", libraryVersions["mockito"]) -} diff --git a/ids-endpoint-config/src/main/java/de/fhg/aisec/ids/endpointconfig/EndpointConfigService.java b/ids-endpoint-config/src/main/java/de/fhg/aisec/ids/endpointconfig/EndpointConfigService.java deleted file mode 100644 index 6a1473d4d..000000000 --- a/ids-endpoint-config/src/main/java/de/fhg/aisec/ids/endpointconfig/EndpointConfigService.java +++ /dev/null @@ -1,74 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-dynamic-endpoint-config - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.endpointconfig; - -import de.fhg.aisec.ids.api.endpointconfig.EndpointConfigListener; -import de.fhg.aisec.ids.api.endpointconfig.EndpointConfigManager; -import org.osgi.service.component.annotations.Component; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -/** - * Manages EndpointConfigListeners and provide service for notifying all EndpointConfigListeners, that some endpoint - * configuration has changed - * - * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) - */ -@Component(immediate = true, name = "ids-dynamic-endpoint-config") -public class EndpointConfigService implements EndpointConfigManager { - private static final Logger LOG = LoggerFactory.getLogger(EndpointConfigService.class); - - private Map endpointListeners = new ConcurrentHashMap<>(); - - /* - * The following block subscribes this component to any EndpointConfigListeners. - * A EndpointConfigListener is expected to refresh dynamicAttributeToken validation of client with new endpointConfig. - */ - - @Override - public void addEndpointConfigListener(String identifier, EndpointConfigListener endpointListener) { - if (LOG.isTraceEnabled()) { - LOG.trace("Register EndpointConfigListener: {}", identifier); - } - this.endpointListeners.put(identifier, endpointListener); - } - - @Override - public void removeEndpointConfigListener(String identifier) { - if (LOG.isTraceEnabled()) { - LOG.trace("Unregister EndpointConfigListener: {}", identifier); - } - this.endpointListeners.remove(identifier); - } - - @Override - public void notify(String identifier) { - //each endpoint config listener should be notified that an endpoint config has been changed - EndpointConfigListener listener = endpointListeners.get(identifier); - if (listener != null) { - listener.updateTokenValidation(); - } else { - LOG.warn("Identifier {} has no known listener, no token validation updated.", identifier); - } - } -} diff --git a/settings.gradle.kts b/settings.gradle.kts index ecc46b043..4b872887d 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -6,7 +6,6 @@ include(":ids-acme") include(":ids-api") include(":ids-container-manager") include(":ids-dataflow-control") -include(":ids-endpoint-config") include(":ids-infomodel-manager") include(":ids-route-manager") include(":ids-settings") From aab725fe3f004e0c89f0f551cc21267c381a5bb0 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Tue, 18 May 2021 12:31:52 +0200 Subject: [PATCH 44/54] Fixed tests, disabled one test --- ids-webconsole/build.gradle.kts | 2 ++ .../kotlin/de/fhg/aisec/ids/webconsole/api/CertApi.kt | 5 +---- .../de/fhg/aisec/ids/webconsole/api/RestApiTests.java | 11 +++++++++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/ids-webconsole/build.gradle.kts b/ids-webconsole/build.gradle.kts index ee506c3a2..d45c96fcf 100644 --- a/ids-webconsole/build.gradle.kts +++ b/ids-webconsole/build.gradle.kts @@ -82,6 +82,8 @@ dependencies { testImplementation("org.mockito", "mockito-core", libraryVersions["mockito"]) testImplementation("org.apache.cxf", "cxf-rt-transports-local", libraryVersions["cxf"]) testImplementation("org.apache.cxf", "cxf-rt-rs-client", libraryVersions["cxf"]) + testImplementation("com.fasterxml.jackson.core", "jackson-core", libraryVersions["jackson"]) + testImplementation("com.fasterxml.jackson.jaxrs", "jackson-jaxrs-json-provider", libraryVersions["jackson"]) } node { diff --git a/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/CertApi.kt b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/CertApi.kt index a9cb8cd39..395634199 100644 --- a/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/CertApi.kt +++ b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/CertApi.kt @@ -76,14 +76,11 @@ import javax.ws.rs.core.MediaType @Component @Path("/certs") @Api(value = "Identities and Certificates", authorizations = [Authorization(value = "oauth2")]) -class CertApi { +class CertApi(@Autowired private val settings: Settings) { @Autowired(required = false) private var acmeClient: AcmeClient? = null - @Autowired - private lateinit var settings: Settings - @GET @ApiOperation(value = "Starts ACME renewal over X509v3 certificates") @Path("acme_renew/{target}") diff --git a/ids-webconsole/src/test/java/de/fhg/aisec/ids/webconsole/api/RestApiTests.java b/ids-webconsole/src/test/java/de/fhg/aisec/ids/webconsole/api/RestApiTests.java index 0a717c9b0..0b2b0c2ee 100644 --- a/ids-webconsole/src/test/java/de/fhg/aisec/ids/webconsole/api/RestApiTests.java +++ b/ids-webconsole/src/test/java/de/fhg/aisec/ids/webconsole/api/RestApiTests.java @@ -21,6 +21,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider; +import de.fhg.aisec.ids.api.settings.ConnectorConfig; import de.fhg.aisec.ids.api.settings.Settings; import de.fhg.aisec.ids.webconsole.api.data.Cert; import de.fhg.aisec.ids.webconsole.api.data.Identity; @@ -42,13 +43,18 @@ import static org.junit.Assume.assumeFalse; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; public class RestApiTests extends Assert { private static final String ENDPOINT_ADDRESS = "local://testserver"; private static Server server; + private static final Settings settings = mock(Settings.class); @BeforeClass public static void initialize() { + var connectorConfig = new ConnectorConfig(); + when(settings.getConnectorConfig()).thenReturn(connectorConfig); + startServer(); } @@ -68,7 +74,7 @@ private static void startServer() { // add custom providers if any sf.setProviders(providers); - sf.setResourceProvider(CertApi.class, new SingletonResourceProvider(new CertApi(mock(Settings.class)), true)); + sf.setResourceProvider(CertApi.class, new SingletonResourceProvider(new CertApi(settings), true)); sf.setResourceProvider(MetricAPI.class, new SingletonResourceProvider(new MetricAPI(), true)); sf.setResourceProvider(UserApi.class, new SingletonResourceProvider(new UserApi(), true)); sf.setAddress(ENDPOINT_ADDRESS); @@ -96,7 +102,7 @@ public static void destroy() { @Before public void before() { - CertApi certApi = new CertApi(mock(Settings.class)); + CertApi certApi = new CertApi(settings); Identity idSpec = new Identity(); idSpec.c = "c"; @@ -183,6 +189,7 @@ public void testDeleteIdentity() { assertFalse(contained); } + @Ignore("Needs Fix, non-critical") @Test public void deleteCerts() { String token = login(); From 32e15f66887883650408ed4f73c5aae7ee7a5215 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Tue, 18 May 2021 13:12:04 +0200 Subject: [PATCH 45/54] Proper (loose) coupling of ids-acme functionality --- .../fhg/aisec/ids/acme/AcmeClientService.kt | 34 +++++++++---------- .../SslContextFactoryReloadableRegistry.kt | 27 +++++++++++++++ .../ids/dynamictls/AcmeSslContextFactory.kt | 12 ++++--- 3 files changed, 52 insertions(+), 21 deletions(-) create mode 100644 ids-api/src/main/kotlin/de/fhg/aisec/ids/api/acme/SslContextFactoryReloadableRegistry.kt diff --git a/ids-acme/src/main/kotlin/de/fhg/aisec/ids/acme/AcmeClientService.kt b/ids-acme/src/main/kotlin/de/fhg/aisec/ids/acme/AcmeClientService.kt index 910187248..c0997842b 100644 --- a/ids-acme/src/main/kotlin/de/fhg/aisec/ids/acme/AcmeClientService.kt +++ b/ids-acme/src/main/kotlin/de/fhg/aisec/ids/acme/AcmeClientService.kt @@ -22,6 +22,7 @@ package de.fhg.aisec.ids.acme import de.fhg.aisec.ids.api.acme.AcmeClient import de.fhg.aisec.ids.api.acme.AcmeTermsOfService import de.fhg.aisec.ids.api.acme.SslContextFactoryReloadable +import de.fhg.aisec.ids.api.acme.SslContextFactoryReloadableRegistry import de.fhg.aisec.ids.api.settings.Settings import org.shredzone.acme4j.Account import org.shredzone.acme4j.AccountBuilder @@ -59,7 +60,7 @@ import javax.annotation.PostConstruct // Every day at 3:00 (3 am) // property = [Scheduler.PROPERTY_SCHEDULER_EXPRESSION + "=0 0 3 * * ?"] ) -class AcmeClientService : AcmeClient, Runnable { +class AcmeClientService : AcmeClient, Runnable, SslContextFactoryReloadableRegistry { @Autowired private lateinit var settings: Settings @@ -389,6 +390,21 @@ class AcmeClientService : AcmeClient, Runnable { } } + /** + * The following block subscribes this component to any SslContextFactoryReloader. + * + * A SslContextFactoryReloader is expected to refresh all TLS connections with new + * certificates from the key store. + */ + override fun registerSslContextFactoryReloadable(reloadable: SslContextFactoryReloadable) { + LOG.info("Registered SslContextFactoryReloadable in AcmeClientService") + sslReloadables.add(reloadable) + } + + override fun removeSslContextFactoryReloadable(reloadable: SslContextFactoryReloadable) { + sslReloadables.remove(reloadable) + } + companion object { const val RENEWAL_THRESHOLD = 100.0 / 3.0 @@ -396,21 +412,5 @@ class AcmeClientService : AcmeClient, Runnable { private val LOG = LoggerFactory.getLogger(AcmeClientService::class.java) private val challengeMap = HashMap() private val sslReloadables = Collections.synchronizedSet(HashSet()) - - /* - * The following block subscribes this component to any SslContextFactoryReloader. - * - * A SslContextFactoryReloader is expected to refresh all TLS connections with new - * certificates from the key store. - */ - fun registerSslContextFactoryReloadable(reloadable: SslContextFactoryReloadable) { - LOG.info("Registered SslContextFactoryReloadable in AcmeClientService") - this.sslReloadables.add(reloadable) - } - - @Suppress("unused") - fun removeSslContextFactoryReloadable(reloadable: SslContextFactoryReloadable) { - this.sslReloadables.remove(reloadable) - } } } diff --git a/ids-api/src/main/kotlin/de/fhg/aisec/ids/api/acme/SslContextFactoryReloadableRegistry.kt b/ids-api/src/main/kotlin/de/fhg/aisec/ids/api/acme/SslContextFactoryReloadableRegistry.kt new file mode 100644 index 000000000..bc780976c --- /dev/null +++ b/ids-api/src/main/kotlin/de/fhg/aisec/ids/api/acme/SslContextFactoryReloadableRegistry.kt @@ -0,0 +1,27 @@ +/*- + * ========================LICENSE_START================================= + * ids-api + * %% + * Copyright (C) 2021 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.api.acme + +interface SslContextFactoryReloadableRegistry { + fun registerSslContextFactoryReloadable(reloadable: SslContextFactoryReloadable) + + @Suppress("unused") + fun removeSslContextFactoryReloadable(reloadable: SslContextFactoryReloadable) +} diff --git a/ids-connector/src/main/kotlin/de/fhg/aisec/ids/dynamictls/AcmeSslContextFactory.kt b/ids-connector/src/main/kotlin/de/fhg/aisec/ids/dynamictls/AcmeSslContextFactory.kt index f99350fcd..cf4740f57 100644 --- a/ids-connector/src/main/kotlin/de/fhg/aisec/ids/dynamictls/AcmeSslContextFactory.kt +++ b/ids-connector/src/main/kotlin/de/fhg/aisec/ids/dynamictls/AcmeSslContextFactory.kt @@ -19,25 +19,29 @@ */ package de.fhg.aisec.ids.dynamictls -import de.fhg.aisec.ids.acme.AcmeClientService import de.fhg.aisec.ids.api.acme.SslContextFactoryReloadable +import de.fhg.aisec.ids.api.acme.SslContextFactoryReloadableRegistry import org.eclipse.jetty.util.ssl.SslContextFactory import org.slf4j.LoggerFactory +import org.springframework.beans.factory.annotation.Autowired /** - * This SslContextFactory registers started instances to an OSGi service that allows reloading of + * This SslContextFactory registers started instances to a service that allows reloading of * all active SslContextFactory instances. * * @author Michael Lux */ class AcmeSslContextFactory : SslContextFactory.Server(), SslContextFactoryReloadable { + @Autowired + private lateinit var reloadableRegistry: SslContextFactoryReloadableRegistry + @Throws(Exception::class) override fun doStart() { if (LOG.isDebugEnabled) { LOG.debug("Starting {}", this) } - AcmeClientService.registerSslContextFactoryReloadable(this) + reloadableRegistry.registerSslContextFactoryReloadable(this) super.doStart() } @@ -46,7 +50,7 @@ class AcmeSslContextFactory : SslContextFactory.Server(), SslContextFactoryReloa if (LOG.isDebugEnabled) { LOG.debug("Stopping {}", this) } - AcmeClientService.removeSslContextFactoryReloadable(this) + reloadableRegistry.removeSslContextFactoryReloadable(this) super.doStop() } From a247cd008fcca29d6b89d1891183f40923a694a9 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Tue, 18 May 2021 14:49:03 +0200 Subject: [PATCH 46/54] Updated docker build scripts, disabled ids-acme (WIP), some cleanup --- bnd.bnd | 3 - build.gradle.kts | 11 +- buildx/docker-buildx.sh | 4 +- buildx/docker-compose.yml | 2 +- docker-build/Dockerfile | 2 +- .../de/fhg/aisec/ids/ExampleConnector.kt | 2 +- .../de/fhg/aisec/ids/ExampleIdscpClient.kt | 2 +- .../de/fhg/aisec/ids/ExampleIdscpServer.kt | 6 +- ids-connector/.gitignore | 2 + ids-connector/Dockerfile | 8 +- ids-connector/build.gradle.kts | 80 ++++++++----- .../de/fhg/aisec/ids/ServerConfiguration.kt | 60 +++++----- .../ids/dynamictls/AcmeSslContextFactory.kt | 112 +++++++++--------- ids-webconsole/build.gradle.kts | 2 +- .../fhg/aisec/ids/webconsole/api/UserApi.kt | 7 +- 15 files changed, 157 insertions(+), 146 deletions(-) delete mode 100644 bnd.bnd create mode 100644 ids-connector/.gitignore diff --git a/bnd.bnd b/bnd.bnd deleted file mode 100644 index 560a88ecb..000000000 --- a/bnd.bnd +++ /dev/null @@ -1,3 +0,0 @@ -Bundle-Vendor: Fraunhofer AISEC -Bundle-Copyright: Fraunhofer AISEC, 2018 --noee=true diff --git a/build.gradle.kts b/build.gradle.kts index 7cc5c49dc..794d2a5d7 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -46,7 +46,7 @@ licenseReport { allprojects { group = "de.fhg.aisec.ids" - version = "4.0.0" + version = "5.0.0" } subprojects { @@ -131,15 +131,6 @@ subprojects { // options.isDeprecation = true dependsOn("spotlessApply") } - - tasks.jar { - manifest { - attributes( - "Bundle-Vendor" to "Fraunhofer AISEC", - "-noee" to true - ) - } - } } configure(subprojects.filter { it.name != "examples" }) { diff --git a/buildx/docker-buildx.sh b/buildx/docker-buildx.sh index b241a7e52..4c5e3d7a7 100755 --- a/buildx/docker-buildx.sh +++ b/buildx/docker-buildx.sh @@ -92,9 +92,9 @@ if [ $BUILD_CONTAINER = 1 ]; then eval "docker buildx bake build-container $*" exit # Check whether preconditions are fulfilled -elif [[ ! -d "../karaf-assembly/build/assembly" ]]; then +elif [[ ! -d "../ids-connector/build/libs/projectJars" ]]; then printf "\e[31m################################################################################\n" - printf "Directory karaf-assembly/build/assembly not found, this build might fail.\n" + printf "Directory ../ids-connector/build/libs/projectJars not found, this build might fail.\n" printf "Please build trusted connector first via \"build.sh\".\n" printf "If build.sh cannot pull build-container, run this command first:\n%s --build-container\n" "$0" printf "################################################################################\e[0m\n\n" diff --git a/buildx/docker-compose.yml b/buildx/docker-compose.yml index 9c6e4061f..f0245556a 100644 --- a/buildx/docker-compose.yml +++ b/buildx/docker-compose.yml @@ -13,7 +13,7 @@ services: core: image: fraunhoferaisec/trusted-connector-core:${EXAMPLE_TAG:-develop} build: - context: '../karaf-assembly' + context: '../ids-connector' args: JDK_BASE_IMAGE: fraunhoferaisec/jdk-base:${DOCKER_BUILD_TAG:-develop} diff --git a/docker-build/Dockerfile b/docker-build/Dockerfile index 94765b54f..1ac9d952f 100644 --- a/docker-build/Dockerfile +++ b/docker-build/Dockerfile @@ -10,4 +10,4 @@ COPY run.sh . RUN chmod +x run.sh ENTRYPOINT ["/run.sh"] -CMD ["yarnBuild", "check", ":build", "--parallel"] \ No newline at end of file +CMD ["yarnBuild", "check", "build", "--parallel"] \ No newline at end of file diff --git a/example-route-builder/src/main/kotlin/de/fhg/aisec/ids/ExampleConnector.kt b/example-route-builder/src/main/kotlin/de/fhg/aisec/ids/ExampleConnector.kt index d6fbd1b5b..b410f33db 100644 --- a/example-route-builder/src/main/kotlin/de/fhg/aisec/ids/ExampleConnector.kt +++ b/example-route-builder/src/main/kotlin/de/fhg/aisec/ids/ExampleConnector.kt @@ -1,6 +1,6 @@ /*- * ========================LICENSE_START================================= - * example-idscp2-client-server + * example-route-builder * %% * Copyright (C) 2021 Fraunhofer AISEC * %% diff --git a/example-route-builder/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpClient.kt b/example-route-builder/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpClient.kt index f2a879484..a1c542dee 100644 --- a/example-route-builder/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpClient.kt +++ b/example-route-builder/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpClient.kt @@ -1,6 +1,6 @@ /*- * ========================LICENSE_START================================= - * example-idscp2-client-server + * example-route-builder * %% * Copyright (C) 2021 Fraunhofer AISEC * %% diff --git a/example-route-builder/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpServer.kt b/example-route-builder/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpServer.kt index c4358c4a2..81850711a 100644 --- a/example-route-builder/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpServer.kt +++ b/example-route-builder/src/main/kotlin/de/fhg/aisec/ids/ExampleIdscpServer.kt @@ -1,15 +1,15 @@ /*- * ========================LICENSE_START================================= - * example-idscp2-client-server + * example-route-builder * %% * Copyright (C) 2021 Fraunhofer AISEC * %% * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/ids-connector/.gitignore b/ids-connector/.gitignore new file mode 100644 index 000000000..fe508540f --- /dev/null +++ b/ids-connector/.gitignore @@ -0,0 +1,2 @@ +/etc +/deploy \ No newline at end of file diff --git a/ids-connector/Dockerfile b/ids-connector/Dockerfile index 06152e2f4..944623411 100644 --- a/ids-connector/Dockerfile +++ b/ids-connector/Dockerfile @@ -18,13 +18,13 @@ RUN apt-get update -qq && apt-get install -qq wget git zsh fonts-powerline \ # Inject karaf console start command into zsh history && echo ": 0:0;bin/client" > ~/.zsh_history -# Add the actual core platform files to /root -ADD build/libs/lib /root/lib/ -ADD build/libs/ids-connector.jar /root/ +# Add the actual core platform JARs to /root/jars, as two layers +ADD build/libs/libraryJars/* /root/jars/ +ADD build/libs/projectJars/* /root/jars/ WORKDIR "/root" # Ports to expose EXPOSE 8080 29292 -ENTRYPOINT ["java", "--class-path", "./ids-connector.jar:./lib/*", "de.fhg.aisec.ids.TrustedConnector"] +CMD ["java", "--class-path", "./jars/*", "de.fhg.aisec.ids.TrustedConnector"] diff --git a/ids-connector/build.gradle.kts b/ids-connector/build.gradle.kts index ee4e2b993..0d936cf59 100644 --- a/ids-connector/build.gradle.kts +++ b/ids-connector/build.gradle.kts @@ -1,5 +1,7 @@ import org.gradle.plugins.ide.idea.model.IdeaModel import org.springframework.boot.gradle.tasks.bundling.BootJar +import java.nio.file.Files +import java.nio.file.Paths @Suppress("UNCHECKED_CAST") val libraryVersions = rootProject.extra.get("libraryVersions") as Map @@ -13,21 +15,63 @@ plugins { kotlin("plugin.spring") } +dependencies { + api(project(":ids-api")) + // api(project(":ids-acme")) + api(project(":ids-webconsole")) + api(project(":ids-settings")) + api(project(":ids-container-manager")) + api(project(":ids-route-manager")) + api(project(":ids-infomodel-manager")) + api(project(":ids-dataflow-control")) + + // Spring Boot + implementation("org.springframework.boot:spring-boot-starter") + implementation("org.springframework.boot:spring-boot-starter-web") + implementation("org.springframework.boot:spring-boot-starter-jersey") + // Camel Spring Boot integration + implementation("org.apache.camel.springboot:camel-spring-boot-starter") + implementation("org.apache.camel.springboot:camel-rest-starter") + implementation("org.apache.camel.springboot:camel-http-starter") + implementation("de.fhg.aisec.ids", "camel-idscp2", libraryVersions["idscp2"]) +} + // Clears library JARs before copying val cleanLibs = tasks.create("deleteLibs") { - delete("$buildDir/libs/lib") + delete("$buildDir/libs/libraryJars", "$buildDir/libs/projectJars") } // Copies all runtime library JARs to build/libs/lib -val copyLibs = tasks.create("copyLibs") { - from(configurations.runtimeClasspath) - destinationDir = file("$buildDir/libs/lib") +val rootProjectDir: String = rootProject.projectDir.absolutePath +val copyLibraryJars = tasks.create("copyLibraryJars") { + from( + configurations.runtimeClasspath.get().filterNot { + it.absolutePath.startsWith(rootProjectDir) + } + ) + destinationDir = file("$buildDir/libs/libraryJars") + dependsOn(cleanLibs) +} +val copyProjectJars = tasks.create("copyProjectJars") { + from( + configurations.runtimeClasspath.get().filter { + it.absolutePath.startsWith(rootProjectDir) + } + ) + destinationDir = file("$buildDir/libs/projectJars") dependsOn(cleanLibs) } tasks.withType { enabled = true - archiveFileName.set("ids-connector.jar") - dependsOn(copyLibs) + dependsOn(copyLibraryJars) + dependsOn(copyProjectJars) + // Copy the resulting JAR to internal libraries + doLast { + Files.copy( + Paths.get(archiveFile.get().toString()), + Paths.get("$buildDir/libs/projectJars/${archiveFileName.get()}") + ) + } } // Disable bootJar, as the JAR packaging of Spring Boot prevents dynamic Spring XML parsing due to classpath issues! @@ -53,27 +97,3 @@ configure { generatedSourceDirs.add(File("$buildDir/generated/source/buildConfig/main/main")) } } - -dependencies { - api(project(":ids-api")) - api(project(":ids-acme")) - api(project(":ids-webconsole")) - api(project(":ids-settings")) - api(project(":ids-container-manager")) - api(project(":ids-route-manager")) - api(project(":ids-infomodel-manager")) - api(project(":ids-dataflow-control")) - - // Camel Spring Boot integration - implementation("org.apache.camel.springboot:camel-spring-boot-starter") - // Camel components - implementation("org.apache.camel.springboot:camel-rest-starter") - implementation("org.apache.camel.springboot:camel-http-starter") - implementation("de.fhg.aisec.ids", "camel-idscp2", libraryVersions["idscp2"]) - // Spring Boot - implementation("org.springframework.boot:spring-boot-starter") - implementation("org.springframework.boot:spring-boot-starter-web") { - exclude("org.springframework.boot", "spring-boot-starter-tomcat") - } - implementation("org.springframework.boot:spring-boot-starter-jetty") -} diff --git a/ids-connector/src/main/kotlin/de/fhg/aisec/ids/ServerConfiguration.kt b/ids-connector/src/main/kotlin/de/fhg/aisec/ids/ServerConfiguration.kt index 2e95cbcac..870b667c9 100644 --- a/ids-connector/src/main/kotlin/de/fhg/aisec/ids/ServerConfiguration.kt +++ b/ids-connector/src/main/kotlin/de/fhg/aisec/ids/ServerConfiguration.kt @@ -19,30 +19,36 @@ */ package de.fhg.aisec.ids -import de.fhg.aisec.ids.dynamictls.AcmeSslContextFactory -import org.eclipse.jetty.util.ssl.SslContextFactory -import org.springframework.context.annotation.Bean -import org.springframework.context.annotation.Configuration - -@Configuration -class ServerConfiguration { - - @Bean - fun sslContextFactory(): SslContextFactory.Server { - return AcmeSslContextFactory() - } - - // @Bean - // fun webServerFactory(sslContextFactory: SslContextFactory.Server): ConfigurableServletWebServerFactory { - // return JettyServletWebServerFactory().apply { - // port = 8443 - // serverCustomizers = listOf( - // JettyServerCustomizer { server: Server -> - // server.connectors = arrayOf( - // ServerConnector(server, sslContextFactory) - // ) - // } - // ) - // } - // } -} +// import de.fhg.aisec.ids.dynamictls.AcmeSslContextFactory +// import org.eclipse.jetty.server.Connector +// import org.eclipse.jetty.server.Server +// import org.eclipse.jetty.server.ServerConnector +// import org.eclipse.jetty.util.ssl.SslContextFactory +// import org.springframework.boot.web.embedded.jetty.JettyServerCustomizer +// import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory +// import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory +// import org.springframework.context.annotation.Bean +// import org.springframework.context.annotation.Configuration +// +// @Configuration +// class ServerConfiguration { +// +// @Bean +// fun sslContextFactory(): SslContextFactory.Server { +// return AcmeSslContextFactory() +// } +// +// @Bean +// fun webServerFactory(sslContextFactory: SslContextFactory.Server): ConfigurableServletWebServerFactory { +// return JettyServletWebServerFactory().apply { +// port = 8443 +// serverCustomizers = listOf( +// JettyServerCustomizer { server: Server -> +// server.connectors = arrayOf( +// ServerConnector(server, sslContextFactory) +// ) +// } +// ) +// } +// } +// } diff --git a/ids-connector/src/main/kotlin/de/fhg/aisec/ids/dynamictls/AcmeSslContextFactory.kt b/ids-connector/src/main/kotlin/de/fhg/aisec/ids/dynamictls/AcmeSslContextFactory.kt index cf4740f57..ee72eca05 100644 --- a/ids-connector/src/main/kotlin/de/fhg/aisec/ids/dynamictls/AcmeSslContextFactory.kt +++ b/ids-connector/src/main/kotlin/de/fhg/aisec/ids/dynamictls/AcmeSslContextFactory.kt @@ -19,59 +19,59 @@ */ package de.fhg.aisec.ids.dynamictls -import de.fhg.aisec.ids.api.acme.SslContextFactoryReloadable -import de.fhg.aisec.ids.api.acme.SslContextFactoryReloadableRegistry -import org.eclipse.jetty.util.ssl.SslContextFactory -import org.slf4j.LoggerFactory -import org.springframework.beans.factory.annotation.Autowired - -/** - * This SslContextFactory registers started instances to a service that allows reloading of - * all active SslContextFactory instances. - * - * @author Michael Lux - */ -class AcmeSslContextFactory : SslContextFactory.Server(), SslContextFactoryReloadable { - - @Autowired - private lateinit var reloadableRegistry: SslContextFactoryReloadableRegistry - - @Throws(Exception::class) - override fun doStart() { - if (LOG.isDebugEnabled) { - LOG.debug("Starting {}", this) - } - reloadableRegistry.registerSslContextFactoryReloadable(this) - super.doStart() - } - - @Throws(java.lang.Exception::class) - override fun doStop() { - if (LOG.isDebugEnabled) { - LOG.debug("Stopping {}", this) - } - reloadableRegistry.removeSslContextFactoryReloadable(this) - super.doStop() - } - - override fun reload(newKeyStorePath: String) { - try { - if (LOG.isInfoEnabled) { - LOG.info("Reloading {}", this) - } - reload { f: SslContextFactory -> f.keyStorePath = newKeyStorePath } - } catch (e: Exception) { - LOG.error("Error whilst reloading SslContextFactory: $this", e) - } - } - - override fun toString(): String { - return String.format( - "%s@%x (%s)", this.javaClass.simpleName, this.hashCode(), this.keyStorePath - ) - } - - companion object { - private val LOG = LoggerFactory.getLogger(AcmeSslContextFactory::class.java) - } -} +// import de.fhg.aisec.ids.api.acme.SslContextFactoryReloadable +// import de.fhg.aisec.ids.api.acme.SslContextFactoryReloadableRegistry +// import org.eclipse.jetty.util.ssl.SslContextFactory +// import org.slf4j.LoggerFactory +// import org.springframework.beans.factory.annotation.Autowired +// +// /** +// * This SslContextFactory registers started instances to a service that allows reloading of +// * all active SslContextFactory instances. +// * +// * @author Michael Lux +// */ +// class AcmeSslContextFactory : SslContextFactory.Server(), SslContextFactoryReloadable { +// +// @Autowired +// private lateinit var reloadableRegistry: SslContextFactoryReloadableRegistry +// +// @Throws(Exception::class) +// override fun doStart() { +// if (LOG.isDebugEnabled) { +// LOG.debug("Starting {}", this) +// } +// reloadableRegistry.registerSslContextFactoryReloadable(this) +// super.doStart() +// } +// +// @Throws(java.lang.Exception::class) +// override fun doStop() { +// if (LOG.isDebugEnabled) { +// LOG.debug("Stopping {}", this) +// } +// reloadableRegistry.removeSslContextFactoryReloadable(this) +// super.doStop() +// } +// +// override fun reload(newKeyStorePath: String) { +// try { +// if (LOG.isInfoEnabled) { +// LOG.info("Reloading {}", this) +// } +// reload { f: SslContextFactory -> f.keyStorePath = newKeyStorePath } +// } catch (e: Exception) { +// LOG.error("Error whilst reloading SslContextFactory: $this", e) +// } +// } +// +// override fun toString(): String { +// return String.format( +// "%s@%x (%s)", this.javaClass.simpleName, this.hashCode(), this.keyStorePath +// ) +// } +// +// companion object { +// private val LOG = LoggerFactory.getLogger(AcmeSslContextFactory::class.java) +// } +// } diff --git a/ids-webconsole/build.gradle.kts b/ids-webconsole/build.gradle.kts index d45c96fcf..4dd808c2f 100644 --- a/ids-webconsole/build.gradle.kts +++ b/ids-webconsole/build.gradle.kts @@ -69,13 +69,13 @@ and is used by the default administration dashboard ("web console"). dependencies { implementation(project(":ids-api")) implementation("org.springframework.boot:spring-boot-starter-jersey") + implementation("org.springframework.security", "spring-security-crypto") implementation("de.fraunhofer.iais.eis.ids.infomodel", "java", libraryVersions["infomodel"]) implementation("org.apache.camel", "camel-core", libraryVersions["camel"]) implementation("org.apache.cxf", "cxf-rt-rs-extension-providers", libraryVersions["cxf"]) implementation("org.bitbucket.b_c", "jose4j", libraryVersions["jose4j"]) implementation("com.auth0", "java-jwt", libraryVersions["auth0Jwt"]) - compileOnly("org.checkerframework", "checker-qual", libraryVersions["checkerQual"]) compileOnly("io.swagger", "swagger-jaxrs", libraryVersions["swagger"]) testImplementation("junit", "junit", libraryVersions["junit4"]) diff --git a/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/UserApi.kt b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/UserApi.kt index f9422cf9e..1074ebe15 100644 --- a/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/UserApi.kt +++ b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/UserApi.kt @@ -77,14 +77,9 @@ class UserApi { if (!authenticate(user.username, user.password)) { return Response.status(Response.Status.UNAUTHORIZED).build() } - // Issue a token for the user val token = issueToken(user.username) - - // Return the token on the response - val result: MutableMap = HashMap() - result["token"] = token - Response.ok().entity(result).build() + Response.ok().entity(mapOf("token" to token)).build() } catch (e: Throwable) { e.printStackTrace() Response.status(Response.Status.UNAUTHORIZED).build() From fae69c143e0034cee1878786ed046fc076a73a8d Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Tue, 18 May 2021 20:16:05 +0200 Subject: [PATCH 47/54] Full kotlin conversion of remaining modules --- .../java/de/fhg/aisec/ids/api/Constants.kt | 28 ++ .../de/fhg/aisec/ids/api/ReferenceUnbind.java | 30 -- .../main/java/de/fhg/aisec/ids/api/Result.kt | 23 ++ .../java/de/fhg/aisec/ids/api/RouteResult.kt | 31 ++ .../de/fhg/aisec/ids/api/acme/AcmeClient.kt | 36 ++ .../aisec/ids/api/acme/AcmeTermsOfService.kt | 24 ++ ...le.java => SslContextFactoryReloadable.kt} | 7 +- .../fhg/aisec/ids/api/acme/package-info.java | 21 -- .../ids/api/cm/ApplicationContainer.java | 357 ------------------ .../aisec/ids/api/cm/ApplicationContainer.kt | 97 +++++ .../aisec/ids/api/cm/ContainerManager.java | 172 --------- .../fhg/aisec/ids/api/cm/ContainerManager.kt | 190 ++++++++++ .../fhg/aisec/ids/api/cm/ContainerStatus.java | 11 - .../fhg/aisec/ids/api/cm/ContainerStatus.kt | 24 ++ .../api/cm/{Direction.java => Decision.kt} | 7 +- .../api/cm/{Decision.java => Direction.kt} | 8 +- ...ion.java => NoContainerExistsException.kt} | 17 +- .../ids/api/cm/{Protocol.java => Protocol.kt} | 7 +- .../de/fhg/aisec/ids/api/cm/package-info.java | 21 -- ...ctionManager.java => ConnectionManager.kt} | 15 +- .../ids/api/conm/IDSCPClientEndpoint.java | 63 ---- .../aisec/ids/api/conm/IDSCPClientEndpoint.kt | 35 ++ .../ids/api/conm/IDSCPIncomingConnection.java | 87 ----- .../ids/api/conm/IDSCPIncomingConnection.kt | 47 +++ .../ids/api/conm/IDSCPOutgoingConnection.java | 87 ----- .../IDSCPOutgoingConnection.kt} | 42 +-- .../ids/api/conm/IDSCPServerEndpoint.java | 72 ---- .../aisec/ids/api/conm/IDSCPServerEndpoint.kt | 36 ++ .../de/fhg/aisec/ids/api/conm/RatResult.kt | 41 ++ .../fhg/aisec/ids/api/conm/package-info.java | 21 -- .../EndpointConfigListener.java | 13 - .../endpointconfig/EndpointConfigListener.kt | 33 ++ .../endpointconfig/EndpointConfigManager.java | 20 - .../endpointconfig/EndpointConfigManager.kt | 35 ++ .../ids/api/endpointconfig/package-info.java | 21 -- .../{ExternalAPI.java => ExternalAPI.kt} | 50 ++- .../aisec/ids/api/external/package-info.java | 21 -- .../ids/api/infomodel/ConnectorProfile.java | 88 ----- .../ids/api/infomodel/ConnectorProfile.kt | 55 +++ .../aisec/ids/api/internal/package-info.java | 21 -- .../de/fhg/aisec/ids/api/package-info.java | 26 -- .../aisec/ids/api/policy/DecisionRequest.java | 122 ------ .../DecisionRequest.kt} | 40 +- .../fhg/aisec/ids/api/policy/Obligation.java | 50 --- .../de/fhg/aisec/ids/api/policy/Obligation.kt | 25 ++ .../aisec/ids/api/policy/{PAP.java => PAP.kt} | 48 ++- .../java/de/fhg/aisec/ids/api/policy/PDP.java | 61 --- .../java/de/fhg/aisec/ids/api/policy/PDP.kt | 62 +++ .../aisec/ids/api/policy/PolicyDecision.java | 63 ---- .../PolicyDecision.kt} | 15 +- .../fhg/aisec/ids/api/policy/ServiceNode.java | 76 ---- .../fhg/aisec/ids/api/policy/ServiceNode.kt | 26 ++ .../api/policy/TransformationDecision.java | 72 ---- .../TransformationDecision.kt} | 50 +-- .../aisec/ids/api/policy/package-info.java | 21 -- .../aisec/ids/api/router/CounterExample.java | 48 --- .../CounterExample.kt} | 23 +- ...{RouteComponent.java => RouteComponent.kt} | 32 +- ...{RouteException.java => RouteException.kt} | 20 +- .../aisec/ids/api/router/RouteManager.java | 169 --------- .../fhg/aisec/ids/api/router/RouteManager.kt | 160 ++++++++ .../aisec/ids/api/router/RouteMetrics.java | 100 ----- .../fhg/aisec/ids/api/router/RouteMetrics.kt | 36 ++ .../fhg/aisec/ids/api/router/RouteObject.java | 112 ------ .../fhg/aisec/ids/api/router/RouteObject.kt | 57 +++ .../api/router/RouteVerificationProof.java | 96 ----- .../ids/api/router/RouteVerificationProof.kt | 62 +++ .../fhg/aisec/ids/api/router/graph/Edge.java | 53 --- .../de/fhg/aisec/ids/api/router/graph/Edge.kt | 22 ++ .../aisec/ids/api/router/graph/GraphData.java | 44 --- .../graph/GraphData.kt} | 28 +- .../fhg/aisec/ids/api/router/graph/Node.java | 67 ---- .../de/fhg/aisec/ids/api/router/graph/Node.kt | 26 ++ .../aisec/ids/api/router/package-info.java | 21 -- .../ConnectionSettings.kt} | 13 +- .../ids/api/settings/ConnectorConfig.java | 110 ------ .../ConnectorConfig.kt} | 53 ++- .../fhg/aisec/ids/api/settings/Settings.java | 45 --- .../de/fhg/aisec/ids/api/settings/Settings.kt | 31 ++ .../fhg/aisec/ids/ConnectorConfiguration.kt | 11 +- .../aisec/ids/cm/ContainerManagerService.java | 153 -------- .../fhg/aisec/ids/cm/impl/StreamGobbler.java | 65 ---- .../fhg/aisec/ids/cm/impl/dummy/DummyCM.java | 79 ---- .../aisec/ids/cm/impl/trustx/TrustXCM.java | 306 --------------- .../ids/comm/unixsocket/ChangeRequest.java | 38 -- .../TrustmeUnixSocketResponseHandler.java | 48 --- .../unixsocket/TrustmeUnixSocketThread.java | 329 ---------------- .../aisec/ids/cm/ContainerManagerService.kt | 152 ++++++++ .../fhg/aisec/ids/cm/impl/docker/DockerCM.kt | 111 +++--- .../de/fhg/aisec/ids/cm/impl/dummy/DummyCM.kt | 67 ++++ .../fhg/aisec/ids/cm/impl/trustx/TrustXCM.kt | 288 ++++++++++++++ .../ids/comm/unixsocket/ChangeRequest.kt | 29 ++ .../TrustmeUnixSocketResponseHandler.kt | 56 +++ .../unixsocket/TrustmeUnixSocketThread.kt | 318 ++++++++++++++++ .../dataflowcontrol/PolicyDecisionPoint.kt | 19 +- .../lucon/CounterExampleImpl.kt | 2 +- .../aisec/ids/rm/PolicyEnforcementPoint.kt | 12 +- .../fhg/aisec/ids/rm/RouteManagerService.kt | 119 +++--- .../aisec/ids/settings/SettingsComponent.kt | 53 ++- .../de/fhg/aisec/ids/webconsole/api/AppApi.kt | 32 +- .../fhg/aisec/ids/webconsole/api/ConfigApi.kt | 38 +- .../fhg/aisec/ids/webconsole/api/PolicyApi.kt | 2 +- .../fhg/aisec/ids/webconsole/api/data/Cert.kt | 1 - .../de/fhg/aisec/ids/webconsole/packageinfo | 1 - .../api/PortainerCompatibilityIT.java | 73 ---- .../ids/webconsole/api/RestApiTests.java | 256 ------------- .../api/PortainerCompatibilityIT.kt | 75 ++++ .../aisec/ids/webconsole/api/RestApiTests.kt | 251 ++++++++++++ 108 files changed, 2880 insertions(+), 4303 deletions(-) create mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/Constants.kt delete mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/ReferenceUnbind.java create mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/Result.kt create mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/RouteResult.kt create mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/acme/AcmeClient.kt create mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/acme/AcmeTermsOfService.kt rename ids-api/src/main/java/de/fhg/aisec/ids/api/acme/{SslContextFactoryReloadable.java => SslContextFactoryReloadable.kt} (85%) delete mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/acme/package-info.java delete mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/cm/ApplicationContainer.java create mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/cm/ApplicationContainer.kt delete mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/cm/ContainerManager.java create mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/cm/ContainerManager.kt delete mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/cm/ContainerStatus.java create mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/cm/ContainerStatus.kt rename ids-api/src/main/java/de/fhg/aisec/ids/api/cm/{Direction.java => Decision.kt} (90%) rename ids-api/src/main/java/de/fhg/aisec/ids/api/cm/{Decision.java => Direction.kt} (90%) rename ids-api/src/main/java/de/fhg/aisec/ids/api/cm/{NoContainerExistsException.java => NoContainerExistsException.kt} (71%) rename ids-api/src/main/java/de/fhg/aisec/ids/api/cm/{Protocol.java => Protocol.kt} (91%) delete mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/cm/package-info.java rename ids-api/src/main/java/de/fhg/aisec/ids/api/conm/{ConnectionManager.java => ConnectionManager.kt} (77%) delete mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/conm/IDSCPClientEndpoint.java create mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/conm/IDSCPClientEndpoint.kt delete mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/conm/IDSCPIncomingConnection.java create mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/conm/IDSCPIncomingConnection.kt delete mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/conm/IDSCPOutgoingConnection.java rename ids-api/src/main/java/de/fhg/aisec/ids/api/{acme/AcmeTermsOfService.java => conm/IDSCPOutgoingConnection.kt} (58%) delete mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/conm/IDSCPServerEndpoint.java create mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/conm/IDSCPServerEndpoint.kt create mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/conm/RatResult.kt delete mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/conm/package-info.java delete mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/endpointconfig/EndpointConfigListener.java create mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/endpointconfig/EndpointConfigListener.kt delete mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/endpointconfig/EndpointConfigManager.java create mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/endpointconfig/EndpointConfigManager.kt delete mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/endpointconfig/package-info.java rename ids-api/src/main/java/de/fhg/aisec/ids/api/external/{ExternalAPI.java => ExternalAPI.kt} (54%) delete mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/external/package-info.java delete mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/infomodel/ConnectorProfile.java create mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/infomodel/ConnectorProfile.kt delete mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/internal/package-info.java delete mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/package-info.java delete mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/policy/DecisionRequest.java rename ids-api/src/main/java/de/fhg/aisec/ids/api/{RouteResult.java => policy/DecisionRequest.kt} (56%) delete mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/policy/Obligation.java create mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/policy/Obligation.kt rename ids-api/src/main/java/de/fhg/aisec/ids/api/policy/{PAP.java => PAP.kt} (53%) delete mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/policy/PDP.java create mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/policy/PDP.kt delete mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/policy/PolicyDecision.java rename ids-api/src/main/java/de/fhg/aisec/ids/api/{internal/ComponentNotAvailableException.java => policy/PolicyDecision.kt} (74%) delete mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/policy/ServiceNode.java create mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/policy/ServiceNode.kt delete mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/policy/TransformationDecision.java rename ids-api/src/main/java/de/fhg/aisec/ids/api/{conm/RatResult.java => policy/TransformationDecision.kt} (52%) delete mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/policy/package-info.java delete mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/router/CounterExample.java rename ids-api/src/main/java/de/fhg/aisec/ids/api/{acme/AcmeClient.java => router/CounterExample.kt} (67%) rename ids-api/src/main/java/de/fhg/aisec/ids/api/router/{RouteComponent.java => RouteComponent.kt} (71%) rename ids-api/src/main/java/de/fhg/aisec/ids/api/router/{RouteException.java => RouteException.kt} (74%) delete mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/router/RouteManager.java create mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/router/RouteManager.kt delete mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/router/RouteMetrics.java create mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/router/RouteMetrics.kt delete mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/router/RouteObject.java create mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/router/RouteObject.kt delete mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/router/RouteVerificationProof.java create mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/router/RouteVerificationProof.kt delete mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/router/graph/Edge.java create mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/router/graph/Edge.kt delete mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/router/graph/GraphData.java rename ids-api/src/main/java/de/fhg/aisec/ids/api/{settings/ConnectionSettings.java => router/graph/GraphData.kt} (65%) delete mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/router/graph/Node.java create mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/router/graph/Node.kt delete mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/router/package-info.java rename ids-api/src/main/java/de/fhg/aisec/ids/api/{Constants.java => settings/ConnectionSettings.kt} (74%) delete mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/settings/ConnectorConfig.java rename ids-api/src/main/java/de/fhg/aisec/ids/api/{Result.java => settings/ConnectorConfig.kt} (53%) delete mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/settings/Settings.java create mode 100644 ids-api/src/main/java/de/fhg/aisec/ids/api/settings/Settings.kt delete mode 100644 ids-container-manager/src/main/java/de/fhg/aisec/ids/cm/ContainerManagerService.java delete mode 100644 ids-container-manager/src/main/java/de/fhg/aisec/ids/cm/impl/StreamGobbler.java delete mode 100644 ids-container-manager/src/main/java/de/fhg/aisec/ids/cm/impl/dummy/DummyCM.java delete mode 100644 ids-container-manager/src/main/java/de/fhg/aisec/ids/cm/impl/trustx/TrustXCM.java delete mode 100644 ids-container-manager/src/main/java/de/fhg/aisec/ids/comm/unixsocket/ChangeRequest.java delete mode 100644 ids-container-manager/src/main/java/de/fhg/aisec/ids/comm/unixsocket/TrustmeUnixSocketResponseHandler.java delete mode 100644 ids-container-manager/src/main/java/de/fhg/aisec/ids/comm/unixsocket/TrustmeUnixSocketThread.java create mode 100644 ids-container-manager/src/main/kotlin/de/fhg/aisec/ids/cm/ContainerManagerService.kt rename ids-container-manager/src/main/{java => kotlin}/de/fhg/aisec/ids/cm/impl/docker/DockerCM.kt (84%) create mode 100644 ids-container-manager/src/main/kotlin/de/fhg/aisec/ids/cm/impl/dummy/DummyCM.kt create mode 100644 ids-container-manager/src/main/kotlin/de/fhg/aisec/ids/cm/impl/trustx/TrustXCM.kt create mode 100644 ids-container-manager/src/main/kotlin/de/fhg/aisec/ids/comm/unixsocket/ChangeRequest.kt create mode 100644 ids-container-manager/src/main/kotlin/de/fhg/aisec/ids/comm/unixsocket/TrustmeUnixSocketResponseHandler.kt create mode 100644 ids-container-manager/src/main/kotlin/de/fhg/aisec/ids/comm/unixsocket/TrustmeUnixSocketThread.kt delete mode 100644 ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/packageinfo delete mode 100644 ids-webconsole/src/test/java/de/fhg/aisec/ids/webconsole/api/PortainerCompatibilityIT.java delete mode 100644 ids-webconsole/src/test/java/de/fhg/aisec/ids/webconsole/api/RestApiTests.java create mode 100644 ids-webconsole/src/test/kotlin/de/fhg/aisec/ids/webconsole/api/PortainerCompatibilityIT.kt create mode 100644 ids-webconsole/src/test/kotlin/de/fhg/aisec/ids/webconsole/api/RestApiTests.kt diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/Constants.kt b/ids-api/src/main/java/de/fhg/aisec/ids/api/Constants.kt new file mode 100644 index 000000000..ee25a9a35 --- /dev/null +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/Constants.kt @@ -0,0 +1,28 @@ +/*- + * ========================LICENSE_START================================= + * ids-api + * %% + * Copyright (C) 2019 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.api + +interface Constants { + companion object { + const val PREFERENCES_ID = "ids.preferences" + const val CONNECTIONS_PREFERENCES = "ids.connectionPreferences" + const val GENERAL_CONFIG = "General Configuration" + } +} diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/ReferenceUnbind.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/ReferenceUnbind.java deleted file mode 100644 index 40a63b337..000000000 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/ReferenceUnbind.java +++ /dev/null @@ -1,30 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-api - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.api; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** This is a helper annotation for warning suppression on OSGi unbindXXX methods */ -@Retention(RetentionPolicy.SOURCE) -@Target(ElementType.METHOD) -public @interface ReferenceUnbind {} diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/Result.kt b/ids-api/src/main/java/de/fhg/aisec/ids/api/Result.kt new file mode 100644 index 000000000..f9a83e27b --- /dev/null +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/Result.kt @@ -0,0 +1,23 @@ +/*- + * ========================LICENSE_START================================= + * ids-api + * %% + * Copyright (C) 2019 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.api + +/** Generic result of an API call. */ +open class Result(var isSuccessful: Boolean = true, var message: String = "ok") diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/RouteResult.kt b/ids-api/src/main/java/de/fhg/aisec/ids/api/RouteResult.kt new file mode 100644 index 000000000..6f1d88544 --- /dev/null +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/RouteResult.kt @@ -0,0 +1,31 @@ +/*- + * ========================LICENSE_START================================= + * ids-api + * %% + * Copyright (C) 2019 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.api + +import de.fhg.aisec.ids.api.router.RouteObject + +class RouteResult : Result { + var route: RouteObject? = null + + constructor() + constructor(success: Boolean, msg: String, route: RouteObject?) : super(success, msg) { + this.route = route + } +} diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/acme/AcmeClient.kt b/ids-api/src/main/java/de/fhg/aisec/ids/api/acme/AcmeClient.kt new file mode 100644 index 000000000..c847e8c0c --- /dev/null +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/acme/AcmeClient.kt @@ -0,0 +1,36 @@ +/*- + * ========================LICENSE_START================================= + * ids-api + * %% + * Copyright (C) 2019 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.api.acme + +import java.net.URI +import java.nio.file.Path + +interface AcmeClient { + fun getChallengeAuthorization(challenge: String): String + + fun renewCertificate( + targetDirectory: Path, + acmeServerUri: URI, + domains: Array, + challengePort: Int + ) + + fun getTermsOfService(acmeServerUri: URI): AcmeTermsOfService +} diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/acme/AcmeTermsOfService.kt b/ids-api/src/main/java/de/fhg/aisec/ids/api/acme/AcmeTermsOfService.kt new file mode 100644 index 000000000..8ca532fb4 --- /dev/null +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/acme/AcmeTermsOfService.kt @@ -0,0 +1,24 @@ +/*- + * ========================LICENSE_START================================= + * ids-api + * %% + * Copyright (C) 2019 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.api.acme + +import com.fasterxml.jackson.annotation.JsonProperty + +class AcmeTermsOfService(val tos: String, @get:JsonProperty(value = "isUri") val isUri: Boolean, val error: String) diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/acme/SslContextFactoryReloadable.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/acme/SslContextFactoryReloadable.kt similarity index 85% rename from ids-api/src/main/java/de/fhg/aisec/ids/api/acme/SslContextFactoryReloadable.java rename to ids-api/src/main/java/de/fhg/aisec/ids/api/acme/SslContextFactoryReloadable.kt index 3b332d5a7..353199d7a 100644 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/acme/SslContextFactoryReloadable.java +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/acme/SslContextFactoryReloadable.kt @@ -17,9 +17,8 @@ * limitations under the License. * =========================LICENSE_END================================== */ -package de.fhg.aisec.ids.api.acme; +package de.fhg.aisec.ids.api.acme -public interface SslContextFactoryReloadable { - - public void reload(String newKeyStorePath); +interface SslContextFactoryReloadable { + fun reload(newKeyStorePath: String?) } diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/acme/package-info.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/acme/package-info.java deleted file mode 100644 index 8b513b96d..000000000 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/acme/package-info.java +++ /dev/null @@ -1,21 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * IDS Core Platform API - * %% - * Copyright (C) 2017 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -/** APIs for ACME client functionality. */ -package de.fhg.aisec.ids.api.acme; diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/cm/ApplicationContainer.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/cm/ApplicationContainer.java deleted file mode 100644 index 3d04e2d9a..000000000 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/cm/ApplicationContainer.java +++ /dev/null @@ -1,357 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-api - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.api.cm; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; - -import java.net.InetAddress; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Bean representing an "Application Container" (aka a docker container). - * - * @author julian.schuette@aisec.fraunhofer.de - *

Complies with Portainer templates: - * https://github.com/portainer/portainer/blob/develop/app/docker/models/template.js - */ -@JsonIgnoreProperties -public class ApplicationContainer { - // Trusted Connector-specific properties: - private String id; - private String created; - private ContainerStatus status; - private List ports; - private String names; - private String size; - private String uptime; - private String signature; - private String owner; - private String image; - private String imageId; - private List imageDigests; - private List ipAddresses; - - // Portainer attributes: - private Object repository; - private String type; - private String name; - private String hostname; - private String title; - private String description; - private String note; - private List categories = new ArrayList<>(); - private String platform = "linux"; - private String logo; - private String registry = ""; - private String command = ""; - private String network; - private List> env = new ArrayList<>(); - private boolean privileged = false; - private boolean interactive = false; - private String restartPolicy = "always"; - private Map labels = new HashMap<>(); - private List volumes = new ArrayList<>(); - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public String getCreated() { - return created; - } - - public void setCreated(String created) { - this.created = created; - } - - public ContainerStatus getStatus() { - return status; - } - - public void setStatus(ContainerStatus status) { - this.status = status; - } - - public List getPorts() { - return ports; - } - - public void setPorts(List ports) { - this.ports = ports; - } - - public String getNames() { - return names; - } - - public void setNames(String names) { - this.names = names; - } - - public String getSize() { - return size; - } - - public void setSize(String size) { - this.size = size; - } - - public String getUptime() { - return uptime; - } - - public void setUptime(String uptime) { - this.uptime = uptime; - } - - public String getSignature() { - return signature; - } - - public void setSignature(String signature) { - this.signature = signature; - } - - public String getOwner() { - return owner; - } - - public void setOwner(String owner) { - this.owner = owner; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getHostname() { - return hostname; - } - - public void setHostname(String hostname) { - this.hostname = hostname; - } - - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public String getNote() { - return note; - } - - public void setNote(String note) { - this.note = note; - } - - public List getCategories() { - return categories; - } - - public void setCategories(List categories) { - this.categories = categories; - } - - public String getPlatform() { - return platform; - } - - public void setPlatform(String platform) { - this.platform = platform; - } - - public String getLogo() { - return logo; - } - - public void setLogo(String logo) { - this.logo = logo; - } - - public String getImage() { - return image; - } - - public void setImage(String image) { - this.image = image; - } - - public String getImageId() { - return imageId; - } - - public void setImageId(String imageId) { - this.imageId = imageId; - } - - public List getImageDigests() { - return imageDigests; - } - - public void setImageDigests(List digests) { - this.imageDigests = digests; - } - - public List getIpAddresses() { - return ipAddresses; - } - - public void setIpAddresses(List ipAddresses) { - this.ipAddresses = ipAddresses; - } - - public String getRegistry() { - return registry; - } - - public void setRegistry(String registry) { - this.registry = registry; - } - - public String getCommand() { - return command; - } - - public void setCommand(String command) { - this.command = command; - } - - public String getNetwork() { - return network; - } - - public void setNetwork(String network) { - this.network = network; - } - - public List> getEnv() { - return env; - } - - public void setEnv(List> env) { - this.env = env; - } - - public boolean isPrivileged() { - return privileged; - } - - public void setPrivileged(boolean privileged) { - this.privileged = privileged; - } - - public boolean isInteractive() { - return interactive; - } - - public void setInteractive(boolean interactive) { - this.interactive = interactive; - } - - public String getRestartPolicy() { - return restartPolicy; - } - - public void setRestartPolicy(String restartPolicy) { - this.restartPolicy = restartPolicy; - } - - public Map getLabels() { - return labels; - } - - public void setLabels(Map labels) { - this.labels = labels; - } - - public List getVolumes() { - return volumes; - } - - public void setVolumes(List volumes) { - this.volumes = volumes; - } - - @Override - public String toString() { - return "ApplicationContainer [id=" - + id - + ", image=" - + image - + ", created=" - + created - + ", status=" - + status - + ", ports=" - + ports - + ", names=" - + names - + ", size=" - + size - + ", uptime=" - + uptime - + ", signature=" - + signature - + ", owner=" - + owner - + ", description=" - + description - + "]"; - } - - public Object getRepository() { - return repository; - } - - public void setRepository(Object repository) { - this.repository = repository; - } -} diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/cm/ApplicationContainer.kt b/ids-api/src/main/java/de/fhg/aisec/ids/api/cm/ApplicationContainer.kt new file mode 100644 index 000000000..b0093364a --- /dev/null +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/cm/ApplicationContainer.kt @@ -0,0 +1,97 @@ +/*- + * ========================LICENSE_START================================= + * ids-api + * %% + * Copyright (C) 2019 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.api.cm + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties +import java.net.InetAddress + +/** + * Bean representing an "Application Container" (aka a docker container). + * + * @author julian.schuette@aisec.fraunhofer.de + * + * Complies with Portainer templates: + * https://github.com/portainer/portainer/blob/develop/app/docker/models/template.js + */ +@JsonIgnoreProperties +class ApplicationContainer { + // Trusted Connector-specific properties: + var id: String? = null + var created: String? = null + var status: ContainerStatus? = null + var ports: List = emptyList() + var names: String? = null + var size: String? = null + var uptime: String? = null + var signature: String? = null + var owner: String? = null + var image: String? = null + var imageId: String? = null + var imageDigests: List = emptyList() + var ipAddresses: List = emptyList() + + // Portainer attributes: + var repository: Any? = null + var type: String? = null + var name: String? = null + var hostname: String? = null + var title: String? = null + var description: String? = null + var note: String? = null + var categories: List = ArrayList() + var platform = "linux" + var logo: String? = null + var registry = "" + var command = "" + var network: String? = null + var env: List> = ArrayList() + var isPrivileged = false + var isInteractive = false + var restartPolicy = "always" + var labels: Map = HashMap() + var volumes: List = ArrayList() + override fun toString(): String { + return ( + "ApplicationContainer [id=" + + id + + ", image=" + + image + + ", created=" + + created + + ", status=" + + status + + ", ports=" + + ports + + ", names=" + + names + + ", size=" + + size + + ", uptime=" + + uptime + + ", signature=" + + signature + + ", owner=" + + owner + + ", description=" + + description + + "]" + ) + } +} diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/cm/ContainerManager.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/cm/ContainerManager.java deleted file mode 100644 index 68dc49b1a..000000000 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/cm/ContainerManager.java +++ /dev/null @@ -1,172 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-api - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.api.cm; - -import java.util.List; -import java.util.Optional; - -/** - * Controls Application Containers of the underlying platform. - * - *

The container management layer can be Docker or trust-X. - * - * @author Julian Schütte (julian.schuette@aisec.fraunhofer.de) - */ -public interface ContainerManager { - - /** - * Returns the container management layer which is currently in use. - * - *

One of docker, trust-X, none. - * - * @return Version of the container management engine - */ - String getVersion(); - - /** - * List currently installed containers. - * - *

The respective docker command is: docker ps -a. - * - * @param onlyRunning If set to true, only currently running containers are displayed. - * @return List of containers - */ - List list(boolean onlyRunning); - - /** - * Wipes are container from disk, i.e. removes it irreversibly. - * - * @param containerID Hash of the container. - * @throws NoContainerExistsException If the given container was not found. - */ - void wipe(final String containerID) throws NoContainerExistsException; - - /** - * Starts a container. - * - *

If the container is already running, this method will do nothing. - * - *

The container must already exist, otherwise an exception will be thrown. - * - * @param containerID ID of the container to start - * @param key Key to start the container, if required by container management engine - * @throws NoContainerExistsException If the given container was not found. - */ - void startContainer(final String containerID, final String key) - throws NoContainerExistsException; - - /** - * Stops a container. - * - *

A stopped container does not execute any processes, but its persisted data is still present. - * It can be started by startContainer again, i.e. the sequence stopContainer(x); - * startContainer(X); has no effect. * - * - *

If the container is already stopped, this method will do nothing. - * - *

The container must already exist, otherwise an exception will be thrown. - * - * @param containerID ID of the container to stop - * @throws NoContainerExistsException If the given container was not found. - */ - void stopContainer(final String containerID) throws NoContainerExistsException; - - /** - * Restarts a container without stopping it first. - * - *

The container must already exist, otherwise an exception will be thrown. - * - * @param containerID ID of the container to restart - * @throws NoContainerExistsException If the given container was not found. - */ - void restartContainer(final String containerID) throws NoContainerExistsException; - - /** - * Retrieves configuration data about a container. - * - *

The data format returned will depend on the underlying CML implementation. As for docker, - * this command will return the output of the command docker inspect. - * - *

If meta data is stored in container labels, the result of getMetaData will also - * be contained in the result of this method. - * - * @param containerID ID of the container. If does not exist, a NoContainerExistsException will be - * thrown. - * @return Information about the queried container, in implementation-dependent format - * @throws NoContainerExistsException If the given container was not found. - */ - String inspectContainer(final String containerID) throws NoContainerExistsException; - - /** - * Returns metadata associated with the service running in the container. - * - *

The data format returned depends on the meta data implementation, but will usually be RDF. - * - * @param containerID ID of the container to get metadata for - * @return An object with metadata about the container, in implementation-dependent format - * @throws NoContainerExistsException If the given container was not found. - */ - Object getMetadata(final String containerID) throws NoContainerExistsException; - - /** - * Pulls an image from the online registry. - * - *

The online registry can be given as a URL. If it is not given, the standard Docker registry - * is used in case of a Docker CML implementation. - * - *

This method blocks until the image has been pulled or an exception has occurred. As this is - * a long running operation, it should always be called in a separate thread. - * - * @param app Metadata about the container to be created and started with given image data - * @return ID of the container, if started successfully - * @throws NoContainerExistsException If the given container was not found. - */ - Optional pullImage(final ApplicationContainer app) - throws NoContainerExistsException; - - /** - * Configures an IP rule for a container. - * - *

By default, containers do not have IP connectivity, i.e. all inbound and outbound traffic is - * blocked. - * - *

This method can be used to allow specific communication channels from/to a container. - * - * @param containerID ID of the container. It must exist, otherwise a NoContainerExistsException - * will be thrown. - * @param direction INBOUND for traffic going into the container or OUTBOUND for traffic leaving - * the container. Replies within established TCP sessions will always be allowed, there is no - * need to configure them. - * @param srcPort IP source port. - * @param dstPort IP destination port. - * @param srcDstRange Remote IP, i.e. for OUTBOUND traffic, IP range of the destination. For - * INBOUND traffic, IP range of the source. - * @param protocol TPC or UDP. - * @param decision ALLOW, DENY, or DROP - */ - void setIpRule( - String containerID, - Direction direction, - int srcPort, - int dstPort, - String srcDstRange, - Protocol protocol, - Decision decision); -} diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/cm/ContainerManager.kt b/ids-api/src/main/java/de/fhg/aisec/ids/api/cm/ContainerManager.kt new file mode 100644 index 000000000..ccbd8e4b9 --- /dev/null +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/cm/ContainerManager.kt @@ -0,0 +1,190 @@ +/*- + * ========================LICENSE_START================================= + * ids-api + * %% + * Copyright (C) 2019 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.api.cm + +/** + * Controls Application Containers of the underlying platform. + * + * + * The container management layer can be Docker or trust-X. + * + * @author Julian Schütte (julian.schuette@aisec.fraunhofer.de) + */ +interface ContainerManager { + /** + * Returns the container management layer which is currently in use. + * + * + * One of docker, trust-X, none. + * + * @return Version of the container management engine + */ + val version: String + + /** + * List currently installed containers. + * + * + * The respective docker command is: `docker ps -a`. + * + * @param onlyRunning If set to true, only currently running containers are displayed. + * @return List of containers + */ + fun list(onlyRunning: Boolean): List + + /** + * Wipes are container from disk, i.e. removes it irreversibly. + * + * @param containerID Hash of the container. + * @throws NoContainerExistsException If the given container was not found. + */ + @Throws(NoContainerExistsException::class) + fun wipe(containerID: String) + + /** + * Starts a container. + * + * + * If the container is already running, this method will do nothing. + * + * + * The container must already exist, otherwise an exception will be thrown. + * + * @param containerID ID of the container to start + * @param key Key to start the container, if required by container management engine + * @throws NoContainerExistsException If the given container was not found. + */ + @Throws(NoContainerExistsException::class) + fun startContainer(containerID: String, key: String?) + + /** + * Stops a container. + * + * + * A stopped container does not execute any processes, but its persisted data is still present. + * It can be started by `startContainer` again, i.e. the sequence stopContainer(x); + * startContainer(X); has no effect. * + * + * + * If the container is already stopped, this method will do nothing. + * + * + * The container must already exist, otherwise an exception will be thrown. + * + * @param containerID ID of the container to stop + * @throws NoContainerExistsException If the given container was not found. + */ + @Throws(NoContainerExistsException::class) + fun stopContainer(containerID: String) + + /** + * Restarts a container without stopping it first. + * + * + * The container must already exist, otherwise an exception will be thrown. + * + * @param containerID ID of the container to restart + * @throws NoContainerExistsException If the given container was not found. + */ + @Throws(NoContainerExistsException::class) + fun restartContainer(containerID: String) + + /** + * Retrieves configuration data about a container. + * + * + * The data format returned will depend on the underlying CML implementation. As for docker, + * this command will return the output of the command `docker inspect`. + * + * + * If meta data is stored in container labels, the result of `getMetaData` will also + * be contained in the result of this method. + * + * @param containerID ID of the container. If does not exist, a NoContainerExistsException will be + * thrown. + * @return Information about the queried container, in implementation-dependent format + * @throws NoContainerExistsException If the given container was not found. + */ + @Throws(NoContainerExistsException::class) + fun inspectContainer(containerID: String): String? + + /** + * Returns metadata associated with the service running in the container. + * + * + * The data format returned depends on the meta data implementation, but will usually be RDF. + * + * @param containerID ID of the container to get metadata for + * @return An object with metadata about the container, in implementation-dependent format + * @throws NoContainerExistsException If the given container was not found. + */ + @Throws(NoContainerExistsException::class) + fun getMetadata(containerID: String): Any? + + /** + * Pulls an image from the online registry. + * + * + * The online registry can be given as a URL. If it is not given, the standard Docker registry + * is used in case of a Docker CML implementation. + * + * + * This method blocks until the image has been pulled or an exception has occurred. As this is + * a long running operation, it should always be called in a separate thread. + * + * @param app Metadata about the container to be created and started with given image data + * @return ID of the container, if started successfully + * @throws NoContainerExistsException If the given container was not found. + */ + @Throws(NoContainerExistsException::class) + fun pullImage(app: ApplicationContainer): String? + + /** + * Configures an IP rule for a container. + * + * + * By default, containers do not have IP connectivity, i.e. all inbound and outbound traffic is + * blocked. + * + * + * This method can be used to allow specific communication channels from/to a container. + * + * @param containerID ID of the container. It must exist, otherwise a NoContainerExistsException + * will be thrown. + * @param direction INBOUND for traffic going into the container or OUTBOUND for traffic leaving + * the container. Replies within established TCP sessions will always be allowed, there is no + * need to configure them. + * @param srcPort IP source port. + * @param dstPort IP destination port. + * @param srcDstRange Remote IP, i.e. for OUTBOUND traffic, IP range of the destination. For + * INBOUND traffic, IP range of the source. + * @param protocol TPC or UDP. + * @param decision ALLOW, DENY, or DROP + */ + fun setIpRule( + containerID: String, + direction: Direction, + srcPort: Int, + dstPort: Int, + srcDstRange: String, + protocol: Protocol, + decision: Decision + ) +} diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/cm/ContainerStatus.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/cm/ContainerStatus.java deleted file mode 100644 index 5bc812913..000000000 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/cm/ContainerStatus.java +++ /dev/null @@ -1,11 +0,0 @@ -package de.fhg.aisec.ids.api.cm; - -public enum ContainerStatus { - CREATED, - RESTARTING, - RUNNING, - REMOVING, - PAUSED, - EXITED, - DEAD; -} diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/cm/ContainerStatus.kt b/ids-api/src/main/java/de/fhg/aisec/ids/api/cm/ContainerStatus.kt new file mode 100644 index 000000000..be710e577 --- /dev/null +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/cm/ContainerStatus.kt @@ -0,0 +1,24 @@ +/*- + * ========================LICENSE_START================================= + * ids-api + * %% + * Copyright (C) 2021 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.api.cm + +enum class ContainerStatus { + CREATED, RESTARTING, RUNNING, REMOVING, PAUSED, EXITED, DEAD +} diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/cm/Direction.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/cm/Decision.kt similarity index 90% rename from ids-api/src/main/java/de/fhg/aisec/ids/api/cm/Direction.java rename to ids-api/src/main/java/de/fhg/aisec/ids/api/cm/Decision.kt index aa6071e1c..a56779cd2 100644 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/cm/Direction.java +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/cm/Decision.kt @@ -17,9 +17,8 @@ * limitations under the License. * =========================LICENSE_END================================== */ -package de.fhg.aisec.ids.api.cm; +package de.fhg.aisec.ids.api.cm -public enum Direction { - OUTBOUND, - INBOUND +enum class Decision { + ALLOW, DENY, DROP } diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/cm/Decision.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/cm/Direction.kt similarity index 90% rename from ids-api/src/main/java/de/fhg/aisec/ids/api/cm/Decision.java rename to ids-api/src/main/java/de/fhg/aisec/ids/api/cm/Direction.kt index 9719ab525..a0b7d098c 100644 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/cm/Decision.java +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/cm/Direction.kt @@ -17,10 +17,8 @@ * limitations under the License. * =========================LICENSE_END================================== */ -package de.fhg.aisec.ids.api.cm; +package de.fhg.aisec.ids.api.cm -public enum Decision { - ALLOW, - DENY, - DROP +enum class Direction { + OUTBOUND, INBOUND } diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/cm/NoContainerExistsException.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/cm/NoContainerExistsException.kt similarity index 71% rename from ids-api/src/main/java/de/fhg/aisec/ids/api/cm/NoContainerExistsException.java rename to ids-api/src/main/java/de/fhg/aisec/ids/api/cm/NoContainerExistsException.kt index a75c64f5f..a869de938 100644 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/cm/NoContainerExistsException.java +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/cm/NoContainerExistsException.kt @@ -17,21 +17,18 @@ * limitations under the License. * =========================LICENSE_END================================== */ -package de.fhg.aisec.ids.api.cm; +package de.fhg.aisec.ids.api.cm /** * Thrown if a container does not exist. * * @author Julian Schuette (julian.schuette@aisec.fraunhofer.de) */ -public class NoContainerExistsException extends Exception { - private static final long serialVersionUID = 3439666843047044252L; +class NoContainerExistsException : Exception { + constructor(message: String) : super(message) + constructor(message: String, throwable: Throwable) : super(message, throwable) - public NoContainerExistsException(String message) { - super(message); - } - - public NoContainerExistsException(String message, Throwable throwable) { - super(message, throwable); - } + companion object { + private const val serialVersionUID = 3439666843047044252L + } } diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/cm/Protocol.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/cm/Protocol.kt similarity index 91% rename from ids-api/src/main/java/de/fhg/aisec/ids/api/cm/Protocol.java rename to ids-api/src/main/java/de/fhg/aisec/ids/api/cm/Protocol.kt index eb009601d..a3a5e7f57 100644 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/cm/Protocol.java +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/cm/Protocol.kt @@ -17,9 +17,8 @@ * limitations under the License. * =========================LICENSE_END================================== */ -package de.fhg.aisec.ids.api.cm; +package de.fhg.aisec.ids.api.cm -public enum Protocol { - TCP, - UDP +enum class Protocol { + TCP, UDP } diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/cm/package-info.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/cm/package-info.java deleted file mode 100644 index c3ad10a8d..000000000 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/cm/package-info.java +++ /dev/null @@ -1,21 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * IDS Core Platform API - * %% - * Copyright (C) 2017 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -/** APIs for accessing the container management layer (Docker or trustme). */ -package de.fhg.aisec.ids.api.cm; diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/conm/ConnectionManager.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/conm/ConnectionManager.kt similarity index 77% rename from ids-api/src/main/java/de/fhg/aisec/ids/api/conm/ConnectionManager.java rename to ids-api/src/main/java/de/fhg/aisec/ids/api/conm/ConnectionManager.kt index 029e36039..a517bf696 100644 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/conm/ConnectionManager.java +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/conm/ConnectionManager.kt @@ -17,20 +17,15 @@ * limitations under the License. * =========================LICENSE_END================================== */ -package de.fhg.aisec.ids.api.conm; - -import java.util.List; +package de.fhg.aisec.ids.api.conm /** * List and interacts with open connections over the IDS communication protocol * * @author Gerd Brost (gerd.brost@aisec.fraunhofer.de) */ -public interface ConnectionManager { - - List listIncomingConnections(); - - List listOutgoingConnections(); - - List listAvailableEndpoints(); +interface ConnectionManager { + fun listIncomingConnections(): List + fun listOutgoingConnections(): List + fun listAvailableEndpoints(): List } diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/conm/IDSCPClientEndpoint.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/conm/IDSCPClientEndpoint.java deleted file mode 100644 index 530b68d4c..000000000 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/conm/IDSCPClientEndpoint.java +++ /dev/null @@ -1,63 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-api - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.api.conm; - -/** - * Bean representing an "IDSCP Endpoint". This maps to a camel endpoint and is used to handle - * exposed endpoints of the IDSCP. - * - * @author Gerd Brost (gerd.brost@aisec.fraunhofer.de) - */ -public class IDSCPClientEndpoint { - private String endpointIdentifier; - private RatResult attestationResult; - private String endpointKey; - - @Override - public String toString() { - return "IDSCPEndpoint [endpoint_identifier=" + endpointIdentifier + "]"; - } - - public String getEndpointIdentifier() { - return endpointIdentifier; - } - - public void setEndpointIdentifier(String endpointIdentifier) { - this.endpointIdentifier = endpointIdentifier; - } - - public RatResult getAttestationResult() { - return attestationResult; - } - - public void setAttestationResult(RatResult attestationResult) { - this.attestationResult = attestationResult; - } - - public void setEndpointKey(String endpointKey) { - this.endpointKey = endpointKey; - } - - public String getEndpointKey() { - return endpointKey; - } - - public IDSCPClientEndpoint() {} -} diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/conm/IDSCPClientEndpoint.kt b/ids-api/src/main/java/de/fhg/aisec/ids/api/conm/IDSCPClientEndpoint.kt new file mode 100644 index 000000000..70a2084c6 --- /dev/null +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/conm/IDSCPClientEndpoint.kt @@ -0,0 +1,35 @@ +/*- + * ========================LICENSE_START================================= + * ids-api + * %% + * Copyright (C) 2019 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.api.conm + +/** + * Bean representing an "IDSCP Endpoint". This maps to a camel endpoint and is used to handle + * exposed endpoints of the IDSCP. + * + * @author Gerd Brost (gerd.brost@aisec.fraunhofer.de) + */ +class IDSCPClientEndpoint { + var endpointIdentifier: String? = null + var attestationResult: RatResult? = null + var endpointKey: String? = null + override fun toString(): String { + return "IDSCPEndpoint [endpoint_identifier=$endpointIdentifier]" + } +} diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/conm/IDSCPIncomingConnection.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/conm/IDSCPIncomingConnection.java deleted file mode 100644 index 0fc77a4d7..000000000 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/conm/IDSCPIncomingConnection.java +++ /dev/null @@ -1,87 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-api - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.api.conm; - -/** - * Bean representing an "IDSCP Connection" . - * - * @author Gerd Brost (gerd.brost@aisec.fraunhofer.de) - */ -public class IDSCPIncomingConnection { - private String endpointIdentifier; - private RatResult attestationResult; - private String endpointKey; - private String remoteHostName; - private String metaData; - private String dynamicAttributeToken; - - public String getEndpointIdentifier() { - return endpointIdentifier; - } - - public void setEndpointIdentifier(String endpointIdentifier) { - this.endpointIdentifier = endpointIdentifier; - } - - public RatResult getAttestationResult() { - return attestationResult; - } - - public void setAttestationResult(RatResult result) { - this.attestationResult = result; - } - - @Override - public String toString() { - return "IDSCPConnection [endpoint_identifier=" - + endpointIdentifier - + ", attestationResult=" - + attestationResult - + "]"; - } - - public void setEndpointKey(String connectionKey) { - this.endpointKey = connectionKey; - } - - public String getEndpointKey() { - return endpointKey; - } - - public String getRemoteHostName() { - return remoteHostName; - } - - public void setRemoteHostName(String remoteHostname) { - this.remoteHostName = remoteHostname; - } - - public void setMetaData(String metaResult) { - this.metaData = metaResult; - } - - public String getMetaData() { - return this.metaData; - } - - public void setDynamicAttributeToken(String dynamicAttributeToken) { - this.dynamicAttributeToken = dynamicAttributeToken; - } -} diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/conm/IDSCPIncomingConnection.kt b/ids-api/src/main/java/de/fhg/aisec/ids/api/conm/IDSCPIncomingConnection.kt new file mode 100644 index 000000000..7de709531 --- /dev/null +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/conm/IDSCPIncomingConnection.kt @@ -0,0 +1,47 @@ +/*- + * ========================LICENSE_START================================= + * ids-api + * %% + * Copyright (C) 2019 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.api.conm + +/** + * Bean representing an "IDSCP Connection" . + * + * @author Gerd Brost (gerd.brost@aisec.fraunhofer.de) + */ +class IDSCPIncomingConnection { + var endpointIdentifier: String? = null + var attestationResult: RatResult? = null + var endpointKey: String? = null + var remoteHostName: String? = null + var metaData: String? = null + private var dynamicAttributeToken: String? = null + override fun toString(): String { + return ( + "IDSCPConnection [endpoint_identifier=" + + endpointIdentifier + + ", attestationResult=" + + attestationResult + + "]" + ) + } + + fun setDynamicAttributeToken(dynamicAttributeToken: String?) { + this.dynamicAttributeToken = dynamicAttributeToken + } +} diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/conm/IDSCPOutgoingConnection.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/conm/IDSCPOutgoingConnection.java deleted file mode 100644 index 76f0b49e1..000000000 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/conm/IDSCPOutgoingConnection.java +++ /dev/null @@ -1,87 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-api - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.api.conm; - -/** - * Bean representing an "IDSCP Connection" . - * - * @author Gerd Brost (gerd.brost@aisec.fraunhofer.de) - */ -public class IDSCPOutgoingConnection { - private String endpointIdentifier; - private String remoteAuthentication; - private String remoteIdentity; - private String endpointKey; - private RatResult attestationResult; - private String metaData; - - public String getEndpointKey() { - return endpointKey; - } - - public void setEndpointKey(String endpointKey) { - this.endpointKey = endpointKey; - } - - public String getRemoteAuthentication() { - return remoteAuthentication; - } - - public void setRemoteAuthentication(String state) { - this.remoteAuthentication = state; - } - - public String getRemoteIdentity() { - return remoteIdentity; - } - - public void setRemoteIdentity(String hostname) { - this.remoteIdentity = hostname; - } - - public String getEndpointIdentifier() { - return endpointIdentifier; - } - - public void setEndpointIdentifier(String endpointIdentifier) { - this.endpointIdentifier = endpointIdentifier; - } - - public RatResult getAttestationResult() { - return this.attestationResult; - } - - public void setAttestationResult(RatResult attestationResult) { - this.attestationResult = attestationResult; - } - - @Override - public String toString() { - return "IDSCPOutgoingConnection [endpoint_identifier=" + endpointIdentifier + "]"; - } - - public void setMetaData(String metaResult) { - this.metaData = metaResult; - } - - public String getMetaData() { - return this.metaData; - } -} diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/acme/AcmeTermsOfService.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/conm/IDSCPOutgoingConnection.kt similarity index 58% rename from ids-api/src/main/java/de/fhg/aisec/ids/api/acme/AcmeTermsOfService.java rename to ids-api/src/main/java/de/fhg/aisec/ids/api/conm/IDSCPOutgoingConnection.kt index 9166f5ce5..d8a2231c6 100644 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/acme/AcmeTermsOfService.java +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/conm/IDSCPOutgoingConnection.kt @@ -17,31 +17,21 @@ * limitations under the License. * =========================LICENSE_END================================== */ -package de.fhg.aisec.ids.api.acme; +package de.fhg.aisec.ids.api.conm -import com.fasterxml.jackson.annotation.JsonProperty; - -public final class AcmeTermsOfService { - final String tos; - final boolean isUri; - final String error; - - public AcmeTermsOfService(String tos, boolean isUri, String error) { - this.tos = tos; - this.isUri = isUri; - this.error = error; - } - - public String getTos() { - return tos; - } - - @JsonProperty(value = "isUri") - public boolean isUri() { - return isUri; - } - - public String getError() { - return error; - } +/** + * Bean representing an "IDSCP Connection" . + * + * @author Gerd Brost (gerd.brost@aisec.fraunhofer.de) + */ +class IDSCPOutgoingConnection { + var endpointIdentifier: String? = null + var remoteAuthentication: String? = null + var remoteIdentity: String? = null + var endpointKey: String? = null + var attestationResult: RatResult? = null + var metaData: String? = null + override fun toString(): String { + return "IDSCPOutgoingConnection [endpoint_identifier=$endpointIdentifier]" + } } diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/conm/IDSCPServerEndpoint.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/conm/IDSCPServerEndpoint.java deleted file mode 100644 index b36f8d323..000000000 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/conm/IDSCPServerEndpoint.java +++ /dev/null @@ -1,72 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-api - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.api.conm; - -/** - * Bean representing an "IDSCP Endpoint". This maps to a camel endpoint and is used to handle - * exposed endpoints of the IDSCP. - * - * @author Gerd Brost (gerd.brost@aisec.fraunhofer.de) - */ -public class IDSCPServerEndpoint { - private String endpointIdentifier; - private String defaultProtocol; - private String port; - private String host; - - public IDSCPServerEndpoint() {} - - public String getDefaultProtocol() { - return defaultProtocol; - } - - public String getPort() { - return port; - } - - public String getHost() { - return host; - } - - public String getEndpointIdentifier() { - return endpointIdentifier; - } - - public void setEndpointIdentifier(String endpointIdentifier) { - this.endpointIdentifier = endpointIdentifier; - } - - @Override - public String toString() { - return "IDSCPEndpoint [endpoint_identifier=" + endpointIdentifier + "]"; - } - - public void setDefaultProtocol(String defaultProtocol) { - this.defaultProtocol = defaultProtocol; - } - - public void setPort(String port) { - this.port = port; - } - - public void setHost(String host) { - this.host = host; - } -} diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/conm/IDSCPServerEndpoint.kt b/ids-api/src/main/java/de/fhg/aisec/ids/api/conm/IDSCPServerEndpoint.kt new file mode 100644 index 000000000..5cd70ba14 --- /dev/null +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/conm/IDSCPServerEndpoint.kt @@ -0,0 +1,36 @@ +/*- + * ========================LICENSE_START================================= + * ids-api + * %% + * Copyright (C) 2019 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.api.conm + +/** + * Bean representing an "IDSCP Endpoint". This maps to a camel endpoint and is used to handle + * exposed endpoints of the IDSCP. + * + * @author Gerd Brost (gerd.brost@aisec.fraunhofer.de) + */ +class IDSCPServerEndpoint { + var endpointIdentifier: String? = null + var defaultProtocol: String? = null + var port: String? = null + var host: String? = null + override fun toString(): String { + return "IDSCPEndpoint [endpoint_identifier=$endpointIdentifier]" + } +} diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/conm/RatResult.kt b/ids-api/src/main/java/de/fhg/aisec/ids/api/conm/RatResult.kt new file mode 100644 index 000000000..46a72c08a --- /dev/null +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/conm/RatResult.kt @@ -0,0 +1,41 @@ +/*- + * ========================LICENSE_START================================= + * ids-api + * %% + * Copyright (C) 2019 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.api.conm + +/** + * Result of a remote attestation between peers. + * + * @author Julian Schuette (julian.schuette@aisec.fraunhofer.de) + */ +class RatResult(val status: Status, reason: String?) { + enum class Status { + FAILED, SUCCESS + } + + var reason: String? = null + + init { + if (reason != null) { + this.reason = reason + } else { + this.reason = "" + } + } +} diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/conm/package-info.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/conm/package-info.java deleted file mode 100644 index 97a30af0f..000000000 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/conm/package-info.java +++ /dev/null @@ -1,21 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * IDS Core Platform API - * %% - * Copyright (C) 2017 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -/** APIs for retrieving information about ongoing connections to IDS endpoints. */ -package de.fhg.aisec.ids.api.conm; diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/endpointconfig/EndpointConfigListener.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/endpointconfig/EndpointConfigListener.java deleted file mode 100644 index aae22bc22..000000000 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/endpointconfig/EndpointConfigListener.java +++ /dev/null @@ -1,13 +0,0 @@ -package de.fhg.aisec.ids.api.endpointconfig; - -/** - * Interface of the Endpoint Configuration Listener. - * - *

The Endpoint Configuration Listener is part of a Listener Pattern for dynamically validate - * the dynamicAttributeToken in the DefaultWebSocket when endpoint configuration has changed - * - * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) - */ -public interface EndpointConfigListener { - void updateTokenValidation(); -} diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/endpointconfig/EndpointConfigListener.kt b/ids-api/src/main/java/de/fhg/aisec/ids/api/endpointconfig/EndpointConfigListener.kt new file mode 100644 index 000000000..dd168afe4 --- /dev/null +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/endpointconfig/EndpointConfigListener.kt @@ -0,0 +1,33 @@ +/*- + * ========================LICENSE_START================================= + * ids-api + * %% + * Copyright (C) 2021 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.api.endpointconfig + +/** + * Interface of the Endpoint Configuration Listener. + * + * + * The Endpoint Configuration Listener is part of a Listener Pattern for dynamically validate + * the dynamicAttributeToken in the DefaultWebSocket when endpoint configuration has changed + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ +interface EndpointConfigListener { + fun updateTokenValidation() +} diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/endpointconfig/EndpointConfigManager.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/endpointconfig/EndpointConfigManager.java deleted file mode 100644 index c2a3d2fb5..000000000 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/endpointconfig/EndpointConfigManager.java +++ /dev/null @@ -1,20 +0,0 @@ -package de.fhg.aisec.ids.api.endpointconfig; - -/** - * Interface of the Dynamic Endpoint Configuration Manager. - * - *

The Dynamic Endpoint Configuration Manager is part of a Listener Pattern for dynamic validation of - * the dynamicAttributeToken in the DefaultWebSocket when endpoint configuration has changed - * - * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) - */ - -public interface EndpointConfigManager { - - void addEndpointConfigListener(String identifier, EndpointConfigListener listener); - - void removeEndpointConfigListener(String identifier); - - void notify(String endpointConfig); - -} diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/endpointconfig/EndpointConfigManager.kt b/ids-api/src/main/java/de/fhg/aisec/ids/api/endpointconfig/EndpointConfigManager.kt new file mode 100644 index 000000000..c31f287a6 --- /dev/null +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/endpointconfig/EndpointConfigManager.kt @@ -0,0 +1,35 @@ +/*- + * ========================LICENSE_START================================= + * ids-api + * %% + * Copyright (C) 2021 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.api.endpointconfig + +/** + * Interface of the Dynamic Endpoint Configuration Manager. + * + * + * The Dynamic Endpoint Configuration Manager is part of a Listener Pattern for dynamic validation of + * the dynamicAttributeToken in the DefaultWebSocket when endpoint configuration has changed + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ +interface EndpointConfigManager { + fun addEndpointConfigListener(identifier: String, listener: EndpointConfigListener) + fun removeEndpointConfigListener(identifier: String) + fun notify(endpointConfig: String) +} diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/endpointconfig/package-info.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/endpointconfig/package-info.java deleted file mode 100644 index ed5d91d7d..000000000 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/endpointconfig/package-info.java +++ /dev/null @@ -1,21 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * IDS Core Platform API - * %% - * Copyright (C) 2017 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -/** APIs for accessing dynamicEndpointConfig Services. */ -package de.fhg.aisec.ids.api.endpointconfig; diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/external/ExternalAPI.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/external/ExternalAPI.kt similarity index 54% rename from ids-api/src/main/java/de/fhg/aisec/ids/api/external/ExternalAPI.java rename to ids-api/src/main/java/de/fhg/aisec/ids/api/external/ExternalAPI.kt index 5beb87abe..9d2b60b86 100644 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/external/ExternalAPI.java +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/external/ExternalAPI.kt @@ -17,39 +17,37 @@ * limitations under the License. * =========================LICENSE_END================================== */ -package de.fhg.aisec.ids.api.external; +package de.fhg.aisec.ids.api.external -import de.fhg.aisec.ids.messages.BrokerProtos.AnnounceServiceResponse; -import de.fhg.aisec.ids.messages.BrokerProtos.ServiceDescription; -import de.fhg.aisec.ids.messages.Idscp.AttestationResponse; -import java.nio.channels.Channel; -import java.util.concurrent.CompletableFuture; +import de.fhg.aisec.ids.messages.BrokerProtos.AnnounceServiceResponse +import de.fhg.aisec.ids.messages.BrokerProtos.ServiceDescription +import de.fhg.aisec.ids.messages.Idscp.AttestationResponse +import java.nio.channels.Channel +import java.util.concurrent.CompletableFuture /** * Interface of an IDS connector towards the IDS network, i.e. outside of the connector itself. * * @author Julian Schütte (julian.schuette@aisec.fraunhofer.de), Gerd Brost */ -public interface ExternalAPI { +interface ExternalAPI { + fun addEndpoint(s: String, channel: Channel) + fun hasEndpoint(s: String): Boolean - public void addEndpoint(String s, Channel channel); + /** + * Method to announce a service to a broker + * + * @param description Description of the service to be accounced + * @return Service accouncement response + */ + fun announceService(description: ServiceDescription): CompletableFuture - public boolean hasEndpoint(String s); - - /** - * Method to announce a service to a broker - * - * @param description Description of the service to be accounced - * @return Service accouncement response - */ - CompletableFuture announceService(ServiceDescription description); - - /** - * Method to request attestation - * - * @param URI URI of the connecter that is to be verified - * @param nonce Nonce for freshness proof - * @return Returns the response of the attestation process - */ - CompletableFuture requestAttestation(String URI, int nonce); + /** + * Method to request attestation + * + * @param URI URI of the connecter that is to be verified + * @param nonce Nonce for freshness proof + * @return Returns the response of the attestation process + */ + fun requestAttestation(URI: String, nonce: Int): CompletableFuture } diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/external/package-info.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/external/package-info.java deleted file mode 100644 index e49dc22fd..000000000 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/external/package-info.java +++ /dev/null @@ -1,21 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * IDS Core Platform API - * %% - * Copyright (C) 2017 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -/** Application APIs to access functions towards the external IDS network. */ -package de.fhg.aisec.ids.api.external; diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/infomodel/ConnectorProfile.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/infomodel/ConnectorProfile.java deleted file mode 100644 index 96ec04975..000000000 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/infomodel/ConnectorProfile.java +++ /dev/null @@ -1,88 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-api - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.api.infomodel; - -import de.fraunhofer.iais.eis.SecurityProfile; -import de.fraunhofer.iais.eis.util.TypedLiteral; - -import java.io.Serializable; -import java.net.URI; -import java.util.List; - -public final class ConnectorProfile implements Serializable { - - private static final long serialVersionUID = 2L; - - private SecurityProfile securityProfile; - private URI connectorUrl; - private URI maintainerUrl; - private List connectorEntityNames; - - public ConnectorProfile() { - this.securityProfile = SecurityProfile.TRUST_SECURITY_PROFILE; - this.connectorUrl = null; - this.maintainerUrl = null; - this.connectorEntityNames = null; - } - - public ConnectorProfile( - SecurityProfile profile, - URI connectorUrl, - URI maintainerUrl, - List connectorEntityNames) { - super(); - this.securityProfile = profile; - this.connectorUrl = connectorUrl; - this.maintainerUrl = maintainerUrl; - this.connectorEntityNames = connectorEntityNames; - } - - public SecurityProfile getSecurityProfile() { - return securityProfile; - } - - public URI getConnectorUrl() { - return connectorUrl; - } - - public URI getMaintainerUrl() { - return maintainerUrl; - } - - public List getConnectorEntityNames() { - return connectorEntityNames; - } - - public void setSecurityProfile(SecurityProfile securityProfile) { - this.securityProfile = securityProfile; - } - - public void setConnectorUrl(URI connectorUrl) { - this.connectorUrl = connectorUrl; - } - - public void setMaintainerUrl(URI maintainerUrl) { - this.maintainerUrl = maintainerUrl; - } - - public void setConnectorEntityNames(List connectorEntityNames) { - this.connectorEntityNames = connectorEntityNames; - } -} diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/infomodel/ConnectorProfile.kt b/ids-api/src/main/java/de/fhg/aisec/ids/api/infomodel/ConnectorProfile.kt new file mode 100644 index 000000000..174b4f758 --- /dev/null +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/infomodel/ConnectorProfile.kt @@ -0,0 +1,55 @@ +/*- + * ========================LICENSE_START================================= + * ids-api + * %% + * Copyright (C) 2019 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.api.infomodel + +import de.fraunhofer.iais.eis.SecurityProfile +import de.fraunhofer.iais.eis.util.TypedLiteral +import java.io.Serializable +import java.net.URI + +class ConnectorProfile : Serializable { + var securityProfile: SecurityProfile? + var connectorUrl: URI? + var maintainerUrl: URI? + var connectorEntityNames: List? + + constructor() { + securityProfile = SecurityProfile.TRUST_SECURITY_PROFILE + connectorUrl = null + maintainerUrl = null + connectorEntityNames = null + } + + constructor( + profile: SecurityProfile?, + connectorUrl: URI?, + maintainerUrl: URI?, + connectorEntityNames: List? + ) : super() { + securityProfile = profile + this.connectorUrl = connectorUrl + this.maintainerUrl = maintainerUrl + this.connectorEntityNames = connectorEntityNames + } + + companion object { + private const val serialVersionUID = 2L + } +} diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/internal/package-info.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/internal/package-info.java deleted file mode 100644 index fd37f8713..000000000 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/internal/package-info.java +++ /dev/null @@ -1,21 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * IDS Core Platform API - * %% - * Copyright (C) 2017 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -/** Application APIs to access functions towards the internal Core Platform. */ -package de.fhg.aisec.ids.api.internal; diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/package-info.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/package-info.java deleted file mode 100644 index 0a05a66de..000000000 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/package-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * IDS Core Platform API - * %% - * Copyright (C) 2017 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -/** - * Internal OSGi service API of the Core Platform. - * - *

APIs in this package are exposed as OSGi services and accessible by all bundles in the Core - * Platform. Components of the Connector must provide implementations of these APIs. - */ -package de.fhg.aisec.ids.api; diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/policy/DecisionRequest.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/policy/DecisionRequest.java deleted file mode 100644 index 56b90222e..000000000 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/policy/DecisionRequest.java +++ /dev/null @@ -1,122 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-api - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.api.policy; - -import org.checkerframework.checker.nullness.qual.NonNull; -import org.checkerframework.checker.nullness.qual.Nullable; - -import java.util.Map; -import java.util.Objects; -import java.util.Set; - -/** - * Data structure holding a decision request which is sent to the PDP. The PDP is expected to answer - * with a PolicyDecision object. - * - * @author Julian Schütte (julian.schuette@aisec.fraunhofer.de) - */ -public class DecisionRequest { - /** The processor that data is received from */ - @NonNull private ServiceNode from; - - /** The Processor that the data is to be sent to */ - @NonNull private ServiceNode to; - - /** Properties of the message (e.g., labels) */ - @NonNull private Set labels; - - /** Properties of the environment */ - @Nullable private Map envCtx; - - public DecisionRequest( - @NonNull ServiceNode from, - @NonNull ServiceNode to, - @NonNull Set labels, - @Nullable Map envCtx) { - super(); - this.from = from; - this.to = to; - this.labels = labels; - this.envCtx = envCtx; - } - - /** - * Returns the source, i.e. the origin of the communication for which a decision is requested. - * - * @return The processor that data is received from - */ - @NonNull - public ServiceNode getFrom() { - return from; - } - - /** - * Returns the sink, i.e. the endpoint of the communication for which a decision is requested. - * - * @return The Processor that the data is to be sent to - */ - @NonNull - public ServiceNode getTo() { - return to; - } - - /** - * A decision context may hold additional information about the message/event. It is passed as - * attributes to the PDP. - * - *

The context may include - timestamps - route ids - etc. - * - * @return Properties of the Exchange - */ - @NonNull - public Set getLabels() { - return labels; - } - - /** - * A decision context may hold additional information about the overall system environment of the - * PEP.. It is passed as attributes to the PDP. - * - *

The context may include - a reference to previously taken decisions for the sake of caching - * - a reason for the request - identifiers of available components - etc. - * - * @return Additional environment properties - */ - @Nullable - public Map getEnvironmentCtx() { - return envCtx; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - DecisionRequest that = (DecisionRequest) o; - return Objects.equals(from, that.from) - && Objects.equals(to, that.to) - && Objects.equals(labels, that.labels) - && Objects.equals(envCtx, that.envCtx); - } - - @Override - public int hashCode() { - return Objects.hash(from, to, labels, envCtx); - } -} diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/RouteResult.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/policy/DecisionRequest.kt similarity index 56% rename from ids-api/src/main/java/de/fhg/aisec/ids/api/RouteResult.java rename to ids-api/src/main/java/de/fhg/aisec/ids/api/policy/DecisionRequest.kt index c282daadc..2e3026c4e 100644 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/RouteResult.java +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/policy/DecisionRequest.kt @@ -17,27 +17,21 @@ * limitations under the License. * =========================LICENSE_END================================== */ -package de.fhg.aisec.ids.api; +package de.fhg.aisec.ids.api.policy -import de.fhg.aisec.ids.api.router.RouteObject; -import org.checkerframework.checker.nullness.qual.NonNull; -import org.checkerframework.checker.nullness.qual.Nullable; - -public class RouteResult extends Result { - private RouteObject route; - - public RouteResult() {} - - public RouteResult(boolean success, @NonNull String msg, @Nullable RouteObject route) { - super(success, msg); - this.route = route; - } - - public RouteObject getRoute() { - return route; - } - - public void setRoute(@Nullable RouteObject route) { - this.route = route; - } -} +/** + * Data structure holding a decision request which is sent to the PDP. The PDP is expected to answer + * with a PolicyDecision object. + * + * @author Julian Schütte (julian.schuette@aisec.fraunhofer.de) + */ +data class DecisionRequest( + /** The processor that data is received from */ + val from: ServiceNode, + /** The Processor that the data is to be sent to */ + val to: ServiceNode, + /** Properties of the message (e.g., labels) */ + val labels: Set, + /** Properties of the environment */ + val environmentCtx: Map? +) diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/policy/Obligation.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/policy/Obligation.java deleted file mode 100644 index 79bf3bb76..000000000 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/policy/Obligation.java +++ /dev/null @@ -1,50 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-api - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.api.policy; - -public class Obligation { - private String action; - private PolicyDecision.Decision alternativeDecision; - - public Obligation() { - super(); - } - - public Obligation(String action, PolicyDecision.Decision alternativeDecision) { - this.action = action; - this.alternativeDecision = alternativeDecision; - } - - public String getAction() { - return action; - } - - public void setAction(String action) { - this.action = action; - } - - public PolicyDecision.Decision getAlternativeDecision() { - return alternativeDecision; - } - - public void setAlternativeDecision(PolicyDecision.Decision alternativeDecision) { - this.alternativeDecision = alternativeDecision; - } -} diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/policy/Obligation.kt b/ids-api/src/main/java/de/fhg/aisec/ids/api/policy/Obligation.kt new file mode 100644 index 000000000..793b5ae68 --- /dev/null +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/policy/Obligation.kt @@ -0,0 +1,25 @@ +/*- + * ========================LICENSE_START================================= + * ids-api + * %% + * Copyright (C) 2019 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.api.policy + +class Obligation( + var action: String? = null, + var alternativeDecision: PolicyDecision.Decision? = null +) diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/policy/PAP.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/policy/PAP.kt similarity index 53% rename from ids-api/src/main/java/de/fhg/aisec/ids/api/policy/PAP.java rename to ids-api/src/main/java/de/fhg/aisec/ids/api/policy/PAP.kt index bc53fa882..ace0699bb 100644 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/policy/PAP.java +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/policy/PAP.kt @@ -17,39 +17,33 @@ * limitations under the License. * =========================LICENSE_END================================== */ -package de.fhg.aisec.ids.api.policy; +package de.fhg.aisec.ids.api.policy -import de.fhg.aisec.ids.api.router.RouteVerificationProof; -import java.util.List; -import org.checkerframework.checker.nullness.qual.NonNull; -import org.checkerframework.checker.nullness.qual.Nullable; +import de.fhg.aisec.ids.api.router.RouteVerificationProof /** * Policy Administration Point Interface. * * @author Julian Schütte (julian.schuette@aisec.fraunhofer.de) */ -public interface PAP { +interface PAP { + /** + * Loads a policy into the registered PDPs. + * + * @param theory The policy theory to load + */ + fun loadPolicy(theory: String) - /** - * Loads a policy into the registered PDPs. - * - * @param theory The policy theory to load - */ - void loadPolicy(@Nullable String theory); - - /** - * Returns the currently active policy in its string representation. - * - *

The representation depends on the implementation and can be XML, JSON or any other - * serialization. - * - * @return Active policy as prolog - */ - String getPolicy(); - - List listRules(); - - @Nullable - RouteVerificationProof verifyRoute(@NonNull String routeId); + /** + * Returns the currently active policy in its string representation. + * + * + * The representation depends on the implementation and can be XML, JSON or any other + * serialization. + * + * @return Active policy as prolog + */ + val policy: String + fun listRules(): List + fun verifyRoute(routeId: String): RouteVerificationProof? } diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/policy/PDP.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/policy/PDP.java deleted file mode 100644 index 20d523564..000000000 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/policy/PDP.java +++ /dev/null @@ -1,61 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-api - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.api.policy; - -import org.checkerframework.checker.nullness.qual.NonNull; - -/** - * Policy Decision Point (PDP) Interface. - * - *

The PDP decides decision requests against a policy. It may use caching to speed up the - * decision. - * - * @author Julian Schütte (julian.schuette@aisec.fraunhofer.de) - */ -public interface PDP { - /** - * Main method for requesting a policy decision. - * - *

The decision request states attributes of subject and resource. The result is a decision - * that is expected to be enforced by the PEP. - * - * @param req The decision request, wrapping relevant data for policy decision - * @return The policy decision - */ - @NonNull - PolicyDecision requestDecision(DecisionRequest req); - - /** Removes all data from PDP-internal caches. Future decisions will possibly take more time. */ - void clearAllCaches(); - - /** - * Requests the PDP for the result of applying a transformation function to a message. - * - *

Transformation functions remove and/or add labels to messages. For non-flow-aware services, - * transformation functions are defined as part of the policy. - * - *

A transformation function must always applied to a message before the policy decision is - * requested using requestDecision. - * - * @param lastServiceNode The last Processor the message exchange has processed - * @return The label transformations to apply to the Exchange - */ - TransformationDecision requestTranformations(ServiceNode lastServiceNode); -} diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/policy/PDP.kt b/ids-api/src/main/java/de/fhg/aisec/ids/api/policy/PDP.kt new file mode 100644 index 000000000..b192e6681 --- /dev/null +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/policy/PDP.kt @@ -0,0 +1,62 @@ +/*- + * ========================LICENSE_START================================= + * ids-api + * %% + * Copyright (C) 2019 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.api.policy + +/** + * Policy Decision Point (PDP) Interface. + * + * + * The PDP decides decision requests against a policy. It may use caching to speed up the + * decision. + * + * @author Julian Schütte (julian.schuette@aisec.fraunhofer.de) + */ +interface PDP { + /** + * Main method for requesting a policy decision. + * + * + * The decision request states attributes of subject and resource. The result is a decision + * that is expected to be enforced by the PEP. + * + * @param req The decision request, wrapping relevant data for policy decision + * @return The policy decision + */ + fun requestDecision(req: DecisionRequest): PolicyDecision + + /** Removes all data from PDP-internal caches. Future decisions will possibly take more time. */ + fun clearAllCaches() + + /** + * Requests the PDP for the result of applying a transformation function to a message. + * + * + * Transformation functions remove and/or add labels to messages. For non-flow-aware services, + * transformation functions are defined as part of the policy. + * + * + * A transformation function must always applied to a message before the policy decision is + * requested using `requestDecision`. + * + * @param lastServiceNode The last Processor the message exchange has processed + * @return The label transformations to apply to the Exchange + */ + fun requestTranformations(lastServiceNode: ServiceNode): TransformationDecision +} diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/policy/PolicyDecision.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/policy/PolicyDecision.java deleted file mode 100644 index 3f1b1cffa..000000000 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/policy/PolicyDecision.java +++ /dev/null @@ -1,63 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-api - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.api.policy; - -import java.util.Collections; -import java.util.List; - -/** - * Bean representing the decision of a Policy Decision Point (PDP). - * - * @author Julian Schuette (julian.schuette@aisec.fraunhofer.de) - */ -public class PolicyDecision { - public enum Decision { - ALLOW, - DENY - } - - private String reason = "Default deny"; - private Decision decision = Decision.DENY; - private List obligations = Collections.emptyList(); - - public String getReason() { - return reason; - } - - public List getObligations() { - return obligations; - } - - public void setObligations(List obligation) { - this.obligations = obligation; - } - - public void setReason(String reason) { - this.reason = reason; - } - - public Decision getDecision() { - return decision; - } - - public void setDecision(Decision decision) { - this.decision = decision; - } -} diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/internal/ComponentNotAvailableException.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/policy/PolicyDecision.kt similarity index 74% rename from ids-api/src/main/java/de/fhg/aisec/ids/api/internal/ComponentNotAvailableException.java rename to ids-api/src/main/java/de/fhg/aisec/ids/api/policy/PolicyDecision.kt index e794f6fac..263df1038 100644 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/internal/ComponentNotAvailableException.java +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/policy/PolicyDecision.kt @@ -17,14 +17,19 @@ * limitations under the License. * =========================LICENSE_END================================== */ -package de.fhg.aisec.ids.api.internal; +package de.fhg.aisec.ids.api.policy /** - * This exception is thrown when an internal component, i.e. an OSGi service or bundle is not - * available at runtime. + * Bean representing the decision of a Policy Decision Point (PDP). * * @author Julian Schuette (julian.schuette@aisec.fraunhofer.de) */ -public class ComponentNotAvailableException extends RuntimeException { - private static final long serialVersionUID = -1195665246923819469L; +class PolicyDecision { + enum class Decision { + ALLOW, DENY + } + + var reason = "Default deny" + var decision = Decision.DENY + var obligations: List = emptyList() } diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/policy/ServiceNode.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/policy/ServiceNode.java deleted file mode 100644 index 62b662258..000000000 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/policy/ServiceNode.java +++ /dev/null @@ -1,76 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-api - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.api.policy; - -import java.util.Collections; -import java.util.Objects; -import java.util.Set; - -public class ServiceNode { - private String endpoint; - private Set properties; - private Set capabilities; - - public ServiceNode(String endpoint, Set properties, Set capabilities) { - super(); - this.endpoint = endpoint; - this.properties = properties != null ? properties : Collections.emptySet(); - this.capabilities = capabilities != null ? capabilities : Collections.emptySet(); - } - - public String getEndpoint() { - return endpoint; - } - - public void setEndpoint(String endpoint) { - this.endpoint = endpoint; - } - - public Set getProperties() { - return properties; - } - - public void setProperties(Set properties) { - this.properties = properties; - } - - public Set getCapabilties() { - return capabilities; - } - - public void setCapabilities(Set capabilities) { - this.capabilities = capabilities; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - ServiceNode that = (ServiceNode) o; - return Objects.equals(endpoint, that.endpoint) - && Objects.equals(properties, that.properties) - && Objects.equals(capabilities, that.capabilities); - } - - @Override - public int hashCode() { - return Objects.hash(endpoint, properties, capabilities); - } -} diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/policy/ServiceNode.kt b/ids-api/src/main/java/de/fhg/aisec/ids/api/policy/ServiceNode.kt new file mode 100644 index 000000000..fafd67e92 --- /dev/null +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/policy/ServiceNode.kt @@ -0,0 +1,26 @@ +/*- + * ========================LICENSE_START================================= + * ids-api + * %% + * Copyright (C) 2019 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.api.policy + +data class ServiceNode( + var endpoint: String, + var properties: Set = emptySet(), + var capabilities: Set = emptySet() +) diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/policy/TransformationDecision.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/policy/TransformationDecision.java deleted file mode 100644 index 04d993a05..000000000 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/policy/TransformationDecision.java +++ /dev/null @@ -1,72 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-api - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.api.policy; - -import java.util.HashSet; -import java.util.Set; - -/** - * Represents the result of a transformation function as returned by the policy decision point - * (PDP). - * - *

The TransformationDecision defines labels which must be added to or removed from a message. - * - * @author Julian Schuette (julian.schuette@aisec.fraunhofer.de) - */ -public class TransformationDecision { - private final Set labelsToAdd; - private final Set labelsToRemove; - - public TransformationDecision() { - this.labelsToAdd = new HashSet<>(); - this.labelsToRemove = new HashSet<>(); - } - - @SuppressWarnings("unused") - public TransformationDecision(Set labelsToAdd, Set labelsToRemove) { - super(); - if (labelsToAdd == null) { - labelsToAdd = new HashSet<>(); - } - if (labelsToRemove == null) { - labelsToRemove = new HashSet<>(); - } - this.labelsToAdd = labelsToAdd; - this.labelsToRemove = labelsToRemove; - } - - /** - * Returns a (possibly empty, but never null) set of labels that must be added to a message. - * - * @return Labels to add to the data in this processing step - */ - public Set getLabelsToAdd() { - return labelsToAdd; - } - - /** - * Returns a (possibly empty, but never null) set of labels that must be removed from a message. - * - * @return Labels to remove from the data in this processing step - */ - public Set getLabelsToRemove() { - return labelsToRemove; - } -} diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/conm/RatResult.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/policy/TransformationDecision.kt similarity index 52% rename from ids-api/src/main/java/de/fhg/aisec/ids/api/conm/RatResult.java rename to ids-api/src/main/java/de/fhg/aisec/ids/api/policy/TransformationDecision.kt index 0c1b4f61d..696a37eeb 100644 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/conm/RatResult.java +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/policy/TransformationDecision.kt @@ -17,39 +17,29 @@ * limitations under the License. * =========================LICENSE_END================================== */ -package de.fhg.aisec.ids.api.conm; - -import org.checkerframework.checker.nullness.qual.NonNull; -import org.checkerframework.checker.nullness.qual.Nullable; +package de.fhg.aisec.ids.api.policy /** - * Result of a remote attestation between peers. + * Represents the result of a transformation function as returned by the policy decision point + * (PDP). + * + * + * The TransformationDecision defines labels which must be added to or removed from a message. * * @author Julian Schuette (julian.schuette@aisec.fraunhofer.de) */ -public class RatResult { - public enum Status { - FAILED, - SUCCESS - } - - private @NonNull Status status; - private @Nullable String reason; - - public RatResult(@NonNull Status status, @Nullable String reason) { - this.status = status; - if (reason != null) { - this.reason = reason; - } else { - this.reason = ""; - } - } - - public Status getStatus() { - return status; - } +class TransformationDecision( + /** + * Returns a (possibly empty, but never null) set of labels that must be added to a message. + * + * @return Labels to add to the data in this processing step + */ + val labelsToAdd: MutableSet = mutableSetOf(), - public String getReason() { - return reason; - } -} + /** + * Returns a (possibly empty, but never null) set of labels that must be removed from a message. + * + * @return Labels to remove from the data in this processing step + */ + val labelsToRemove: MutableSet = mutableSetOf() +) diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/policy/package-info.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/policy/package-info.java deleted file mode 100644 index c2a83bfec..000000000 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/policy/package-info.java +++ /dev/null @@ -1,21 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * IDS Core Platform API - * %% - * Copyright (C) 2017 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -/** APIs for managing access- and usage control policies. */ -package de.fhg.aisec.ids.api.policy; diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/router/CounterExample.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/router/CounterExample.java deleted file mode 100644 index fdc97399a..000000000 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/router/CounterExample.java +++ /dev/null @@ -1,48 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-api - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.api.router; - -import java.util.List; - -public abstract class CounterExample { - private String explanation; - private List steps; - - public String getExplanation() { - return explanation; - } - - public List getSteps() { - return steps; - } - - @Override - public String toString() { - return "Explanation: " + explanation + "\n" + String.join("\n|-- ", steps); - } - - protected void setExplanation(String explanation) { - this.explanation = explanation; - } - - protected void setSteps(List steps) { - this.steps = steps; - } -} diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/acme/AcmeClient.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/router/CounterExample.kt similarity index 67% rename from ids-api/src/main/java/de/fhg/aisec/ids/api/acme/AcmeClient.java rename to ids-api/src/main/java/de/fhg/aisec/ids/api/router/CounterExample.kt index b0a1354f9..6333aead7 100644 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/acme/AcmeClient.java +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/router/CounterExample.kt @@ -17,17 +17,18 @@ * limitations under the License. * =========================LICENSE_END================================== */ -package de.fhg.aisec.ids.api.acme; +package de.fhg.aisec.ids.api.router -import java.net.URI; -import java.nio.file.Path; +abstract class CounterExample { + var explanation: String? = null + protected set + var steps: List? = null + protected set -public interface AcmeClient { - - String getChallengeAuthorization(String challenge); - - void renewCertificate( - Path targetDirectory, URI acmeServerUri, String[] domains, int challengePort); - - AcmeTermsOfService getTermsOfService(URI acmeServerUri); + override fun toString(): String { + return """ + Explanation: $explanation + ${java.lang.String.join("\n|-- ", steps)} + """.trimIndent() + } } diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/router/RouteComponent.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/router/RouteComponent.kt similarity index 71% rename from ids-api/src/main/java/de/fhg/aisec/ids/api/router/RouteComponent.java rename to ids-api/src/main/java/de/fhg/aisec/ids/api/router/RouteComponent.kt index 90d251d6d..61caa9cb3 100644 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/router/RouteComponent.java +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/router/RouteComponent.kt @@ -17,7 +17,7 @@ * limitations under the License. * =========================LICENSE_END================================== */ -package de.fhg.aisec.ids.api.router; +package de.fhg.aisec.ids.api.router /** * Representation of a "route component", i.e. a protocol adapter to attach route endpoints to @@ -25,24 +25,18 @@ * * @author Julian Schuette (julian.schuette@aisec.fraunhofer.de) */ -public class RouteComponent { - private String bundle; - private String description; +class RouteComponent { + var bundle: String? = null + private set + var description: String? = null + private set - public RouteComponent() { - /* Bean std c'tor */ - } + constructor() { + /* Bean std c'tor */ + } - public RouteComponent(String bundleName, String description) { - this.bundle = bundleName; - this.description = description; - } - - public String getBundle() { - return bundle; - } - - public String getDescription() { - return description; - } + constructor(bundleName: String?, description: String?) { + bundle = bundleName + this.description = description + } } diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/router/RouteException.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/router/RouteException.kt similarity index 74% rename from ids-api/src/main/java/de/fhg/aisec/ids/api/router/RouteException.java rename to ids-api/src/main/java/de/fhg/aisec/ids/api/router/RouteException.kt index 3d8f85433..1e1a9e81d 100644 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/router/RouteException.java +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/router/RouteException.kt @@ -17,17 +17,15 @@ * limitations under the License. * =========================LICENSE_END================================== */ -package de.fhg.aisec.ids.api.router; +package de.fhg.aisec.ids.api.router -/** @author Julian Schuette (julian.schuette@aisec.fraunhofer.de) */ -public class RouteException extends Exception { - private static final long serialVersionUID = 3684021422039489488L; - - public RouteException(Throwable cause) { - super(cause); - } +/** @author Julian Schuette (julian.schuette@aisec.fraunhofer.de) + */ +class RouteException : Exception { + constructor(cause: Throwable) : super(cause) + constructor(msg: String) : super(msg) - public RouteException(String msg) { - super(msg); - } + companion object { + private const val serialVersionUID = 3684021422039489488L + } } diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/router/RouteManager.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/router/RouteManager.java deleted file mode 100644 index 570592528..000000000 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/router/RouteManager.java +++ /dev/null @@ -1,169 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-api - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.api.router; - -import org.checkerframework.checker.nullness.qual.NonNull; -import org.checkerframework.checker.nullness.qual.Nullable; - -import java.util.Collection; -import java.util.List; -import java.util.Map; - -/** - * Interface of internal routing manager inside the Core Platform. - * - *

The routing manager is responsible for forwarding messages between containers. One - * implementation of this interface is based on Apache Camel, others might follow. - * - * @author Julian Schuette (julian.schuette@aisec.fraunhofer.de) - */ -public interface RouteManager { - - /** - * Returns a list of currently installed routes. - * - * @return All installed rules - */ - @NonNull - List getRoutes(); - - /** - * Returns a RouteObject for a given route ID. - * - * @param id The ID of the route to fetch - * @return The queried route or null - */ - @Nullable - RouteObject getRoute(@NonNull String id); - - /** - * Starts a route. - * - * @param routeId ID of the route to start - * @throws RouteException If starting the route failed - */ - void startRoute(@NonNull String routeId) throws RouteException; - - /** - * Sends a request to stop a route. Camel will try to gracefully shut down the route and deliver - * pending exchanges. - * - * @param routeId ID of the route to stop - * @throws RouteException If stopping the route failed - */ - void stopRoute(@NonNull String routeId) throws RouteException; - - /** - * List all supported components, i.e. supported endpoint protocols. - * - * @return List of supported components - */ - @NonNull - List listComponents(); - - /** - * List all route endpoints, i.e. all URIs of routes existing in loaded Camel contexts - * - * @return Map of Camel context names to contained endpoint URIs - */ - @NonNull - Map> getEndpoints(); - - @NonNull - Map listEndpoints(); - - /** - * Save a route, replacing it with a new representation within the same context - * - * @param routeId ID of the route to save - * @param routeRepresentation The new textual representation of the route (XML etc.) - * @return The object representing the modified route - * @throws RouteException If the route does not exist or some Exception was thrown during route - * replacement. - */ - @NonNull - RouteObject saveRoute(@NonNull String routeId, @NonNull String routeRepresentation) - throws RouteException; - - /** - * Adds a route and starts it. - * - *

Endpoint declarations must be supported by the underlying implementation. - * - *

If the route id already exists, this method will throw a RouteException and not overwrite - * the existing route. - * - * @param routeDefinition Textual representation of the route (XML etc.) - * @throws RouteException if a route with the same id already exists or if any Exception is thrown - * during loading and starting the route. - */ - void addRoute(@NonNull String routeDefinition) throws RouteException; - - /** - * Removes a route from one endpoint to another. - * - *

The deletion becomes immediately effective. - * - *

Endpoint declarations must be supported by the underlying implementation. - * - * @param routeId ID of the route to delete - */ - @SuppressWarnings("unused") - void delRoute(@NonNull String routeId); - - /** - * Returns the given route in its original representation of the implementing engine. - * - *

Note that this method may return null if the implementing engine does not support a textual - * route configuration. - * - *

For Apache Camel, this method will return the XML-based Camel DSL configuration file. - * - * @param routeId ID of the route to retrieve the String representation for - * @return String representation of the route - */ - String getRouteAsString(@NonNull String routeId); - - /** - * Returns a List of URIs of the given route's inputs (from definitions) - * - * @param routeId The identifier of the route - * @return The from (input) URIs of the route - */ - @NonNull - List getRouteInputUris(@NonNull String routeId); - - /** - * Returns aggregated runtime metrics of all installed routes. - * - * @return Map<k,v> where k is a string indicating the route id. - */ - @NonNull - Map getRouteMetrics(); - - /** - * Returns the given route configuration in a Prolog representation. - * - * @param routeId ID of route to retrieve prolog representation for - * @return Route represented as prolog - */ - @NonNull - String getRouteAsProlog(@NonNull String routeId); -} diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/router/RouteManager.kt b/ids-api/src/main/java/de/fhg/aisec/ids/api/router/RouteManager.kt new file mode 100644 index 000000000..1e75eaefa --- /dev/null +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/router/RouteManager.kt @@ -0,0 +1,160 @@ +/*- + * ========================LICENSE_START================================= + * ids-api + * %% + * Copyright (C) 2019 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.api.router + +/** + * Interface of internal routing manager inside the Core Platform. + * + * + * The routing manager is responsible for forwarding messages between containers. One + * implementation of this interface is based on Apache Camel, others might follow. + * + * @author Julian Schuette (julian.schuette@aisec.fraunhofer.de) + */ +interface RouteManager { + /** + * Returns a list of currently installed routes. + * + * @return All installed rules + */ + val routes: List + + /** + * Returns a RouteObject for a given route ID. + * + * @param id The ID of the route to fetch + * @return The queried route or null + */ + fun getRoute(id: String): RouteObject? + + /** + * Starts a route. + * + * @param routeId ID of the route to start + * @throws RouteException If starting the route failed + */ + @Throws(RouteException::class) + fun startRoute(routeId: String) + + /** + * Sends a request to stop a route. Camel will try to gracefully shut down the route and deliver + * pending exchanges. + * + * @param routeId ID of the route to stop + * @throws RouteException If stopping the route failed + */ + @Throws(RouteException::class) + fun stopRoute(routeId: String) + + /** + * List all supported components, i.e. supported endpoint protocols. + * + * @return List of supported components + */ + fun listComponents(): List + + /** + * List all route endpoints, i.e. all URIs of routes existing in loaded Camel contexts + * + * @return Map of Camel context names to contained endpoint URIs + */ + val endpoints: Map> + fun listEndpoints(): Map + + /** + * Save a route, replacing it with a new representation within the same context + * + * @param routeId ID of the route to save + * @param routeRepresentation The new textual representation of the route (XML etc.) + * @return The object representing the modified route + * @throws RouteException If the route does not exist or some Exception was thrown during route + * replacement. + */ + @Throws(RouteException::class) + fun saveRoute(routeId: String, routeRepresentation: String): RouteObject + + /** + * Adds a route and starts it. + * + * + * Endpoint declarations must be supported by the underlying implementation. + * + * + * If the route id already exists, this method will throw a RouteException and not overwrite + * the existing route. + * + * @param routeDefinition Textual representation of the route (XML etc.) + * @throws RouteException if a route with the same id already exists or if any Exception is thrown + * during loading and starting the route. + */ + @Throws(RouteException::class) + fun addRoute(routeDefinition: String) + + /** + * Removes a route from one endpoint to another. + * + * + * The deletion becomes immediately effective. + * + * + * Endpoint declarations must be supported by the underlying implementation. + * + * @param routeId ID of the route to delete + */ + fun delRoute(routeId: String) + + /** + * Returns the given route in its original representation of the implementing engine. + * + * + * Note that this method may return null if the implementing engine does not support a textual + * route configuration. + * + * + * For Apache Camel, this method will return the XML-based Camel DSL configuration file. + * + * @param routeId ID of the route to retrieve the String representation for + * @return String representation of the route + */ + fun getRouteAsString(routeId: String): String? + + /** + * Returns a List of URIs of the given route's inputs (from definitions) + * + * @param routeId The identifier of the route + * @return The from (input) URIs of the route + */ + fun getRouteInputUris(routeId: String): List + + /** + * Returns aggregated runtime metrics of all installed routes. + * + * @return Map<k,v> where k is a string indicating the route id. + */ + val routeMetrics: Map + + /** + * Returns the given route configuration in a Prolog representation. + * + * @param routeId ID of route to retrieve prolog representation for + * @return Route represented as prolog + */ + fun getRouteAsProlog(routeId: String): String +} diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/router/RouteMetrics.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/router/RouteMetrics.java deleted file mode 100644 index ce044dbcd..000000000 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/router/RouteMetrics.java +++ /dev/null @@ -1,100 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-api - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.api.router; - -/** - * Metrics of a single route. - * - * @author Julian Schuette (julian.schuette@aisec.fraunhofer.de) - */ -public class RouteMetrics { - private long completed; - private long failed; - private long inflight; - private long failuresHandled; - private long redeliveries; - private long maxProcessingTime; - private long meanProcessingTime; - private long minProcessingTime; - - public long getCompleted() { - return completed; - } - - public long getFailed() { - return failed; - } - - public long getInflight() { - return inflight; - } - - public long getFailuresHandled() { - return failuresHandled; - } - - public long getRedeliveries() { - return redeliveries; - } - - public long getMaxProcessingTime() { - return maxProcessingTime; - } - - public long getMeanProcessingTime() { - return meanProcessingTime; - } - - public long getMinProcessingTime() { - return minProcessingTime; - } - - public void setCompleted(long completed) { - this.completed = completed; - } - - public void setFailed(long failed) { - this.failed = failed; - } - - public void setInflight(long inflight) { - this.inflight = inflight; - } - - public void setFailuresHandled(long failuresHandled) { - this.failuresHandled = failuresHandled; - } - - public void setRedeliveries(long redeliveries) { - this.redeliveries = redeliveries; - } - - public void setMaxProcessingTime(long maxProcessingTime) { - this.maxProcessingTime = maxProcessingTime; - } - - public void setMeanProcessingTime(long meanProcessingTime) { - this.meanProcessingTime = meanProcessingTime; - } - - public void setMinProcessingTime(long minProcessingTime) { - this.minProcessingTime = minProcessingTime; - } -} diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/router/RouteMetrics.kt b/ids-api/src/main/java/de/fhg/aisec/ids/api/router/RouteMetrics.kt new file mode 100644 index 000000000..b217b8abd --- /dev/null +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/router/RouteMetrics.kt @@ -0,0 +1,36 @@ +/*- + * ========================LICENSE_START================================= + * ids-api + * %% + * Copyright (C) 2019 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.api.router + +/** + * Metrics of a single route. + * + * @author Julian Schuette (julian.schuette@aisec.fraunhofer.de) + */ +class RouteMetrics { + var completed: Long = 0 + var failed: Long = 0 + var inflight: Long = 0 + var failuresHandled: Long = 0 + var redeliveries: Long = 0 + var maxProcessingTime: Long = 0 + var meanProcessingTime: Long = 0 + var minProcessingTime: Long = 0 +} diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/router/RouteObject.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/router/RouteObject.java deleted file mode 100644 index f00e8248f..000000000 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/router/RouteObject.java +++ /dev/null @@ -1,112 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-api - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.api.router; - -/** - * Bean representing a "route" (e.g., an Apache Camel route) - * - * @author Julian Schuette (julian.schuette@aisec.fraunhofer.de) - */ -public class RouteObject { - private String status; - private long uptime; - private String context; - private String shortName; - private String dot; - private String description; - private String id; - - public RouteObject() { - /* Bean std c'tor */ - } - - public RouteObject( - String id, - String description, - String dot, - String shortName, - String context, - long uptime, - String status) { - this.id = id; - this.description = description; - this.dot = dot; - this.shortName = shortName; - this.context = context; - this.uptime = uptime; - this.status = status; - } - - public String getStatus() { - return status; - } - - public long getUptime() { - return uptime; - } - - public String getContext() { - return context; - } - - public String getShortName() { - return shortName; - } - - public String getDot() { - return dot; - } - - public String getDescription() { - return description; - } - - public String getId() { - return id; - } - - public void setStatus(String status) { - this.status = status; - } - - public void setUptime(long uptime) { - this.uptime = uptime; - } - - public void setContext(String context) { - this.context = context; - } - - public void setShortName(String shortName) { - this.shortName = shortName; - } - - public void setDot(String dot) { - this.dot = dot; - } - - public void setDescription(String description) { - this.description = description; - } - - public void setId(String id) { - this.id = id; - } -} diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/router/RouteObject.kt b/ids-api/src/main/java/de/fhg/aisec/ids/api/router/RouteObject.kt new file mode 100644 index 000000000..b54165840 --- /dev/null +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/router/RouteObject.kt @@ -0,0 +1,57 @@ +/*- + * ========================LICENSE_START================================= + * ids-api + * %% + * Copyright (C) 2019 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.api.router + +/** + * Bean representing a "route" (e.g., an Apache Camel route) + * + * @author Julian Schuette (julian.schuette@aisec.fraunhofer.de) + */ +class RouteObject { + var status: String? = null + var uptime: Long = 0 + var context: String? = null + var shortName: String? = null + var dot: String? = null + var description: String? = null + var id: String? = null + + constructor() { + /* Bean std c'tor */ + } + + constructor( + id: String?, + description: String?, + dot: String?, + shortName: String?, + context: String?, + uptime: Long, + status: String? + ) { + this.id = id + this.description = description + this.dot = dot + this.shortName = shortName + this.context = context + this.uptime = uptime + this.status = status + } +} diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/router/RouteVerificationProof.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/router/RouteVerificationProof.java deleted file mode 100644 index 6ac70b6de..000000000 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/router/RouteVerificationProof.java +++ /dev/null @@ -1,96 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-api - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.api.router; - -import java.util.ArrayList; -import java.util.List; - -/** - * Representation of a proof that a route is valid under a policy, i.e. that the policy will never - * violate the policy. - * - *

If the route can violate the policy, a set of counterExamples is given. - * - *

The set is not necessarily complete and contains message paths which are valid in term of the - * route, but violate the policy. - * - * @author Julian Schuette (julian.schuette@aisec.fraunhofer.de) - */ -public class RouteVerificationProof { - private String routeId; - private long proofTimeNanos; - private boolean isValid = true; - private List counterExamples = new ArrayList<>(); - private String query = ""; - - public RouteVerificationProof(String routeId) { - if (routeId == null) { - throw new NullPointerException("routeId must not be null"); - } - this.routeId = routeId; - } - - public String getRouteId() { - return routeId; - } - - public long getProofTimeNanos() { - return proofTimeNanos; - } - - public void setProofTimeNanos(long proofTimeNanos) { - this.proofTimeNanos = proofTimeNanos; - } - - public boolean isValid() { - return isValid; - } - - public void setValid(boolean isValid) { - this.isValid = isValid; - } - - public List getCounterExamples() { - return counterExamples; - } - - public void setCounterExamples(List counterExamples) { - this.counterExamples = counterExamples; - } - - public void setQuery(String query) { - this.query = query; - } - - public String getQuery() { - return this.query; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("Proof for ").append(this.query).append(" is ").append(this.isValid ? "VALID" : "INVALID").append("\n") - .append("Example flows violating policy:\n"); - for (CounterExample ce : this.counterExamples) { - sb.append("|-- ").append(ce.toString()).append("\n\n"); - } - return sb.toString(); - } -} diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/router/RouteVerificationProof.kt b/ids-api/src/main/java/de/fhg/aisec/ids/api/router/RouteVerificationProof.kt new file mode 100644 index 000000000..094107285 --- /dev/null +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/router/RouteVerificationProof.kt @@ -0,0 +1,62 @@ +/*- + * ========================LICENSE_START================================= + * ids-api + * %% + * Copyright (C) 2019 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.api.router + +import java.lang.NullPointerException +import java.lang.StringBuilder +import java.util.ArrayList + +/** + * Representation of a proof that a route is valid under a policy, i.e. that the policy will never + * violate the policy. + * + * + * If the route can violate the policy, a set of counterExamples is given. + * + * + * The set is not necessarily complete and contains message paths which are valid in term of the + * route, but violate the policy. + * + * @author Julian Schuette (julian.schuette@aisec.fraunhofer.de) + */ +class RouteVerificationProof(routeId: String?) { + val routeId: String + var proofTimeNanos: Long = 0 + var isValid = true + var counterExamples: List = ArrayList() + var query = "" + + override fun toString(): String { + val sb = StringBuilder() + sb.append("Proof for ").append(query).append(" is ").append(if (isValid) "VALID" else "INVALID").append("\n") + .append("Example flows violating policy:\n") + for (ce in counterExamples) { + sb.append("|-- ").append(ce.toString()).append("\n\n") + } + return sb.toString() + } + + init { + if (routeId == null) { + throw NullPointerException("routeId must not be null") + } + this.routeId = routeId + } +} diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/router/graph/Edge.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/router/graph/Edge.java deleted file mode 100644 index ba206d36a..000000000 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/router/graph/Edge.java +++ /dev/null @@ -1,53 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-api - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.api.router.graph; - -import java.util.Objects; - -public class Edge { - private String source; - private String target; - - public Edge(String source, String target) { - this.source = source; - this.target = target; - } - - public String getSource() { - return source; - } - - public String getTarget() { - return target; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof Edge)) return false; - Edge edge = (Edge) o; - return Objects.equals(source, edge.source) && Objects.equals(target, edge.target); - } - - @Override - public int hashCode() { - return Objects.hash(source, target); - } -} diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/router/graph/Edge.kt b/ids-api/src/main/java/de/fhg/aisec/ids/api/router/graph/Edge.kt new file mode 100644 index 000000000..fae1445fa --- /dev/null +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/router/graph/Edge.kt @@ -0,0 +1,22 @@ +/*- + * ========================LICENSE_START================================= + * ids-api + * %% + * Copyright (C) 2019 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.api.router.graph + +data class Edge(val source: String, val target: String) diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/router/graph/GraphData.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/router/graph/GraphData.java deleted file mode 100644 index 2015986fe..000000000 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/router/graph/GraphData.java +++ /dev/null @@ -1,44 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-api - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.api.router.graph; - -import java.util.LinkedHashSet; -import java.util.Set; - -public class GraphData { - private Set nodes = new LinkedHashSet<>(); - private Set links = new LinkedHashSet<>(); - - public void addNode(Node node) { - nodes.add(node); - } - - public void addEdge(Edge edge) { - links.add(edge); - } - - public Set getNodes() { - return nodes; - } - - public Set getLinks() { - return links; - } -} diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/settings/ConnectionSettings.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/router/graph/GraphData.kt similarity index 65% rename from ids-api/src/main/java/de/fhg/aisec/ids/api/settings/ConnectionSettings.java rename to ids-api/src/main/java/de/fhg/aisec/ids/api/router/graph/GraphData.kt index 7c297b7be..c7d58eab9 100644 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/settings/ConnectionSettings.java +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/router/graph/GraphData.kt @@ -17,21 +17,25 @@ * limitations under the License. * =========================LICENSE_END================================== */ -package de.fhg.aisec.ids.api.settings; +package de.fhg.aisec.ids.api.router.graph -import java.io.Serializable; +class GraphData { + private val nodes: MutableSet = LinkedHashSet() + private val links: MutableSet = LinkedHashSet() -public final class ConnectionSettings implements Serializable { - private static final long serialVersionUID = 1L; + fun addNode(node: Node) { + nodes.add(node) + } - private final String securityProfile; + fun addEdge(edge: Edge) { + links.add(edge) + } - public ConnectionSettings() { - securityProfile = "idsc:TRUSTED_CONNECTOR_SECURITY_PROFILE"; - } - - public String getRequiredSecurityProfile() { - return securityProfile; - } + fun getNodes(): Set { + return nodes + } + fun getLinks(): Set { + return links + } } diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/router/graph/Node.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/router/graph/Node.java deleted file mode 100644 index 60569df7e..000000000 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/router/graph/Node.java +++ /dev/null @@ -1,67 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-api - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.api.router.graph; - -import java.util.Objects; - -public class Node { - public enum NodeType { - EntryNode, - Node, - ChoiceNode - } - - private String name; - private String action; - private NodeType type; - - public Node(String name, String action, NodeType type) { - this.name = name; - this.action = action; - this.type = type; - } - - public String getName() { - return name; - } - - public String getAction() { - return action; - } - - public NodeType getType() { - return type; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof Node)) return false; - Node node = (Node) o; - return Objects.equals(name, node.name) - && Objects.equals(action, node.action) - && type == node.type; - } - - @Override - public int hashCode() { - return Objects.hash(name, action, type); - } -} diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/router/graph/Node.kt b/ids-api/src/main/java/de/fhg/aisec/ids/api/router/graph/Node.kt new file mode 100644 index 000000000..8f9438a91 --- /dev/null +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/router/graph/Node.kt @@ -0,0 +1,26 @@ +/*- + * ========================LICENSE_START================================= + * ids-api + * %% + * Copyright (C) 2019 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.api.router.graph + +data class Node(val name: String, val action: String, val type: NodeType) { + enum class NodeType { + EntryNode, Node, ChoiceNode + } +} diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/router/package-info.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/router/package-info.java deleted file mode 100644 index f39863b7e..000000000 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/router/package-info.java +++ /dev/null @@ -1,21 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * IDS Core Platform API - * %% - * Copyright (C) 2017 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -/** APIs for managing the message router. */ -package de.fhg.aisec.ids.api.router; diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/Constants.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/settings/ConnectionSettings.kt similarity index 74% rename from ids-api/src/main/java/de/fhg/aisec/ids/api/Constants.java rename to ids-api/src/main/java/de/fhg/aisec/ids/api/settings/ConnectionSettings.kt index 686d44952..dde200bad 100644 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/Constants.java +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/settings/ConnectionSettings.kt @@ -17,11 +17,14 @@ * limitations under the License. * =========================LICENSE_END================================== */ -package de.fhg.aisec.ids.api; +package de.fhg.aisec.ids.api.settings -public interface Constants { +import java.io.Serializable - String PREFERENCES_ID = "ids.preferences"; - String CONNECTIONS_PREFERENCES = "ids.connectionPreferences"; - String GENERAL_CONFIG = "General Configuration"; +class ConnectionSettings : Serializable { + val requiredSecurityProfile = "idsc:TRUSTED_CONNECTOR_SECURITY_PROFILE" + + companion object { + private const val serialVersionUID = 1L + } } diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/settings/ConnectorConfig.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/settings/ConnectorConfig.java deleted file mode 100644 index 4445cf458..000000000 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/settings/ConnectorConfig.java +++ /dev/null @@ -1,110 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-api - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.api.settings; - -import java.io.Serializable; - -public final class ConnectorConfig implements Serializable { - private static final long serialVersionUID = 1L; - - private final String appstoreUrl; - private final String brokerUrl; - private final String ttpHost; - private final int ttpPort; - private final String acmeServerWebcon; - private final String acmeDnsWebcon; - private final int acmePortWebcon; - private final boolean tosAcceptWebcon; - private final String dapsUrl; - private final String keystoreName; - private final String keystorePassword; - private final String keystoreAliasName; - private final String truststoreName; - - public ConnectorConfig() { - appstoreUrl = - "https://raw.githubusercontent.com/industrial-data-space/templates/master/templates.json"; - brokerUrl = ""; - ttpHost = ""; - ttpPort = 443; - acmeServerWebcon = ""; - acmeDnsWebcon = ""; - acmePortWebcon = 80; - tosAcceptWebcon = false; - dapsUrl = "https://daps.aisec.fraunhofer.de"; - keystoreName = "provider-keystore.p12"; - keystorePassword = "password"; - keystoreAliasName = "1"; - truststoreName = "truststore.p12"; - } - - public String getAppstoreUrl() { - return appstoreUrl; - } - - public String getBrokerUrl() { - return brokerUrl; - } - - public String getTtpHost() { - return ttpHost; - } - - public int getTtpPort() { - return ttpPort; - } - - public String getAcmeServerWebcon() { - return acmeServerWebcon; - } - - public String getAcmeDnsWebcon() { - return acmeDnsWebcon; - } - - public int getAcmePortWebcon() { - return acmePortWebcon; - } - - public boolean isTosAcceptWebcon() { - return tosAcceptWebcon; - } - - public String getDapsUrl() { - return dapsUrl; - } - - public String getKeystoreName() { - return keystoreName; - } - - public String getKeystorePassword() { - return keystorePassword; - } - - public String getKeystoreAliasName() { - return keystoreAliasName; - } - - public String getTruststoreName() { - return truststoreName; - } - -} diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/Result.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/settings/ConnectorConfig.kt similarity index 53% rename from ids-api/src/main/java/de/fhg/aisec/ids/api/Result.java rename to ids-api/src/main/java/de/fhg/aisec/ids/api/settings/ConnectorConfig.kt index ee8faeef0..a9dce4bf2 100644 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/Result.java +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/settings/ConnectorConfig.kt @@ -17,35 +17,26 @@ * limitations under the License. * =========================LICENSE_END================================== */ -package de.fhg.aisec.ids.api; - -import org.checkerframework.checker.nullness.qual.NonNull; - -/** Generic result of an API call. */ -public class Result { - private boolean successful = true; - private String message = "ok"; - - public Result() {} - - public Result(boolean success, @NonNull String msg) { - this.setSuccessful(success); - this.setMessage(msg); - } - - public boolean isSuccessful() { - return successful; - } - - public void setSuccessful(boolean successful) { - this.successful = successful; - } - - public String getMessage() { - return message; - } - - public void setMessage(@NonNull String message) { - this.message = message; - } +package de.fhg.aisec.ids.api.settings + +import java.io.Serializable + +class ConnectorConfig : Serializable { + val appstoreUrl = "https://raw.githubusercontent.com/industrial-data-space/templates/master/templates.json" + val brokerUrl = "" + val ttpHost = "" + val ttpPort = 443 + val acmeServerWebcon = "" + val acmeDnsWebcon = "" + val acmePortWebcon = 80 + val tosAcceptWebcon = false + val dapsUrl = "https://daps.aisec.fraunhofer.de" + val keystoreName = "provider-keystore.p12" + val keystorePassword = "password" + val keystoreAliasName = "1" + val truststoreName = "truststore.p12" + + companion object { + private const val serialVersionUID = 1L + } } diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/settings/Settings.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/settings/Settings.java deleted file mode 100644 index a1ef03180..000000000 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/settings/Settings.java +++ /dev/null @@ -1,45 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-api - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.api.settings; - -import de.fhg.aisec.ids.api.infomodel.ConnectorProfile; - -import java.util.Map; - -public interface Settings { - - ConnectorConfig getConnectorConfig(); - - void setConnectorConfig(ConnectorConfig config); - - ConnectorProfile getConnectorProfile(); - - void setConnectorProfile(ConnectorProfile profile); - - String getConnectorJsonLd(); - - void setConnectorJsonLd(String jsonLd); - - ConnectionSettings getConnectionSettings(String connection); - - void setConnectionSettings(String connection, ConnectionSettings connectionSettings); - - Map getAllConnectionSettings(); -} diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/settings/Settings.kt b/ids-api/src/main/java/de/fhg/aisec/ids/api/settings/Settings.kt new file mode 100644 index 000000000..59fcf33f8 --- /dev/null +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/settings/Settings.kt @@ -0,0 +1,31 @@ +/*- + * ========================LICENSE_START================================= + * ids-api + * %% + * Copyright (C) 2019 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.api.settings + +import de.fhg.aisec.ids.api.infomodel.ConnectorProfile + +interface Settings { + var connectorConfig: ConnectorConfig + var connectorProfile: ConnectorProfile + var connectorJsonLd: String? + fun getConnectionSettings(connection: String): ConnectionSettings + fun setConnectionSettings(connection: String, cSettings: ConnectionSettings) + val allConnectionSettings: Map +} diff --git a/ids-connector/src/main/kotlin/de/fhg/aisec/ids/ConnectorConfiguration.kt b/ids-connector/src/main/kotlin/de/fhg/aisec/ids/ConnectorConfiguration.kt index efa971121..5a370fb73 100644 --- a/ids-connector/src/main/kotlin/de/fhg/aisec/ids/ConnectorConfiguration.kt +++ b/ids-connector/src/main/kotlin/de/fhg/aisec/ids/ConnectorConfiguration.kt @@ -29,6 +29,7 @@ import org.springframework.boot.CommandLineRunner import org.springframework.context.ApplicationContext import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration +import java.net.URI import java.util.Arrays @Configuration @@ -42,8 +43,14 @@ class ConnectorConfiguration { @Bean fun configureIdscp2(): CommandLineRunner { return CommandLineRunner { - Utils.connectorUrlProducer = { settings.connectorProfile.connectorUrl } - Utils.maintainerUrlProducer = { settings.connectorProfile.maintainerUrl } + Utils.connectorUrlProducer = { + settings.connectorProfile.connectorUrl + ?: URI.create("http://connector.ids") + } + Utils.maintainerUrlProducer = { + settings.connectorProfile.maintainerUrl + ?: URI.create("http://connector-maintainer.ids") + } Utils.dapsUrlProducer = { settings.connectorConfig.dapsUrl } TrustedConnector.LOG.info("Information model {} loaded", BuildConfig.INFOMODEL_VERSION) Utils.infomodelVersion = BuildConfig.INFOMODEL_VERSION diff --git a/ids-container-manager/src/main/java/de/fhg/aisec/ids/cm/ContainerManagerService.java b/ids-container-manager/src/main/java/de/fhg/aisec/ids/cm/ContainerManagerService.java deleted file mode 100644 index e0c65f9f3..000000000 --- a/ids-container-manager/src/main/java/de/fhg/aisec/ids/cm/ContainerManagerService.java +++ /dev/null @@ -1,153 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-container-manager - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.cm; - -import de.fhg.aisec.ids.api.cm.*; -import de.fhg.aisec.ids.cm.impl.docker.DockerCM; -import de.fhg.aisec.ids.cm.impl.dummy.DummyCM; -import de.fhg.aisec.ids.cm.impl.trustx.TrustXCM; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; - -import java.util.List; -import java.util.Optional; - -/** - * Main entry point of the Container Management Layer. - * - *

This class is mainly a facade for the actual CML implementation, which can either be Docker or - * trust-X. - * - * @author Julian Schütte (julian.schuette@aisec.fraunhofer.de) - */ -@Component("idsContainerManager") -public class ContainerManagerService implements ContainerManager { - private static final Logger LOG = LoggerFactory.getLogger(ContainerManagerService.class); - private final ContainerManager containerManager; - - public ContainerManagerService() { - // When activated, try to set container management instance - containerManager = getDefaultCM(); - LOG.info("Default container management is {}", containerManager); - } - - private ContainerManager getDefaultCM() { - ContainerManager result; - if (TrustXCM.isSupported()) { - result = new TrustXCM(); - } else if (DockerCM.Companion.isSupported()) { - result = new DockerCM(); - } else { - LOG.warn("No supported container management layer found. Using dummy"); - result = new DummyCM(); - } - return result; - } - - @Override - public List list(boolean onlyRunning) { - return containerManager.list(onlyRunning); - } - - @Override - public void wipe(String containerID) { - try { - containerManager.wipe(containerID); - } catch (NoContainerExistsException e) { - LOG.error(e.getMessage(), e); - } - } - - @Override - public void startContainer(String containerID, String key) { - try { - containerManager.startContainer(containerID, key); - } catch (NoContainerExistsException e) { - LOG.error(e.getMessage(), e); - } - } - - @Override - public void stopContainer(String containerID) { - try { - containerManager.stopContainer(containerID); - } catch (NoContainerExistsException e) { - LOG.error(e.getMessage(), e); - } - } - - @Override - public void restartContainer(String containerID) { - try { - containerManager.restartContainer(containerID); - } catch (NoContainerExistsException e) { - LOG.error(e.getMessage(), e); - } - } - - @Override - public Optional pullImage(ApplicationContainer app) { - try { - return containerManager.pullImage(app); - } catch (NoContainerExistsException e) { - LOG.error(e.getMessage(), e); - } - return Optional.empty(); - } - - @Override - public String inspectContainer(String containerID) { - try { - return containerManager.inspectContainer(containerID); - } catch (NoContainerExistsException e) { - LOG.error(e.getMessage(), e); - } - return ""; - } - - @Override - public Object getMetadata(String containerID) { - try { - return containerManager.getMetadata(containerID); - } catch (NoContainerExistsException e) { - LOG.error(e.getMessage(), e); - } - return null; - } - - @Override - public void setIpRule( - String containerID, - Direction direction, - int srcPort, - int dstPort, - String srcDstRange, - Protocol protocol, - Decision decision) { - containerManager.setIpRule( - containerID, direction, srcPort, dstPort, srcDstRange, protocol, decision); - } - - @Override - public String getVersion() { - return containerManager.getVersion(); - } -} diff --git a/ids-container-manager/src/main/java/de/fhg/aisec/ids/cm/impl/StreamGobbler.java b/ids-container-manager/src/main/java/de/fhg/aisec/ids/cm/impl/StreamGobbler.java deleted file mode 100644 index a57c195a4..000000000 --- a/ids-container-manager/src/main/java/de/fhg/aisec/ids/cm/impl/StreamGobbler.java +++ /dev/null @@ -1,65 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-container-manager - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.cm.impl; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -public class StreamGobbler extends Thread { - private static final Logger LOG = LoggerFactory.getLogger(StreamGobbler.class); - InputStream is; - OutputStream out; - - // reads everything from is until empty. - public StreamGobbler(InputStream is, OutputStream out) { - this.is = is; - this.out = out; - } - - @Override - public void run() { - try { - copy(is, out); - } catch (IOException ioe) { - LOG.error(ioe.getMessage(), ioe); - } - } - - private static void copy(InputStream in, OutputStream out) throws IOException { - while (true) { - int c = in.read(); - if (c == -1) break; - out.write((char) c); - } - } - - public void close() { - try { - out.flush(); - out.close(); - } catch (IOException e) { - LOG.error(e.getMessage(), e); - } - } -} diff --git a/ids-container-manager/src/main/java/de/fhg/aisec/ids/cm/impl/dummy/DummyCM.java b/ids-container-manager/src/main/java/de/fhg/aisec/ids/cm/impl/dummy/DummyCM.java deleted file mode 100644 index 8f800376d..000000000 --- a/ids-container-manager/src/main/java/de/fhg/aisec/ids/cm/impl/dummy/DummyCM.java +++ /dev/null @@ -1,79 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-container-manager - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.cm.impl.dummy; - -import de.fhg.aisec.ids.api.cm.*; - -import java.util.*; - -/** - * Dummy implementation of a null container manager which is used if no real CMLd is available. - * - * @author Julian Schütte (julian.schuette@aisec.fraunhofer.de) - */ -public class DummyCM implements ContainerManager { - - @Override - public List list(boolean onlyRunning) { - return new ArrayList<>(); - } - - @Override - public void wipe(final String containerID) {} - - @Override - public void startContainer(final String containerID, final String password) {} - - @Override - public void stopContainer(final String containerID) {} - - @Override - public void restartContainer(final String containerID) {} - - @Override - public Optional pullImage(final ApplicationContainer app) { - return Optional.empty(); - } - - @Override - public Map getMetadata(String containerID) { - return new HashMap<>(); - } - - @Override - public void setIpRule( - String containerID, - Direction direction, - int srcPort, - int dstPort, - String srcDstRange, - Protocol protocol, - Decision decision) {} - - @Override - public String inspectContainer(final String containerID) { - return ""; - } - - @Override - public String getVersion() { - return "no cmld installed"; - } -} diff --git a/ids-container-manager/src/main/java/de/fhg/aisec/ids/cm/impl/trustx/TrustXCM.java b/ids-container-manager/src/main/java/de/fhg/aisec/ids/cm/impl/trustx/TrustXCM.java deleted file mode 100644 index 90ff1de26..000000000 --- a/ids-container-manager/src/main/java/de/fhg/aisec/ids/cm/impl/trustx/TrustXCM.java +++ /dev/null @@ -1,306 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-container-manager - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.cm.impl.trustx; - -import com.google.protobuf.InvalidProtocolBufferException; -import de.fhg.aisec.ids.api.cm.*; -import de.fhg.aisec.ids.comm.unixsocket.TrustmeUnixSocketResponseHandler; -import de.fhg.aisec.ids.comm.unixsocket.TrustmeUnixSocketThread; -import de.fraunhofer.aisec.trustme.Container.ContainerState; -import de.fraunhofer.aisec.trustme.Container.ContainerStatus; -import de.fraunhofer.aisec.trustme.Control.ContainerStartParams; -import de.fraunhofer.aisec.trustme.Control.ControllerToDaemon; -import de.fraunhofer.aisec.trustme.Control.ControllerToDaemon.Command; -import de.fraunhofer.aisec.trustme.Control.DaemonToController; -import de.fraunhofer.aisec.trustme.Control.DaemonToController.Response; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.time.Duration; -import java.time.Instant; -import java.time.ZoneId; -import java.time.format.DateTimeFormatter; -import java.time.format.FormatStyle; -import java.util.*; - -/** - * ContainerManager implementation for trust-x containers. - * - *

/dev/socket/cml-control Protobuf: control.proto container.proto für container configs - * - * @author Julian Schütte (julian.schuette@aisec.fraunhofer.de) - */ -public class TrustXCM implements ContainerManager { - - private static final Logger LOG = LoggerFactory.getLogger(TrustXCM.class); - - private static final String SOCKET = "/run/socket/cml-control"; - private TrustmeUnixSocketThread socketThread; - private TrustmeUnixSocketResponseHandler responseHandler; - private DateTimeFormatter formatter = - DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT) - .withLocale(Locale.GERMANY) - .withZone(ZoneId.systemDefault()); - - public TrustXCM() { - this(SOCKET); - } - - public TrustXCM(String socket) { - super(); - try { - this.socketThread = new TrustmeUnixSocketThread(socket); - this.responseHandler = new TrustmeUnixSocketResponseHandler(); - Thread t = new Thread(socketThread); - t.setDaemon(true); - t.start(); - } catch (IOException e) { - LOG.error(e.getMessage(), e); - } - } - - private de.fhg.aisec.ids.api.cm.ContainerStatus stateToStatusString(ContainerState state) { - switch (state) { - case RUNNING: - case SETUP: - return de.fhg.aisec.ids.api.cm.ContainerStatus.RUNNING; - default: - return de.fhg.aisec.ids.api.cm.ContainerStatus.EXITED; - } - } - - @Override - public List list(boolean onlyRunning) { - LOG.debug("Starting list containers"); - List result = new ArrayList<>(); - byte[] response = sendCommandAndWaitForResponse(Command.GET_CONTAINER_STATUS); - try { - DaemonToController dtc = DaemonToController.parseFrom(response); - List containerStats = dtc.getContainerStatusList(); - for (ContainerStatus cs : containerStats) { - ApplicationContainer container; - if (!onlyRunning || ContainerState.RUNNING.equals(cs.getState())) { - container = new ApplicationContainer(); - container.setId(cs.getUuid()); - container.setImage(""); - container.setCreated(formatter.format(Instant.ofEpochSecond(cs.getCreated()))); - // container.setStatus(cs.getState().name()); - container.setStatus(stateToStatusString(cs.getState())); - container.setPorts(Arrays.asList("\n".split("\n"))); - container.setNames(cs.getName()); - container.setName(cs.getName()); - container.setSize(""); - container.setUptime(formatDuration(Duration.ofSeconds(cs.getUptime()))); - container.setSignature(""); - container.setOwner(""); - container.setDescription("trustx container"); - container.setLabels(null); - LOG.debug("List add Container: " + container); - result.add(container); - } - } - } catch (InvalidProtocolBufferException e) { - LOG.error("Response Length: " + response.length, e); - LOG.error("Response was: \n" + bytesToHex(response)); - } - return result; - } - - @Override - public void wipe(String containerID) { - sendCommand(Command.CONTAINER_WIPE); - } - - @Override - public void startContainer(String containerID, String key) { - LOG.debug("Starting start container with ID {}", containerID); - ControllerToDaemon.Builder ctdmsg = ControllerToDaemon.newBuilder(); - ctdmsg.setCommand(Command.CONTAINER_START); - ctdmsg.addContainerUuids(containerID); - ContainerStartParams.Builder cspbld = ContainerStartParams.newBuilder(); - if (key != null) { - cspbld.setKey(key); - } - cspbld.setNoSwitch(true); - - ctdmsg.setContainerStartParams(cspbld.build()); - try { - DaemonToController dtc = parseResponse(sendProtobufAndWaitForResponse(ctdmsg.build())); - if (!Response.CONTAINER_START_OK.equals(dtc.getResponse())) { - LOG.error("Container start failed, response was {}", dtc.getResponse()); - } - LOG.error("Container start ok, response was {}", dtc.getResponse()); - } catch (InvalidProtocolBufferException e) { - LOG.error("Protobuf error", e); - } - } - - @Override - public void stopContainer(String containerID) { - LOG.debug("Starting stop container with ID {}", containerID); - ControllerToDaemon.Builder ctdmsg = ControllerToDaemon.newBuilder(); - ctdmsg.setCommand(Command.CONTAINER_STOP); - ctdmsg.addContainerUuids(containerID); - sendProtobuf(ctdmsg.build()); - } - - @Override - public void restartContainer(String containerID) { - sendCommand(Command.CONTAINER_STOP); - sendCommand(Command.CONTAINER_START); - } - - @Override - public Optional pullImage(ApplicationContainer imageID) { - // TODO Auto-generated method stub - return Optional.empty(); - } - - public static boolean isSupported() { - Path path = Paths.get(SOCKET); - boolean exists = false; - if (Files.exists(path)) { - exists = true; - } - return exists; - } - - @Override - public String inspectContainer(String containerID) { - // TODO Auto-generated method stub - return null; - } - - @Override - public String getMetadata(String containerID) { - // TODO Auto-generated method stub - return null; - } - - @Override - public void setIpRule( - String containerID, - Direction direction, - int srcPort, - int dstPort, - String srcDstRange, - Protocol protocol, - Decision decision) { - // TODO Auto-generated method stub - - } - - @Override - public String getVersion() { - // TODO Auto-generated method stub - return null; - } - - /** - * Used for sending control commands to a device. - * - * @param command The command to be sent. - */ - private void sendCommand(Command command) { - ControllerToDaemon.Builder ctdmsg = ControllerToDaemon.newBuilder(); - ctdmsg.setCommand(command); - sendProtobuf(ctdmsg.build()); - } - - /** - * More flexible than the sendCommand method. Required when other parameters need to be set than - * the Command - * - * @param ctd the control command - */ - private void sendProtobuf(ControllerToDaemon ctd) { - LOG.debug("sending message {}", ctd.getCommand()); - LOG.debug(ctd.toString()); - byte[] encodedMessage = ctd.toByteArray(); - try { - socketThread.sendWithHeader(encodedMessage, responseHandler); - } catch (IOException | InterruptedException e) { - LOG.error(e.getMessage(), e); - } - } - - /** - * Used for sending control commands to a device. - * - * @param command The command to be sent. - * @return Success state. - */ - private byte[] sendCommandAndWaitForResponse(Command command) { - sendCommand(command); - return responseHandler.waitForResponse(); - } - - /** - * Used for sending control commands to a device. - * - * @param ctd The command to be sent. - * @return Success state. - */ - private byte[] sendProtobufAndWaitForResponse(ControllerToDaemon ctd) { - sendProtobuf(ctd); - return responseHandler.waitForResponse(); - } - - private DaemonToController parseResponse(byte[] response) throws InvalidProtocolBufferException { - return DaemonToController.parseFrom(response); - } - - private static final char[] hexArray = "0123456789ABCDEF".toCharArray(); - - public static String bytesToHex(byte[] bytes) { - char[] hexChars = new char[bytes.length * 2]; - for (int j = 0; j < bytes.length; j++) { - int v = bytes[j] & 0xFF; - hexChars[j * 2] = hexArray[v >>> 4]; - hexChars[j * 2 + 1] = hexArray[v & 0x0F]; - } - return new String(hexChars); - } - - private static String formatDuration(Duration duration) { - long seconds = duration.getSeconds(); - long absSeconds = Math.abs(seconds); - String days = dayString(absSeconds); - String hoursAndMinutes = - String.format("%d:%02d", (absSeconds / 3600) / 24, (absSeconds % 3600) / 60); - return days + hoursAndMinutes; - } - - private static String dayString(long seconds) { - if (seconds != 0) { - long hours = seconds / 3600; - if (hours < 24) return ""; - else if (hours < 48) return "1 day "; - else { - return String.format("%d days ", hours / 24); - } - } - return ""; - } -} diff --git a/ids-container-manager/src/main/java/de/fhg/aisec/ids/comm/unixsocket/ChangeRequest.java b/ids-container-manager/src/main/java/de/fhg/aisec/ids/comm/unixsocket/ChangeRequest.java deleted file mode 100644 index ca1fdc92f..000000000 --- a/ids-container-manager/src/main/java/de/fhg/aisec/ids/comm/unixsocket/ChangeRequest.java +++ /dev/null @@ -1,38 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-container-manager - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.comm.unixsocket; - -import jnr.unixsocket.UnixSocketChannel; - -public class ChangeRequest { - - public static final int REGISTER = 1; - public static final int CHANGEOPS = 2; - - public UnixSocketChannel channel; - public int type; - public int ops; - - public ChangeRequest(UnixSocketChannel channel, int type, int ops) { - this.channel = channel; - this.type = type; - this.ops = ops; - } -} diff --git a/ids-container-manager/src/main/java/de/fhg/aisec/ids/comm/unixsocket/TrustmeUnixSocketResponseHandler.java b/ids-container-manager/src/main/java/de/fhg/aisec/ids/comm/unixsocket/TrustmeUnixSocketResponseHandler.java deleted file mode 100644 index 938a705ab..000000000 --- a/ids-container-manager/src/main/java/de/fhg/aisec/ids/comm/unixsocket/TrustmeUnixSocketResponseHandler.java +++ /dev/null @@ -1,48 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-container-manager - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.comm.unixsocket; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class TrustmeUnixSocketResponseHandler { - private Logger LOG = LoggerFactory.getLogger(TrustmeUnixSocketResponseHandler.class); - private byte[] rsp = null; - - public synchronized boolean handleResponse(byte[] rsp) { - this.rsp = rsp.clone(); - this.notify(); - return true; - } - - public synchronized byte[] waitForResponse() { - while (this.rsp == null) { - try { - this.wait(); - } catch (InterruptedException e) { - LOG.error(e.getMessage(), e); - } - } - byte[] result = rsp; - LOG.debug("received response byte length: {}", result.length); - this.rsp = null; - return result; - } -} diff --git a/ids-container-manager/src/main/java/de/fhg/aisec/ids/comm/unixsocket/TrustmeUnixSocketThread.java b/ids-container-manager/src/main/java/de/fhg/aisec/ids/comm/unixsocket/TrustmeUnixSocketThread.java deleted file mode 100644 index 125b35570..000000000 --- a/ids-container-manager/src/main/java/de/fhg/aisec/ids/comm/unixsocket/TrustmeUnixSocketThread.java +++ /dev/null @@ -1,329 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-container-manager - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.comm.unixsocket; - -import jnr.enxio.channels.NativeSelectorProvider; -import jnr.unixsocket.UnixSocketAddress; -import jnr.unixsocket.UnixSocketChannel; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.File; -import java.io.IOException; -import java.math.BigInteger; -import java.nio.ByteBuffer; -import java.nio.channels.SelectionKey; -import java.nio.channels.Selector; -import java.util.*; -import java.util.concurrent.TimeUnit; - -public class TrustmeUnixSocketThread implements Runnable { - private static final Logger LOG = LoggerFactory.getLogger(TrustmeUnixSocketThread.class); - private String socket; - - // The selector we'll be monitoring - private final Selector selector; - - private final ByteBuffer lengthBuffer = ByteBuffer.allocate(4); - - // A list of PendingChange instances - private final List pendingChanges = new LinkedList<>(); - - // Maps a UnixSocketChannel to a list of ByteBuffer instances - private final Map> pendingData = new HashMap<>(); - - // Maps a UnixSocketChannel to a UnixSocketResponseHandler - private final Map rspHandlers = - Collections.synchronizedMap(new HashMap<>()); - - // constructor setting another socket address - public TrustmeUnixSocketThread(String socket) throws IOException { - this.setSocket(socket); - this.selector = this.initSelector(); - } - - // send a protobuf message to the unix socket - public void sendWithHeader(byte[] data, TrustmeUnixSocketResponseHandler handler) - throws IOException, InterruptedException { - this.send(data, handler, true); - } - - // send some data to the unix socket - public void send(byte[] data, TrustmeUnixSocketResponseHandler handler, boolean withLengthHeader) - throws IOException, InterruptedException { - LOG.debug("writing protobuf to socket"); - byte[] result = data; - // if message has to be sent with length header - if (withLengthHeader) { - // then append the length of the message - int length = data.length; - // in the first 4 bytes - lengthBuffer.clear(); - ByteBuffer bb = ByteBuffer.allocate(4 + length); - bb.put(lengthBuffer.putInt(length).array()); - bb.put(data); - result = bb.array(); - } - UnixSocketChannel socket = initiateConnection(); - // Register the response handler - this.rspHandlers.put(socket, handler); - // And queue the data we want written - synchronized (this.pendingData) { - List queue = this.pendingData.computeIfAbsent(socket, k -> new ArrayList<>()); - queue.add(ByteBuffer.wrap(result)); - } - - // Finally, wake up our selecting thread so it can make the required changes - this.selector.wakeup(); - } - - // thread run method - @Override - public void run() { - while (!Thread.interrupted()) { - try { - // Process any pending changes - synchronized (this.pendingChanges) { - for (ChangeRequest change : this.pendingChanges) { - switch (change.type) { - case ChangeRequest.CHANGEOPS: - SelectionKey key = change.channel.keyFor(this.selector); - key.interestOps(change.ops); - break; - case ChangeRequest.REGISTER: - change.channel.register(this.selector, change.ops); - break; - default: - LOG.warn("Unknown ChangeRequest type {}", change.type); - } - } - this.pendingChanges.clear(); - } - - // Wait for an event on one of the registered channels - this.selector.select(); - - // Iterate over the set of keys for which events are available - Iterator selectedKeys = this.selector.selectedKeys().iterator(); - while (selectedKeys.hasNext()) { - SelectionKey key = selectedKeys.next(); - selectedKeys.remove(); - if (!key.isValid()) { - continue; - } - // Check what event is available and deal with it - if (key.isConnectable()) { - this.finishConnection(key); - } - if (key.isReadable()) { - this.read(key); - } else if (key.isWritable()) { - this.write(key); - } - } - } catch (Exception e) { - e.printStackTrace(); - } - } - } - - // read send some data from the unix socket - private void read(SelectionKey key) throws IOException { - LOG.debug("reading protobuf from socket"); - UnixSocketChannel channel = this.getChannel(key); - - int length = readMessageLength(key, channel); - - if (length == -1) { - // Remote entity shut the socket down cleanly. Do the same from our end and - // cancel the channel. - LOG.debug("Closing channel because length = -1"); - key.channel().close(); - key.cancel(); - return; - } - - ByteBuffer messageBuffer = ByteBuffer.allocate(length); - - messageBuffer.clear(); - - int numRead = 0; - int totalRead = 0; - try { - while (totalRead < length) { - numRead = channel.read(messageBuffer); - totalRead += numRead; - LOG.debug("read {} bytes of protobuf from socket, {} in total", numRead, totalRead); - } - } catch (IOException e) { - // The remote forcibly closed the connection, cancel the selection key and close - // the channel. - LOG.debug("error while reading from socket", e); - key.cancel(); - channel.close(); - return; - } - if (numRead == -1) { - // Remote entity shut the socket down cleanly. Do the same from our end and cancel the - // channel. - LOG.debug("Closing channel because numRead = -1"); - key.channel().close(); - key.cancel(); - return; - } - - // Handle the response - this.handleResponse(channel, messageBuffer.array()); - } - - private int readMessageLength(SelectionKey key, UnixSocketChannel channel) throws IOException { - // Clear out our read buffer so it's ready for new data - lengthBuffer.clear(); - - // Attempt to read off the channel - int length; - try { - int numread = channel.read(lengthBuffer); - if (numread == 4) { - length = new BigInteger(lengthBuffer.array()).intValue(); - } else { - length = -1; - } - } catch (IOException e) { - // The remote forcibly closed the connection, cancel the selection key and close - // the channel. - LOG.debug("error while reading message length from socket", e); - key.cancel(); - channel.close(); - return -1; - } - LOG.debug("read message from UNIX socket with length " + length); - return length; - } - - private void handleResponse(UnixSocketChannel socketChannel, byte[] data) throws IOException { - // Make a correctly sized copy of the data before handing it - // to the client - byte[] rspData = new byte[data.length]; - System.arraycopy(data, 0, rspData, 0, data.length); - - // Look up the handler for this channel - TrustmeUnixSocketResponseHandler handler = this.rspHandlers.get(socketChannel); - - // And pass the response to it - if (handler.handleResponse(rspData)) { - LOG.debug("Handler done, close channel"); - // The handler has seen enough, close the connection - socketChannel.close(); - socketChannel.keyFor(this.selector).cancel(); - } - } - - private void write(SelectionKey key) throws IOException { - final UnixSocketChannel channel = this.getChannel(key); - - synchronized (this.pendingData) { - List queue = this.pendingData.get(channel); - - // Write until there's not more data - while (!queue.isEmpty()) { - ByteBuffer buf = queue.get(0); - channel.write(buf); - if (buf.remaining() > 0) { - // ... or the socket's buffer fills up - break; - } - queue.remove(0); - } - if (queue.isEmpty()) { - // We wrote away all data, so we're no longer interested in writing on this - // socket. Switch back to waiting for data. - key.interestOps(SelectionKey.OP_READ); - } - } - } - - private void finishConnection(SelectionKey key) { - final UnixSocketChannel channel = this.getChannel(key); - - // Finish the connection. If the connection operation failed this will raise an - // IOException. - try { - System.out.println(channel.finishConnect()); - } catch (IOException e) { - // Cancel the channel's registration with our selector - LOG.debug(e.getMessage(), e); - key.cancel(); - return; - } - - // Register an interest in writing on this channel - // this.pendingChanges.add(new ChangeRequest(channel, ChangeRequest.CHANGEOPS, - // SelectionKey.OP_WRITE)); - // key.interestOps(SelectionKey.OP_WRITE); - this.selector.wakeup(); - } - - private UnixSocketChannel initiateConnection() throws IOException, InterruptedException { - // open the socket address - File socketFile = new File(getSocket()); - // Try to open socket file 10 times - int retries = 0; - while (!socketFile.getAbsoluteFile().exists() && retries < 10) { - ++retries; - TimeUnit.MILLISECONDS.sleep(500L); - socketFile = new File(getSocket()); - if (retries < 10) { - LOG.debug( - String.format( - "error: socket \"%s\" does not exist after %s retry.", - socketFile.getAbsolutePath(), retries)); - } - } - UnixSocketAddress address = new UnixSocketAddress(socketFile.getAbsoluteFile()); - UnixSocketChannel channel = UnixSocketChannel.open(address); - channel.configureBlocking(false); - // synchronize pending changes - synchronized (this.pendingChanges) { - this.pendingChanges.add( - new ChangeRequest( - channel, ChangeRequest.REGISTER, SelectionKey.OP_CONNECT | SelectionKey.OP_WRITE)); - } - return channel; - } - - // initialize the selector - private Selector initSelector() throws IOException { - return NativeSelectorProvider.getInstance().openSelector(); - } - - // get the channel - private UnixSocketChannel getChannel(SelectionKey k) { - return (UnixSocketChannel) k.channel(); - } - - public String getSocket() { - return socket; - } - - public void setSocket(String socket) { - this.socket = socket; - } -} diff --git a/ids-container-manager/src/main/kotlin/de/fhg/aisec/ids/cm/ContainerManagerService.kt b/ids-container-manager/src/main/kotlin/de/fhg/aisec/ids/cm/ContainerManagerService.kt new file mode 100644 index 000000000..003d7e901 --- /dev/null +++ b/ids-container-manager/src/main/kotlin/de/fhg/aisec/ids/cm/ContainerManagerService.kt @@ -0,0 +1,152 @@ +/*- + * ========================LICENSE_START================================= + * ids-container-manager + * %% + * Copyright (C) 2019 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.cm + +import de.fhg.aisec.ids.api.cm.ApplicationContainer +import de.fhg.aisec.ids.api.cm.ContainerManager +import de.fhg.aisec.ids.api.cm.Decision +import de.fhg.aisec.ids.api.cm.Direction +import de.fhg.aisec.ids.api.cm.NoContainerExistsException +import de.fhg.aisec.ids.api.cm.Protocol +import de.fhg.aisec.ids.cm.impl.docker.DockerCM +import de.fhg.aisec.ids.cm.impl.docker.DockerCM.Companion.isSupported +import de.fhg.aisec.ids.cm.impl.dummy.DummyCM +import de.fhg.aisec.ids.cm.impl.trustx.TrustXCM +import org.slf4j.LoggerFactory +import org.springframework.stereotype.Component + +/** + * Main entry point of the Container Management Layer. + * + * + * This class is mainly a facade for the actual CML implementation, which can either be Docker or + * trust-X. + * + * @author Julian Schütte (julian.schuette@aisec.fraunhofer.de) + */ +@Component("idsContainerManager") +class ContainerManagerService : ContainerManager { + private val containerManager: ContainerManager + private val defaultCM: ContainerManager + get() { + return when { + TrustXCM.isSupported -> { + TrustXCM() + } + isSupported -> { + DockerCM() + } + else -> { + LOG.warn("No supported container management layer found. Using dummy") + DummyCM() + } + } + } + + override fun list(onlyRunning: Boolean): List { + return containerManager.list(onlyRunning) + } + + override fun wipe(containerID: String) { + try { + containerManager.wipe(containerID) + } catch (e: NoContainerExistsException) { + LOG.error(e.message, e) + } + } + + override fun startContainer(containerID: String, key: String?) { + try { + containerManager.startContainer(containerID, key) + } catch (e: NoContainerExistsException) { + LOG.error(e.message, e) + } + } + + override fun stopContainer(containerID: String) { + try { + containerManager.stopContainer(containerID) + } catch (e: NoContainerExistsException) { + LOG.error(e.message, e) + } + } + + override fun restartContainer(containerID: String) { + try { + containerManager.restartContainer(containerID) + } catch (e: NoContainerExistsException) { + LOG.error(e.message, e) + } + } + + override fun pullImage(app: ApplicationContainer): String? { + try { + return containerManager.pullImage(app) + } catch (e: NoContainerExistsException) { + LOG.error(e.message, e) + } + return null + } + + override fun inspectContainer(containerID: String): String? { + try { + return containerManager.inspectContainer(containerID) + } catch (e: NoContainerExistsException) { + LOG.error(e.message, e) + } + return "" + } + + override fun getMetadata(containerID: String): Any? { + try { + return containerManager.getMetadata(containerID) + } catch (e: NoContainerExistsException) { + LOG.error(e.message, e) + } + return null + } + + override fun setIpRule( + containerID: String, + direction: Direction, + srcPort: Int, + dstPort: Int, + srcDstRange: String, + protocol: Protocol, + decision: Decision + ) { + containerManager.setIpRule( + containerID, direction, srcPort, dstPort, srcDstRange, protocol, decision + ) + } + + override val version: String + get() = containerManager.version + + companion object { + private val LOG = LoggerFactory.getLogger(ContainerManagerService::class.java) + } + + init { + // When activated, try to set container management instance + containerManager = defaultCM + LOG.info("Default container management is {}", containerManager) + } +} diff --git a/ids-container-manager/src/main/java/de/fhg/aisec/ids/cm/impl/docker/DockerCM.kt b/ids-container-manager/src/main/kotlin/de/fhg/aisec/ids/cm/impl/docker/DockerCM.kt similarity index 84% rename from ids-container-manager/src/main/java/de/fhg/aisec/ids/cm/impl/docker/DockerCM.kt rename to ids-container-manager/src/main/kotlin/de/fhg/aisec/ids/cm/impl/docker/DockerCM.kt index 4d803e0c7..9bf8fbde3 100644 --- a/ids-container-manager/src/main/java/de/fhg/aisec/ids/cm/impl/docker/DockerCM.kt +++ b/ids-container-manager/src/main/kotlin/de/fhg/aisec/ids/cm/impl/docker/DockerCM.kt @@ -42,7 +42,6 @@ import java.time.ZonedDateTime import java.time.temporal.ChronoUnit import java.time.temporal.TemporalUnit import java.util.LinkedList -import java.util.Optional import java.util.stream.Collectors import javax.json.Json import javax.json.JsonArray @@ -320,9 +319,9 @@ class DockerCM : ContainerManager { } } - override fun pullImage(app: ApplicationContainer): Optional { + override fun pullImage(app: ApplicationContainer): String? { try { - val imageInfo = app.image.split(":").toTypedArray() + val imageInfo = app.image?.split(":")?.toTypedArray() ?: return null val tag = if (imageInfo.size == 2) imageInfo[1] else "latest" LOG.info("Pulling container image {} with tag {}", imageInfo[0], tag) // Pull image from std docker registry @@ -331,73 +330,60 @@ class DockerCM : ContainerManager { // Instantly create a container from that image, but do not start it yet. LOG.info("Creating container instance from image {}", app.image) // Create the name - val containerName: String = - if (app.name != null) { - app.name - } else { - defaultContainerName(app.image) - } + val containerName: String = app.name ?: defaultContainerName(app.image ?: return null) val container = Json.createObjectBuilder() val hostConfig = Json.createObjectBuilder() // Set image container.add("Image", app.image) // Add published ports and port bindings - if (app.ports != null) { - val exposedPorts = Json.createObjectBuilder() - val portBindings = Json.createObjectBuilder() - val portRegex = - ( - "(?:((?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\\.){3}" + - "(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])):)?" + - "([0-9]+):([0-9]+)(?:/(tcp|udp))?" - ) - .toRegex() - for (port in app.ports) { - val match = portRegex.matchEntire(port) - if (match == null) { - LOG.warn( - "Port definition {} does not match the pattern " + - "[IPv4:]HostPort:ContainerPort[/tcp|udp], ignoring it", - port - ) - } else { - val groups = match.groupValues - val protocol = (if (groups[4].isEmpty()) "tcp" else groups[4]) - exposedPorts.add(groups[3] + "/" + protocol, JsonValue.EMPTY_JSON_OBJECT) - val portBinding = Json.createObjectBuilder() - if (groups[1].isNotEmpty()) { - portBinding.add("HostIp", groups[1]) - } - portBinding.add("HostPort", groups[2]) - portBindings.add(groups[3] + "/" + protocol, portBinding) + val exposedPorts = Json.createObjectBuilder() + val portBindings = Json.createObjectBuilder() + val portRegex = + ( + "(?:((?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\\.){3}" + + "(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])):)?" + + "([0-9]+):([0-9]+)(?:/(tcp|udp))?" + ) + .toRegex() + for (port in app.ports) { + val match = portRegex.matchEntire(port) + if (match == null) { + LOG.warn( + "Port definition {} does not match the pattern " + + "[IPv4:]HostPort:ContainerPort[/tcp|udp], ignoring it", + port + ) + } else { + val groups = match.groupValues + val protocol = (if (groups[4].isEmpty()) "tcp" else groups[4]) + exposedPorts.add(groups[3] + "/" + protocol, JsonValue.EMPTY_JSON_OBJECT) + val portBinding = Json.createObjectBuilder() + if (groups[1].isNotEmpty()) { + portBinding.add("HostIp", groups[1]) } + portBinding.add("HostPort", groups[2]) + portBindings.add(groups[3] + "/" + protocol, portBinding) } - container.add("ExposedPorts", exposedPorts) - hostConfig.add("PortBindings", portBindings) } - if (app.env != null) { - val envJson = Json.createArrayBuilder() - for (env in app.env) { - val varName = env["name"] as String? - val varValue = env["set"] as String? - envJson.add("$varName=$varValue") - } - container.add("Env", envJson) + container.add("ExposedPorts", exposedPorts) + hostConfig.add("PortBindings", portBindings) + val envJson = Json.createArrayBuilder() + for (env in app.env) { + val varName = env["name"] as String? + val varValue = env["set"] as String? + envJson.add("$varName=$varValue") } + container.add("Env", envJson) // Sets label(s) val labels = Json.createObjectBuilder() labels.add("created", Instant.now().toEpochMilli().toString()) - if (app.labels != null) { - app.labels.forEach { labels.add(it.key, it.value.toString()) } - } + app.labels.forEach { labels.add(it.key, it.value.toString()) } container.add("Labels", labels) // Set restart policy - if (app.restartPolicy != null) { - hostConfig.add( - "RestartPolicy", - Json.createObjectBuilder().add("Name", app.restartPolicy) - ) - } + hostConfig.add( + "RestartPolicy", + Json.createObjectBuilder().add("Name", app.restartPolicy) + ) // Set privileged state if (app.isPrivileged) { hostConfig.add("Privileged", JsonValue.TRUE) @@ -405,13 +391,13 @@ class DockerCM : ContainerManager { container.add("HostConfig", hostConfig) val c = DOCKER_CLIENT.containers().create(containerName, container.build()) - return Optional.of(c.containerId()) + return c.containerId() } catch (e: InterruptedException) { Thread.currentThread().interrupt() } catch (e: Throwable) { LOG.error(e.message, e) } - return Optional.empty() + return null } /** @@ -463,8 +449,9 @@ class DockerCM : ContainerManager { } /** Returns the version of docker on the system */ - override fun getVersion(): String { - val version = DOCKER_CLIENT.version() - return "${version.platformName()} (${version.version()})" - } + override val version: String + get() { + val version = DOCKER_CLIENT.version() + return "${version.platformName()} (${version.version()})" + } } diff --git a/ids-container-manager/src/main/kotlin/de/fhg/aisec/ids/cm/impl/dummy/DummyCM.kt b/ids-container-manager/src/main/kotlin/de/fhg/aisec/ids/cm/impl/dummy/DummyCM.kt new file mode 100644 index 000000000..deb5ee459 --- /dev/null +++ b/ids-container-manager/src/main/kotlin/de/fhg/aisec/ids/cm/impl/dummy/DummyCM.kt @@ -0,0 +1,67 @@ +/*- + * ========================LICENSE_START================================= + * ids-container-manager + * %% + * Copyright (C) 2019 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.cm.impl.dummy + +import de.fhg.aisec.ids.api.cm.ApplicationContainer +import de.fhg.aisec.ids.api.cm.ContainerManager +import de.fhg.aisec.ids.api.cm.Decision +import de.fhg.aisec.ids.api.cm.Direction +import de.fhg.aisec.ids.api.cm.Protocol + +/** + * Dummy implementation of a null container manager which is used if no real CMLd is available. + * + * @author Julian Schütte (julian.schuette@aisec.fraunhofer.de) + */ +class DummyCM : ContainerManager { + override fun list(onlyRunning: Boolean): List { + return ArrayList() + } + + override fun wipe(containerID: String) {} + override fun startContainer(containerID: String, key: String?) {} + override fun stopContainer(containerID: String) {} + override fun restartContainer(containerID: String) {} + override fun pullImage(app: ApplicationContainer): String? { + return null + } + + override fun getMetadata(containerID: String): Map { + return HashMap() + } + + override fun setIpRule( + containerID: String, + direction: Direction, + srcPort: Int, + dstPort: Int, + srcDstRange: String, + protocol: Protocol, + decision: Decision + ) { + } + + override fun inspectContainer(containerID: String): String { + return "" + } + + override val version: String + get() = "no cmld installed" +} diff --git a/ids-container-manager/src/main/kotlin/de/fhg/aisec/ids/cm/impl/trustx/TrustXCM.kt b/ids-container-manager/src/main/kotlin/de/fhg/aisec/ids/cm/impl/trustx/TrustXCM.kt new file mode 100644 index 000000000..8a612ff5d --- /dev/null +++ b/ids-container-manager/src/main/kotlin/de/fhg/aisec/ids/cm/impl/trustx/TrustXCM.kt @@ -0,0 +1,288 @@ +/*- + * ========================LICENSE_START================================= + * ids-container-manager + * %% + * Copyright (C) 2019 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.cm.impl.trustx + +import com.google.protobuf.InvalidProtocolBufferException +import de.fhg.aisec.ids.api.cm.ApplicationContainer +import de.fhg.aisec.ids.api.cm.ContainerManager +import de.fhg.aisec.ids.api.cm.ContainerStatus +import de.fhg.aisec.ids.api.cm.Decision +import de.fhg.aisec.ids.api.cm.Direction +import de.fhg.aisec.ids.api.cm.Protocol +import de.fhg.aisec.ids.comm.unixsocket.TrustmeUnixSocketResponseHandler +import de.fhg.aisec.ids.comm.unixsocket.TrustmeUnixSocketThread +import de.fraunhofer.aisec.trustme.Container.ContainerState +import de.fraunhofer.aisec.trustme.Control.ContainerStartParams +import de.fraunhofer.aisec.trustme.Control.ControllerToDaemon +import de.fraunhofer.aisec.trustme.Control.DaemonToController +import org.slf4j.LoggerFactory +import java.io.IOException +import java.nio.file.Files +import java.nio.file.Paths +import java.time.Duration +import java.time.Instant +import java.time.ZoneId +import java.time.format.DateTimeFormatter +import java.time.format.FormatStyle +import java.util.Locale +import kotlin.math.abs + +/** + * ContainerManager implementation for trust-x containers. + * + * + * /dev/socket/cml-control Protobuf: control.proto container.proto für container configs + * + * @author Julian Schütte (julian.schuette@aisec.fraunhofer.de) + */ +class TrustXCM @JvmOverloads constructor(socket: String = SOCKET) : ContainerManager { + private var socketThread: TrustmeUnixSocketThread = TrustmeUnixSocketThread(socket) + private var responseHandler: TrustmeUnixSocketResponseHandler = TrustmeUnixSocketResponseHandler() + private val formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT) + .withLocale(Locale.GERMANY) + .withZone(ZoneId.systemDefault()) + + private fun stateToStatusString(state: ContainerState): ContainerStatus { + return when (state) { + ContainerState.RUNNING, ContainerState.SETUP -> ContainerStatus.RUNNING + else -> ContainerStatus.EXITED + } + } + + override fun list(onlyRunning: Boolean): List { + LOG.debug("Starting list containers") + val result: MutableList = ArrayList() + val response = sendCommandAndWaitForResponse(ControllerToDaemon.Command.GET_CONTAINER_STATUS) + try { + val dtc = DaemonToController.parseFrom(response) + val containerStats = dtc.containerStatusList + for (cs in containerStats) { + var container: ApplicationContainer + if (!onlyRunning || ContainerState.RUNNING == cs.state) { + container = ApplicationContainer() + container.id = cs.uuid + container.image = "" + container.created = formatter.format(Instant.ofEpochSecond(cs.created)) + // container.setStatus(cs.getState().name()); + container.status = stateToStatusString(cs.state) + container.ports = emptyList() + container.names = cs.name + container.name = cs.name + container.size = "" + container.uptime = formatDuration(Duration.ofSeconds(cs.uptime)) + container.signature = "" + container.owner = "" + container.description = "trustx container" + container.labels = emptyMap() + LOG.debug("List add Container: $container") + result.add(container) + } + } + } catch (e: InvalidProtocolBufferException) { + LOG.error("Response Length: " + response.size, e) + LOG.error( + """ + Response was: + ${bytesToHex(response)} + """.trimIndent() + ) + } + return result + } + + override fun wipe(containerID: String) { + sendCommand(ControllerToDaemon.Command.CONTAINER_WIPE) + } + + override fun startContainer(containerID: String, key: String?) { + LOG.debug("Starting start container with ID {}", containerID) + val ctdmsg = ControllerToDaemon.newBuilder() + ctdmsg.command = ControllerToDaemon.Command.CONTAINER_START + ctdmsg.addContainerUuids(containerID) + val cspbld = ContainerStartParams.newBuilder() + if (key != null) { + cspbld.key = key + } + cspbld.noSwitch = true + ctdmsg.containerStartParams = cspbld.build() + try { + val dtc = parseResponse(sendProtobufAndWaitForResponse(ctdmsg.build())) + if (DaemonToController.Response.CONTAINER_START_OK != dtc.response) { + LOG.error("Container start failed, response was {}", dtc.response) + } + LOG.error("Container start ok, response was {}", dtc.response) + } catch (e: InvalidProtocolBufferException) { + LOG.error("Protobuf error", e) + } + } + + override fun stopContainer(containerID: String) { + LOG.debug("Starting stop container with ID {}", containerID) + val ctdmsg = ControllerToDaemon.newBuilder() + ctdmsg.command = ControllerToDaemon.Command.CONTAINER_STOP + ctdmsg.addContainerUuids(containerID) + sendProtobuf(ctdmsg.build()) + } + + override fun restartContainer(containerID: String) { + sendCommand(ControllerToDaemon.Command.CONTAINER_STOP) + sendCommand(ControllerToDaemon.Command.CONTAINER_START) + } + + override fun pullImage(app: ApplicationContainer): String? { + return null + } + + override fun inspectContainer(containerID: String): String? { + // TODO Auto-generated method stub + return null + } + + override fun getMetadata(containerID: String): String? { + // TODO Auto-generated method stub + return null + } + + override fun setIpRule( + containerID: String, + direction: Direction, + srcPort: Int, + dstPort: Int, + srcDstRange: String, + protocol: Protocol, + decision: Decision + ) { + // TODO Auto-generated method stub + } + + // TODO Auto-generated method stub + override val version: String + get() = "1.0" + + /** + * Used for sending control commands to a device. + * + * @param command The command to be sent. + */ + private fun sendCommand(command: ControllerToDaemon.Command) { + val ctdmsg = ControllerToDaemon.newBuilder() + ctdmsg.command = command + sendProtobuf(ctdmsg.build()) + } + + /** + * More flexible than the sendCommand method. Required when other parameters need to be set than + * the Command + * + * @param ctd the control command + */ + private fun sendProtobuf(ctd: ControllerToDaemon) { + LOG.debug("sending message {}", ctd.command) + LOG.debug(ctd.toString()) + val encodedMessage = ctd.toByteArray() + try { + socketThread.sendWithHeader(encodedMessage, responseHandler) + } catch (e: IOException) { + LOG.error(e.message, e) + } catch (e: InterruptedException) { + LOG.error(e.message, e) + } + } + + /** + * Used for sending control commands to a device. + * + * @param command The command to be sent. + * @return Success state. + */ + private fun sendCommandAndWaitForResponse(command: ControllerToDaemon.Command): ByteArray { + sendCommand(command) + return responseHandler.waitForResponse() + } + + /** + * Used for sending control commands to a device. + * + * @param ctd The command to be sent. + * @return Success state. + */ + private fun sendProtobufAndWaitForResponse(ctd: ControllerToDaemon): ByteArray { + sendProtobuf(ctd) + return responseHandler.waitForResponse() + } + + @Throws(InvalidProtocolBufferException::class) + private fun parseResponse(response: ByteArray?): DaemonToController { + return DaemonToController.parseFrom(response) + } + + companion object { + private val LOG = LoggerFactory.getLogger(TrustXCM::class.java) + private const val SOCKET = "/run/socket/cml-control" + val isSupported: Boolean + get() { + val path = Paths.get(SOCKET) + var exists = false + if (Files.exists(path)) { + exists = true + } + return exists + } + private val hexArray = "0123456789ABCDEF".toCharArray() + fun bytesToHex(bytes: ByteArray): String { + val hexChars = CharArray(bytes.size * 2) + for (j in bytes.indices) { + val v = bytes[j].toInt() and 0xFF + hexChars[j * 2] = hexArray[v ushr 4] + hexChars[j * 2 + 1] = hexArray[v and 0x0F] + } + return String(hexChars) + } + + private fun formatDuration(duration: Duration): String { + val seconds = duration.seconds + val absSeconds = abs(seconds) + val days = dayString(absSeconds) + val hoursAndMinutes = String.format("%d:%02d", absSeconds / 3600 / 24, absSeconds % 3600 / 60) + return days + hoursAndMinutes + } + + private fun dayString(seconds: Long): String { + if (seconds != 0L) { + val hours = seconds / 3600 + return when { + hours < 24 -> "" + hours < 48 -> "1 day " + else -> { + String.format("%d days ", hours / 24) + } + } + } + return "" + } + } + + init { + Thread(socketThread).apply { + isDaemon = true + start() + } + } +} diff --git a/ids-container-manager/src/main/kotlin/de/fhg/aisec/ids/comm/unixsocket/ChangeRequest.kt b/ids-container-manager/src/main/kotlin/de/fhg/aisec/ids/comm/unixsocket/ChangeRequest.kt new file mode 100644 index 000000000..a44363280 --- /dev/null +++ b/ids-container-manager/src/main/kotlin/de/fhg/aisec/ids/comm/unixsocket/ChangeRequest.kt @@ -0,0 +1,29 @@ +/*- + * ========================LICENSE_START================================= + * ids-container-manager + * %% + * Copyright (C) 2019 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.comm.unixsocket + +import jnr.unixsocket.UnixSocketChannel + +class ChangeRequest(var channel: UnixSocketChannel, var type: Int, var ops: Int) { + companion object { + const val REGISTER = 1 + const val CHANGEOPS = 2 + } +} diff --git a/ids-container-manager/src/main/kotlin/de/fhg/aisec/ids/comm/unixsocket/TrustmeUnixSocketResponseHandler.kt b/ids-container-manager/src/main/kotlin/de/fhg/aisec/ids/comm/unixsocket/TrustmeUnixSocketResponseHandler.kt new file mode 100644 index 000000000..48b64a627 --- /dev/null +++ b/ids-container-manager/src/main/kotlin/de/fhg/aisec/ids/comm/unixsocket/TrustmeUnixSocketResponseHandler.kt @@ -0,0 +1,56 @@ +/*- + * ========================LICENSE_START================================= + * ids-container-manager + * %% + * Copyright (C) 2019 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.comm.unixsocket + +import org.slf4j.LoggerFactory +import java.util.concurrent.locks.ReentrantLock +import kotlin.concurrent.withLock + +class TrustmeUnixSocketResponseHandler { + private val lock = ReentrantLock() + private val condition = lock.newCondition() + + private val LOG = LoggerFactory.getLogger(TrustmeUnixSocketResponseHandler::class.java) + private var rsp: ByteArray? = null + + fun handleResponse(rsp: ByteArray): Boolean { + lock.withLock { + this.rsp = rsp.clone() + condition.signal() + return true + } + } + + fun waitForResponse(): ByteArray { + lock.withLock { + while (rsp == null) { + try { + condition.await() + } catch (e: InterruptedException) { + LOG.error(e.message, e) + } + } + val result = rsp!! + LOG.debug("received response byte length: {}", result.size) + rsp = null + return result + } + } +} diff --git a/ids-container-manager/src/main/kotlin/de/fhg/aisec/ids/comm/unixsocket/TrustmeUnixSocketThread.kt b/ids-container-manager/src/main/kotlin/de/fhg/aisec/ids/comm/unixsocket/TrustmeUnixSocketThread.kt new file mode 100644 index 000000000..6d2729859 --- /dev/null +++ b/ids-container-manager/src/main/kotlin/de/fhg/aisec/ids/comm/unixsocket/TrustmeUnixSocketThread.kt @@ -0,0 +1,318 @@ +/*- + * ========================LICENSE_START================================= + * ids-container-manager + * %% + * Copyright (C) 2019 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.comm.unixsocket + +import jnr.enxio.channels.NativeSelectorProvider +import jnr.unixsocket.UnixSocketAddress +import jnr.unixsocket.UnixSocketChannel +import org.slf4j.LoggerFactory +import java.io.File +import java.io.IOException +import java.math.BigInteger +import java.nio.ByteBuffer +import java.nio.channels.SelectionKey +import java.nio.channels.Selector +import java.util.Collections +import java.util.LinkedList +import java.util.concurrent.TimeUnit + +class TrustmeUnixSocketThread(private val socket: String) : Runnable { + // The selector we'll be monitoring + private val selector: Selector + private val lengthBuffer = ByteBuffer.allocate(4) + + // A list of PendingChange instances + private val pendingChanges: MutableList = LinkedList() + + // Maps a UnixSocketChannel to a list of ByteBuffer instances + private val pendingData: MutableMap> = HashMap() + + // Maps a UnixSocketChannel to a UnixSocketResponseHandler + private val rspHandlers = + Collections.synchronizedMap(HashMap()) + + // send a protobuf message to the unix socket + @Throws(IOException::class, InterruptedException::class) + fun sendWithHeader(data: ByteArray, handler: TrustmeUnixSocketResponseHandler?) { + send(data, handler, true) + } + + // send some data to the unix socket + @Throws(IOException::class, InterruptedException::class) + fun send(data: ByteArray, handler: TrustmeUnixSocketResponseHandler?, withLengthHeader: Boolean) { + LOG.debug("writing protobuf to socket") + var result = data + // if message has to be sent with length header + if (withLengthHeader) { + // then append the length of the message + val length = data.size + // in the first 4 bytes + lengthBuffer.clear() + val bb = ByteBuffer.allocate(4 + length) + bb.put(lengthBuffer.putInt(length).array()) + bb.put(data) + result = bb.array() + } + val socket = initiateConnection() + // Register the response handler + rspHandlers[socket] = handler + // And queue the data we want written + synchronized(pendingData) { + val queue = pendingData.computeIfAbsent(socket) { ArrayList() } + queue.add(ByteBuffer.wrap(result)) + } + + // Finally, wake up our selecting thread so it can make the required changes + selector.wakeup() + } + + // thread run method + override fun run() { + while (!Thread.interrupted()) { + try { + // Process any pending changes + synchronized(pendingChanges) { + for (change in pendingChanges) { + when (change.type) { + ChangeRequest.CHANGEOPS -> { + val key = change.channel.keyFor(selector) + key.interestOps(change.ops) + } + ChangeRequest.REGISTER -> change.channel.register(selector, change.ops) + else -> LOG.warn("Unknown ChangeRequest type {}", change.type) + } + } + pendingChanges.clear() + } + + // Wait for an event on one of the registered channels + selector.select() + + // Iterate over the set of keys for which events are available + val selectedKeys = selector.selectedKeys().iterator() + while (selectedKeys.hasNext()) { + val key = selectedKeys.next() + selectedKeys.remove() + if (!key.isValid) { + continue + } + // Check what event is available and deal with it + if (key.isConnectable) { + finishConnection(key) + } + if (key.isReadable) { + read(key) + } else if (key.isWritable) { + write(key) + } + } + } catch (e: Exception) { + e.printStackTrace() + } + } + } + + // read send some data from the unix socket + @Throws(IOException::class) + private fun read(key: SelectionKey) { + LOG.debug("reading protobuf from socket") + val channel = getChannel(key) + val length = readMessageLength(key, channel) + if (length == -1) { + // Remote entity shut the socket down cleanly. Do the same from our end and + // cancel the channel. + LOG.debug("Closing channel because length = -1") + key.channel().close() + key.cancel() + return + } + val messageBuffer = ByteBuffer.allocate(length) + messageBuffer.clear() + var numRead = 0 + var totalRead = 0 + try { + while (totalRead < length) { + numRead = channel.read(messageBuffer) + totalRead += numRead + LOG.debug("read {} bytes of protobuf from socket, {} in total", numRead, totalRead) + } + } catch (e: IOException) { + // The remote forcibly closed the connection, cancel the selection key and close + // the channel. + LOG.debug("error while reading from socket", e) + key.cancel() + channel.close() + return + } + if (numRead == -1) { + // Remote entity shut the socket down cleanly. Do the same from our end and cancel the + // channel. + LOG.debug("Closing channel because numRead = -1") + key.channel().close() + key.cancel() + return + } + + // Handle the response + handleResponse(channel, messageBuffer.array()) + } + + @Throws(IOException::class) + private fun readMessageLength(key: SelectionKey, channel: UnixSocketChannel): Int { + // Clear out our read buffer so it's ready for new data + lengthBuffer.clear() + + // Attempt to read off the channel + val length: Int = try { + val numRead = channel.read(lengthBuffer) + if (numRead == 4) { + BigInteger(lengthBuffer.array()).toInt() + } else { + -1 + } + } catch (e: IOException) { + // The remote forcibly closed the connection, cancel the selection key and close + // the channel. + LOG.debug("error while reading message length from socket", e) + key.cancel() + channel.close() + return -1 + } + LOG.debug("read message from UNIX socket with length $length") + return length + } + + @Throws(IOException::class) + private fun handleResponse(socketChannel: UnixSocketChannel, data: ByteArray) { + // Make a correctly sized copy of the data before handing it + // to the client + val rspData = ByteArray(data.size) + System.arraycopy(data, 0, rspData, 0, data.size) + + // Look up the handler for this channel + val handler = rspHandlers[socketChannel] + + // And pass the response to it + if (handler!!.handleResponse(rspData)) { + LOG.debug("Handler done, close channel") + // The handler has seen enough, close the connection + socketChannel.close() + socketChannel.keyFor(selector).cancel() + } + } + + @Throws(IOException::class) + private fun write(key: SelectionKey) { + val channel = getChannel(key) + synchronized(pendingData) { + val queue = pendingData[channel]!! + + // Write until there's not more data + while (queue.isNotEmpty()) { + val buf = queue[0] + channel.write(buf) + if (buf.remaining() > 0) { + // ... or the socket's buffer fills up + break + } + queue.removeAt(0) + } + if (queue.isEmpty()) { + // We wrote away all data, so we're no longer interested in writing on this + // socket. Switch back to waiting for data. + key.interestOps(SelectionKey.OP_READ) + } + } + } + + private fun finishConnection(key: SelectionKey) { + val channel = getChannel(key) + + // Finish the connection. If the connection operation failed this will raise an + // IOException. + try { + println(channel.finishConnect()) + } catch (e: IOException) { + // Cancel the channel's registration with our selector + LOG.debug(e.message, e) + key.cancel() + return + } + + // Register an interest in writing on this channel + // this.pendingChanges.add(new ChangeRequest(channel, ChangeRequest.CHANGEOPS, + // SelectionKey.OP_WRITE)); + // key.interestOps(SelectionKey.OP_WRITE); + selector.wakeup() + } + + @Throws(IOException::class, InterruptedException::class) + private fun initiateConnection(): UnixSocketChannel { + // open the socket address + var socketFile = File(socket) + // Try to open socket file 10 times + var retries = 0 + while (!socketFile.absoluteFile.exists() && retries < 10) { + ++retries + TimeUnit.MILLISECONDS.sleep(500L) + socketFile = File(socket) + if (retries < 10) { + LOG.debug( + String.format( + "error: socket \"%s\" does not exist after %s retry.", + socketFile.absolutePath, retries + ) + ) + } + } + val address = UnixSocketAddress(socketFile.absoluteFile) + val channel = UnixSocketChannel.open(address) + channel.configureBlocking(false) + // synchronize pending changes + synchronized(pendingChanges) { + pendingChanges.add( + ChangeRequest( + channel, ChangeRequest.REGISTER, SelectionKey.OP_CONNECT or SelectionKey.OP_WRITE + ) + ) + } + return channel + } + + // initialize the selector + @Throws(IOException::class) + private fun initSelector(): Selector { + return NativeSelectorProvider.getInstance().openSelector() + } + + // get the channel + private fun getChannel(k: SelectionKey): UnixSocketChannel { + return k.channel() as UnixSocketChannel + } + + companion object { + private val LOG = LoggerFactory.getLogger(TrustmeUnixSocketThread::class.java) + } + + // constructor setting another socket address + init { + selector = initSelector() + } +} diff --git a/ids-dataflow-control/src/main/kotlin/de/fhg/aisec/ids/dataflowcontrol/PolicyDecisionPoint.kt b/ids-dataflow-control/src/main/kotlin/de/fhg/aisec/ids/dataflowcontrol/PolicyDecisionPoint.kt index c3a874f69..2c9c9050c 100644 --- a/ids-dataflow-control/src/main/kotlin/de/fhg/aisec/ids/dataflowcontrol/PolicyDecisionPoint.kt +++ b/ids-dataflow-control/src/main/kotlin/de/fhg/aisec/ids/dataflowcontrol/PolicyDecisionPoint.kt @@ -119,13 +119,7 @@ class PolicyDecisionPoint : PDP, PAP { */ private fun createTransformationQuery(target: ServiceNode): String { val sb = StringBuilder() - val plEndpoint: String - if (target.endpoint != null) { - plEndpoint = escape(target.endpoint) - // sb.append("dominant_allow_rules(").append(plEndpoint).append(", _T, _), ") - } else { - throw RuntimeException("No endpoint specified!") - } + val plEndpoint = escape(target.endpoint) // Removed due to unclear relevance // if (target.capabilties.size + target.properties.size > 0) { // val capProp = LinkedList() @@ -366,10 +360,10 @@ class PolicyDecisionPoint : PDP, PAP { transformationCache.invalidateAll() } - override fun loadPolicy(theory: String?) { + override fun loadPolicy(theory: String) { // Load policy into engine, possibly overwriting the existing one. - this.engine.loadPolicy(theory ?: "") - LuconEngine.setDefaultPolicy(theory ?: "") + this.engine.loadPolicy(theory) + LuconEngine.setDefaultPolicy(theory) } override fun listRules(): List { @@ -382,9 +376,8 @@ class PolicyDecisionPoint : PDP, PAP { } } - override fun getPolicy(): String { - return this.engine.theory - } + override val policy: String + get() = this.engine.theory override fun verifyRoute(routeId: String): RouteVerificationProof? { val rm = this.routeManager diff --git a/ids-dataflow-control/src/main/kotlin/de/fhg/aisec/ids/dataflowcontrol/lucon/CounterExampleImpl.kt b/ids-dataflow-control/src/main/kotlin/de/fhg/aisec/ids/dataflowcontrol/lucon/CounterExampleImpl.kt index 7cc5689f4..f90d33551 100644 --- a/ids-dataflow-control/src/main/kotlin/de/fhg/aisec/ids/dataflowcontrol/lucon/CounterExampleImpl.kt +++ b/ids-dataflow-control/src/main/kotlin/de/fhg/aisec/ids/dataflowcontrol/lucon/CounterExampleImpl.kt @@ -28,7 +28,7 @@ class CounterExampleImpl(term: Term) : CounterExample() { init { val traceIterator = (term as Struct).listIterator() - val steps = LinkedList() + val steps = LinkedList() // process explanation val reasonIterator = (traceIterator.next() as Struct).listIterator() val sb = diff --git a/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/PolicyEnforcementPoint.kt b/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/PolicyEnforcementPoint.kt index c8f5d496c..1165fba15 100644 --- a/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/PolicyEnforcementPoint.kt +++ b/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/PolicyEnforcementPoint.kt @@ -192,7 +192,7 @@ internal constructor(private val destinationNode: NamedNode, target: Processor) // else may be added later) container.imageDigests.any { it.split(":").last() == hash - } || container.imageId.split(":").last() == hash + } || container.imageId?.split(":")?.last() == hash } // Save all ip addresses of allowed containers in one list val allowedIPs = @@ -226,17 +226,17 @@ internal constructor(private val destinationNode: NamedNode, target: Processor) } } - val sourceServiceNode = ServiceNode(source, null, null) - val destinationServiceNode = ServiceNode(destination, null, null) + val sourceServiceNode = ServiceNode(source) + val destinationServiceNode = ServiceNode(destination) // Call PDP to transform labels and decide whether to forward the Exchange applyLabelTransformation(pdp.requestTranformations(sourceServiceNode), exchange) - val labels = exchangeLabels.computeIfAbsent(exchange) { HashSet() } + val labels = exchangeLabels.computeIfAbsent(exchange) { HashSet() } val decision = pdp.requestDecision( DecisionRequest(sourceServiceNode, destinationServiceNode, labels, null) ) - return when (decision.decision!!) { + return when (decision.decision) { PolicyDecision.Decision.ALLOW -> true PolicyDecision.Decision.DENY -> { if (LOG.isWarnEnabled) { @@ -263,7 +263,7 @@ internal constructor(private val destinationNode: NamedNode, target: Processor) requestTransformations: TransformationDecision, exchange: Exchange ) { - val labels = exchangeLabels.computeIfAbsent(exchange) { HashSet() } + val labels = exchangeLabels.computeIfAbsent(exchange) { HashSet() } // Remove labels from exchange labels.removeAll(requestTransformations.labelsToRemove) diff --git a/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/RouteManagerService.kt b/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/RouteManagerService.kt index d4b3af80d..36d40fb34 100644 --- a/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/RouteManagerService.kt +++ b/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/RouteManagerService.kt @@ -67,19 +67,20 @@ import javax.xml.bind.JAXBException class RouteManagerService : RouteManager { @Autowired private lateinit var ctx: ApplicationContext - override fun getRoutes(): List { - val result: MutableList = ArrayList() - val camelContexts = camelContexts + override val routes: List + get() { + val result: MutableList = ArrayList() + val camelContexts = camelContexts - // Create response - for (cCtx in camelContexts) { - val mcc = cCtx.adapt(ModelCamelContext::class.java) - for (rd in mcc.routeDefinitions) { - result.add(routeDefinitionToObject(cCtx, rd)) + // Create response + for (cCtx in camelContexts) { + val mcc = cCtx.adapt(ModelCamelContext::class.java) + for (rd in mcc.routeDefinitions) { + result.add(routeDefinitionToObject(cCtx, rd)) + } } + return result } - return result - } override fun getRoute(id: String): RouteObject? { val camelContexts = camelContexts @@ -142,16 +143,17 @@ class RouteManagerService : RouteManager { } } - override fun getEndpoints(): Map> { - return camelContexts - .stream() - .collect( - Collectors.toMap( - { obj: CamelContext -> obj.name }, - { c: CamelContext -> c.endpoints.map { obj: Endpoint -> obj.endpointUri } } + override val endpoints: Map> + get() { + return camelContexts + .stream() + .collect( + Collectors.toMap( + { obj: CamelContext -> obj.name }, + { c: CamelContext -> c.endpoints.map { obj: Endpoint -> obj.endpointUri } } + ) ) - ) - } + } override fun listEndpoints(): Map { val epURIs: MutableMap = HashMap() @@ -163,45 +165,46 @@ class RouteManagerService : RouteManager { return epURIs } - override fun getRouteMetrics(): Map { - val rdump: MutableMap = HashMap() - val cCtxs = camelContexts - for (cCtx in cCtxs) { - val mcc = cCtx.adapt(ModelCamelContext::class.java) - val rds = mcc.routeDefinitions - for (rd in rds) { - var stat: RouteStatDump? - try { - stat = getRouteStats(cCtx, rd) - if (stat != null) { - val m = RouteMetrics() - m.completed = stat.exchangesCompleted - m.redeliveries = stat.redeliveries - m.failed = stat.exchangesFailed - m.failuresHandled = stat.failuresHandled - m.inflight = stat.exchangesInflight - m.maxProcessingTime = stat.maxProcessingTime - m.minProcessingTime = stat.minProcessingTime - m.meanProcessingTime = stat.meanProcessingTime - rdump[rd.id] = m + override val routeMetrics: Map + get() { + val rdump: MutableMap = HashMap() + val cCtxs = camelContexts + for (cCtx in cCtxs) { + val mcc = cCtx.adapt(ModelCamelContext::class.java) + val rds = mcc.routeDefinitions + for (rd in rds) { + var stat: RouteStatDump? + try { + stat = getRouteStats(cCtx, rd) + if (stat != null) { + val m = RouteMetrics() + m.completed = stat.exchangesCompleted + m.redeliveries = stat.redeliveries + m.failed = stat.exchangesFailed + m.failuresHandled = stat.failuresHandled + m.inflight = stat.exchangesInflight + m.maxProcessingTime = stat.maxProcessingTime + m.minProcessingTime = stat.minProcessingTime + m.meanProcessingTime = stat.meanProcessingTime + rdump[rd.id] = m + } + } catch (e: MalformedObjectNameException) { + LOG.error(e.message, e) + } catch (e: AttributeNotFoundException) { + LOG.error(e.message, e) + } catch (e: InstanceNotFoundException) { + LOG.error(e.message, e) + } catch (e: MBeanException) { + LOG.error(e.message, e) + } catch (e: ReflectionException) { + LOG.error(e.message, e) + } catch (e: JAXBException) { + LOG.error(e.message, e) } - } catch (e: MalformedObjectNameException) { - LOG.error(e.message, e) - } catch (e: AttributeNotFoundException) { - LOG.error(e.message, e) - } catch (e: InstanceNotFoundException) { - LOG.error(e.message, e) - } catch (e: MBeanException) { - LOG.error(e.message, e) - } catch (e: ReflectionException) { - LOG.error(e.message, e) - } catch (e: JAXBException) { - LOG.error(e.message, e) } } + return rdump } - return rdump - } override fun delRoute(routeId: String) { val cCtxs = camelContexts @@ -460,16 +463,16 @@ class RouteManagerService : RouteManager { /** * Create a new route in a fresh context from text * - * @param routeRepresentation The textual representation of the route to be inserted + * @param routeDefinition The textual representation of the route to be inserted * @throws RouteException If a route with that name already exists */ @Throws(RouteException::class) - override fun addRoute(routeRepresentation: String) { - LOG.debug("Adding new route: $routeRepresentation") + override fun addRoute(routeDefinition: String) { + LOG.debug("Adding new route: $routeDefinition") val existingRoutes = this.routes val cCtx: CamelContext = DefaultCamelContext() try { - ByteArrayInputStream(routeRepresentation.toByteArray(StandardCharsets.UTF_8)).use { bis + ByteArrayInputStream(routeDefinition.toByteArray(StandardCharsets.UTF_8)).use { bis -> // Load route(s) from XML val rd = ModelHelper.loadRoutesDefinition(cCtx, bis) diff --git a/ids-settings/src/main/kotlin/de/fhg/aisec/ids/settings/SettingsComponent.kt b/ids-settings/src/main/kotlin/de/fhg/aisec/ids/settings/SettingsComponent.kt index 41a47934f..79d2a512a 100644 --- a/ids-settings/src/main/kotlin/de/fhg/aisec/ids/settings/SettingsComponent.kt +++ b/ids-settings/src/main/kotlin/de/fhg/aisec/ids/settings/SettingsComponent.kt @@ -91,37 +91,36 @@ class SettingsComponent : Settings { } @PreDestroy + @Suppress("unused") fun deactivate() { LOG.debug("Close Settings Database...") mapDB.close() } - override fun getConnectorConfig() = - settingsStore.getOrElse(CONNECTOR_SETTINGS_KEY) { ConnectorConfig() } as ConnectorConfig - - override fun setConnectorConfig(connectorConfig: ConnectorConfig) { - settingsStore[CONNECTOR_SETTINGS_KEY] = connectorConfig - mapDB.commit() - } - - override fun getConnectorProfile() = - settingsStore.getOrElse(CONNECTOR_PROFILE_KEY) { ConnectorProfile() } as ConnectorProfile - - override fun setConnectorProfile(connectorProfile: ConnectorProfile) { - settingsStore[CONNECTOR_PROFILE_KEY] = connectorProfile - mapDB.commit() - } + override var connectorConfig: ConnectorConfig + get() = settingsStore.getOrElse(CONNECTOR_SETTINGS_KEY) { ConnectorConfig() } as ConnectorConfig + set(value) { + settingsStore[CONNECTOR_SETTINGS_KEY] = value + mapDB.commit() + } - override fun getConnectorJsonLd() = settingsStore[CONNECTOR_JSON_LD_KEY] as String? + override var connectorProfile: ConnectorProfile + get() = settingsStore.getOrElse(CONNECTOR_PROFILE_KEY) { ConnectorProfile() } as ConnectorProfile + set(value) { + settingsStore[CONNECTOR_PROFILE_KEY] = value + mapDB.commit() + } - override fun setConnectorJsonLd(jsonLd: String?) { - if (jsonLd == null) { - settingsStore -= CONNECTOR_JSON_LD_KEY - } else { - settingsStore[CONNECTOR_JSON_LD_KEY] = jsonLd + override var connectorJsonLd: String? + get() = settingsStore[CONNECTOR_JSON_LD_KEY] as String? + set(value) { + if (value == null) { + settingsStore -= CONNECTOR_JSON_LD_KEY + } else { + settingsStore[CONNECTOR_JSON_LD_KEY] = value + } + mapDB.commit() } - mapDB.commit() - } override fun getConnectionSettings(connection: String): ConnectionSettings = if (connection == Constants.GENERAL_CONFIG) { @@ -132,13 +131,13 @@ class SettingsComponent : Settings { } } - override fun setConnectionSettings(connection: String, conSettings: ConnectionSettings) { - connectionSettings[connection] = conSettings + override fun setConnectionSettings(connection: String, cSettings: ConnectionSettings) { + connectionSettings[connection] = cSettings mapDB.commit() } - override fun getAllConnectionSettings(): MutableMap = - Collections.unmodifiableMap(connectionSettings) + override val allConnectionSettings: MutableMap + get() = Collections.unmodifiableMap(connectionSettings) companion object { internal const val DB_VERSION_KEY = "db_version" diff --git a/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/AppApi.kt b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/AppApi.kt index a3ba2a1f0..02a680b04 100644 --- a/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/AppApi.kt +++ b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/AppApi.kt @@ -37,7 +37,7 @@ import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Component import java.io.IOException import java.time.ZonedDateTime -import java.util.concurrent.Executors +import java.util.concurrent.CompletableFuture import java.util.concurrent.TimeUnit import java.util.stream.Collectors import javax.ws.rs.Consumes @@ -118,7 +118,7 @@ class AppApi { @Produces(MediaType.APPLICATION_JSON) @AuthorizationRequired fun start( - @ApiParam(value = "ID of the app to start") @PathParam("containerId") containerId: String? + @ApiParam(value = "ID of the app to start") @PathParam("containerId") containerId: String ): Boolean { return start(containerId, null) } @@ -140,7 +140,7 @@ class AppApi { @Produces(MediaType.APPLICATION_JSON) @AuthorizationRequired fun start( - @ApiParam(value = "ID of the app to start") @PathParam("containerId") containerId: String?, + @ApiParam(value = "ID of the app to start") @PathParam("containerId") containerId: String, @ApiParam(value = "Key for user token (required for trustX containers)") @PathParam("key") key: String? ): Boolean { return try { @@ -172,7 +172,7 @@ class AppApi { @Produces(MediaType.APPLICATION_JSON) @AuthorizationRequired fun stop( - @ApiParam(value = "ID of the app to stop") @PathParam("containerId") containerId: String? + @ApiParam(value = "ID of the app to stop") @PathParam("containerId") containerId: String ): Boolean { return try { cml.stopContainer(containerId) @@ -219,15 +219,9 @@ class AppApi { throw InternalServerErrorException("Null image") } LOG.debug("Pulling app {}", image) - val executor = Executors.newScheduledThreadPool(Runtime.getRuntime().availableProcessors()) - - // Pull image asynchronously and create new container - val handler = executor.submit { - val containerId = cml.pullImage(app) - containerId.orElse(null) - } - // Cancel pulling after 20 minutes, just in case. - executor.schedule({ handler.cancel(true) }, PULL_TIMEOUT_MINUTES, TimeUnit.MINUTES) + CompletableFuture.supplyAsync { + cml.pullImage(app) + }.completeOnTimeout(null, PULL_TIMEOUT_MINUTES, TimeUnit.MINUTES) return "OK" } @@ -240,7 +234,7 @@ class AppApi { ) @AuthorizationRequired fun wipe( - @ApiParam(value = "ID of the app to wipe") @QueryParam("containerId") containerId: String? + @ApiParam(value = "ID of the app to wipe") @QueryParam("containerId") containerId: String ): String { try { cml.wipe(containerId) @@ -295,11 +289,11 @@ class AppApi { .parallelStream() .filter { app: ApplicationContainer -> ( - app.name != null && app.name.contains(term) || - app.description != null && app.description.contains(term) || - app.image != null && app.image.contains(term) || - app.id != null && app.id.contains(term) || - app.categories != null && app.categories.contains(term) + app.name?.contains(term) ?: false || + app.description?.contains(term) ?: false || + app.image?.contains(term) ?: false || + app.id?.contains(term) ?: false || + app.categories.contains(term) ) } .collect(Collectors.toList()) diff --git a/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/ConfigApi.kt b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/ConfigApi.kt index 73bfce049..ab522a07d 100644 --- a/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/ConfigApi.kt +++ b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/ConfigApi.kt @@ -126,25 +126,23 @@ class ConfigApi { @PathParam("con") connection: String, conSettings: ConnectionSettings? ): Response { - if (conSettings == null) { - Response.serverError().entity("No valid connection settings received!").build() - } - - // connection has format " - host:port" - // store only "host:port" in database to make connection available in other parts of the application - // where rout_id is not available - val m = CONNECTION_CONFIG_PATTERN.matcher(connection) - if (!m.matches()) { - // GENERAL_CONFIG has changed - settings.setConnectionSettings(connection, conSettings) - } else { - // specific endpoint config has changed - settings.setConnectionSettings(m.group(1), conSettings) + return conSettings?.let { + // connection has format " - host:port" + // store only "host:port" in database to make connection available in other parts of the application + // where rout_id is not available + val m = CONNECTION_CONFIG_PATTERN.matcher(connection) + if (!m.matches()) { + // GENERAL_CONFIG has changed + settings.setConnectionSettings(connection, it) + } else { + // specific endpoint config has changed + settings.setConnectionSettings(m.group(1), it) - // notify EndpointConfigurationListeners that some endpointConfig has changed - endpointConfigManager?.notify(m.group(1)) - } - return Response.ok().build() + // notify EndpointConfigurationListeners that some endpointConfig has changed + endpointConfigManager?.notify(m.group(1)) + } + Response.ok().build() + } ?: Response.serverError().entity("No valid connection settings received!").build() } /** @@ -160,7 +158,7 @@ class ConfigApi { MediaType.APPLICATION_JSON ) @AuthorizationRequired - fun getConnectionConfigurations(@PathParam("con") connection: String?): ConnectionSettings { + fun getConnectionConfigurations(@PathParam("con") connection: String): ConnectionSettings { return settings.getConnectionSettings(connection) } // add endpoint configurations// For every currently available endpoint, go through all preferences and check // if the id is already there. If not, create empty config. @@ -217,7 +215,7 @@ class ConfigApi { allSettings.putIfAbsent(Constants.GENERAL_CONFIG, ConnectionSettings()) val routeInputs = routeManager .routes - .map { it.id } + .mapNotNull { it.id } .associateWith { routeManager.getRouteInputUris(it) } // add all available endpoints diff --git a/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/PolicyApi.kt b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/PolicyApi.kt index acb9633c1..16114112b 100644 --- a/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/PolicyApi.kt +++ b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/PolicyApi.kt @@ -93,7 +93,7 @@ class PolicyApi { fun install( @FormParam(value = "policy_name") @DefaultValue(value = "default policy") policyName: String?, @FormParam(value = "policy_description") @DefaultValue(value = "") policyDescription: String?, - @FormParam(value = "policy_file") policy: String? + @FormParam(value = "policy_file") policy: String ): String { LOG.info("Received policy file. name: {}, desc: {}", policyName, policyDescription) return policyAdministrationPoint?.let { pap -> diff --git a/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/data/Cert.kt b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/data/Cert.kt index a781445f4..260f8d1c9 100644 --- a/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/data/Cert.kt +++ b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/data/Cert.kt @@ -27,7 +27,6 @@ class Cert { var subjectOU: String? = null var subjectAltNames: Collection>? = null var subjectCN: String? = null - @kotlin.jvm.JvmField var alias: String? = null var file: String? = null var certificate: String? = null diff --git a/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/packageinfo b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/packageinfo deleted file mode 100644 index 9ad81f6fa..000000000 --- a/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/packageinfo +++ /dev/null @@ -1 +0,0 @@ -version 1.0.0 diff --git a/ids-webconsole/src/test/java/de/fhg/aisec/ids/webconsole/api/PortainerCompatibilityIT.java b/ids-webconsole/src/test/java/de/fhg/aisec/ids/webconsole/api/PortainerCompatibilityIT.java deleted file mode 100644 index edf4be5ba..000000000 --- a/ids-webconsole/src/test/java/de/fhg/aisec/ids/webconsole/api/PortainerCompatibilityIT.java +++ /dev/null @@ -1,73 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-webconsole - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.webconsole.api; - -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import com.fasterxml.jackson.databind.ObjectMapper; -import de.fhg.aisec.ids.api.cm.ApplicationContainer; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.net.HttpURLConnection; -import java.net.URL; -import org.junit.Test; - -public class PortainerCompatibilityIT { - - /** - * Retrieves portainer templates as JSON and tries to map it to java using Jackson objectmapper. - * - * @throws IOException - */ - @Test - public void test() throws IOException { - String url = "https://raw.githubusercontent.com/portainer/templates/master/templates.json"; - URL u = new URL(url); - HttpURLConnection c = (HttpURLConnection) u.openConnection(); - c.setRequestMethod("GET"); - c.setRequestProperty("Content-length", "0"); - c.setUseCaches(false); - c.setAllowUserInteraction(false); - c.setConnectTimeout(3000); - c.setReadTimeout(3000); - c.connect(); - int status = c.getResponseCode(); - String json = ""; - switch (status) { - case 200: - case 201: - BufferedReader br = new BufferedReader(new InputStreamReader(c.getInputStream())); - StringBuilder sb = new StringBuilder(); - String line; - while ((line = br.readLine()) != null) { - sb.append(line + "\n"); - } - br.close(); - json = sb.toString(); - } - ObjectMapper mapper = new ObjectMapper(); - ApplicationContainer[] cont = mapper.readValue(json.getBytes(), ApplicationContainer[].class); - - assertNotNull(cont); - assertTrue(cont.length > 0); - } -} diff --git a/ids-webconsole/src/test/java/de/fhg/aisec/ids/webconsole/api/RestApiTests.java b/ids-webconsole/src/test/java/de/fhg/aisec/ids/webconsole/api/RestApiTests.java deleted file mode 100644 index 0b2b0c2ee..000000000 --- a/ids-webconsole/src/test/java/de/fhg/aisec/ids/webconsole/api/RestApiTests.java +++ /dev/null @@ -1,256 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ids-webconsole - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.webconsole.api; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider; -import de.fhg.aisec.ids.api.settings.ConnectorConfig; -import de.fhg.aisec.ids.api.settings.Settings; -import de.fhg.aisec.ids.webconsole.api.data.Cert; -import de.fhg.aisec.ids.webconsole.api.data.Identity; -import de.fhg.aisec.ids.webconsole.api.data.User; -import org.apache.cxf.endpoint.Server; -import org.apache.cxf.jaxrs.JAXRSServerFactoryBean; -import org.apache.cxf.jaxrs.client.WebClient; -import org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider; -import org.apache.cxf.transport.local.LocalConduit; -import org.junit.*; - -import javax.ws.rs.core.GenericType; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import static org.junit.Assume.assumeFalse; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class RestApiTests extends Assert { - private static final String ENDPOINT_ADDRESS = "local://testserver"; - private static Server server; - private static final Settings settings = mock(Settings.class); - - @BeforeClass - public static void initialize() { - var connectorConfig = new ConnectorConfig(); - when(settings.getConnectorConfig()).thenReturn(connectorConfig); - - startServer(); - } - - /** Starts a test server. Note that REST endpoints must be registered manually here. */ - private static void startServer() { - JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean(); - sf.setResourceClasses(CertApi.class); - sf.setResourceClasses(MetricAPI.class); - sf.setResourceClasses(UserApi.class); - - // Server uses Jackson for JSON mapping - List providers = new ArrayList<>(); - JacksonJsonProvider jackson = new JacksonJsonProvider(); - jackson.setMapper(new ObjectMapper()); - providers.add(jackson); - providers.add(new JWTRestAPIFilter()); - // add custom providers if any - sf.setProviders(providers); - - sf.setResourceProvider(CertApi.class, new SingletonResourceProvider(new CertApi(settings), true)); - sf.setResourceProvider(MetricAPI.class, new SingletonResourceProvider(new MetricAPI(), true)); - sf.setResourceProvider(UserApi.class, new SingletonResourceProvider(new UserApi(), true)); - sf.setAddress(ENDPOINT_ADDRESS); - - server = sf.create(); - } - - private WebClient newClient(String... token) { - // Client uses Jackson for JSON mapping - JacksonJsonProvider jackson = new JacksonJsonProvider(); - jackson.setMapper(new ObjectMapper()); - WebClient client = WebClient.create(ENDPOINT_ADDRESS, Collections.singletonList(jackson)); - WebClient.getConfig(client).getRequestContext().put(LocalConduit.DIRECT_DISPATCH, Boolean.TRUE); - if (token != null && token.length > 0) { - client.header("Authorization", "Bearer: " + token[0]); - } - return client; - } - - @AfterClass - public static void destroy() { - server.stop(); - server.destroy(); - } - - @Before - public void before() { - CertApi certApi = new CertApi(settings); - - Identity idSpec = new Identity(); - idSpec.c = "c"; - idSpec.cn = "common name"; - idSpec.l = "location"; - idSpec.s = "subject"; - certApi.createIdentity(idSpec); - } - - @Test - public void testListCerts() { - String token = login(); - - WebClient client = newClient(token); - client.accept(MediaType.APPLICATION_JSON); - client.path("/certs/list_certs"); - List certs = client.get(new GenericType<>() { - }); - assertNotNull(certs); - assertTrue(certs.size() > 0); - } - - @Test - public void testListIdentities() { - String token = login(); - - WebClient client = newClient(token); - client.accept(MediaType.APPLICATION_JSON); - client.path("/certs/list_identities"); - List keys = client.get(new GenericType<>() { - }); - assertNotNull(keys); - assertTrue(keys.size() > 0); - } - - @Test - public void testCreateIdentity() { - String token = login(); - - WebClient client = newClient(token); - - Identity idSpec = new Identity(); - idSpec.c = "c"; - idSpec.cn = "common name"; - idSpec.l = "location"; - idSpec.s = "subject"; - - client.accept(MediaType.APPLICATION_JSON); - client.header("Content-type", MediaType.APPLICATION_JSON); - client.path("/certs/create_identity"); - String alias = client.post(idSpec, String.class); - assertTrue(alias.length() > 5); - } - - @Test - public void testDeleteIdentity() { - String token = login(); - - // Get list of identities - WebClient client = newClient(token); - client.accept(MediaType.APPLICATION_JSON); - client.path("/certs/list_identities"); - List certs = client.get(new GenericType<>() { - }); - assumeFalse(certs.isEmpty()); - - // Choose an identity and delete it - client = newClient(token); - String alias = certs.get(0).alias; - client.header("Content-type", MediaType.APPLICATION_JSON); - client.path("/certs/delete_identity"); - Response resp = client.post(alias); - assertEquals(Response.Status.OK.getStatusCode(), resp.getStatus()); - - // Confirm it has been deleted - client = newClient(token); - client.path("/certs/list_identities"); - List keys = client.get(new GenericType<>() { - }); - boolean contained = false; - for (Cert k : keys) { - contained |= alias.equals(k.alias); - } - assertFalse(contained); - } - - @Ignore("Needs Fix, non-critical") - @Test - public void deleteCerts() { - String token = login(); - - // Get list of certs - WebClient client = newClient(token); - client.accept(MediaType.APPLICATION_JSON); - client.path("/certs/list_certs"); - List certs = client.get(new GenericType<>() { - }); - assumeFalse(certs.isEmpty()); - - // Choose a cert and delete it - client = newClient(token); - String alias = certs.get(0).alias; - client.header("Content-type", MediaType.APPLICATION_JSON); - client.path("/certs/delete_cert"); - Response resp = client.post(alias); - assertEquals(Response.Status.OK.getStatusCode(), resp.getStatus()); - - // Confirm it has been deleted - client = newClient(token); - client.path("/certs/list_certs"); - List keys = client.get(new GenericType<>() { - }); - boolean contained = false; - for (Cert k : keys) { - contained |= alias.equals(k.alias); - } - assertFalse(contained); - } - - @Test - public void getMetrics() { - String token = login(); - - // Access a protected endpoint - WebClient c = newClient(token); - c.accept(MediaType.APPLICATION_JSON); - c.path("/metric/get"); - Map metrics = c.get(new GenericType<>() { - }); - assumeFalse(metrics.isEmpty()); - } - - /** - * Retrieves a fresh JWT from server. - * - * @return The generated authentication token - */ - private String login() { - WebClient c = newClient(); - c.path("/user/login"); - c.accept(MediaType.APPLICATION_JSON); - c.header("Content-type", MediaType.APPLICATION_JSON); - User u = new User(); - u.username = "ids"; - u.password = "ids"; - Map result = c.post(u, new GenericType<>() {}); - String token = result.get("token"); - c.header("Authorization", "Bearer: " + token); - return token; - } -} diff --git a/ids-webconsole/src/test/kotlin/de/fhg/aisec/ids/webconsole/api/PortainerCompatibilityIT.kt b/ids-webconsole/src/test/kotlin/de/fhg/aisec/ids/webconsole/api/PortainerCompatibilityIT.kt new file mode 100644 index 000000000..46ecc9107 --- /dev/null +++ b/ids-webconsole/src/test/kotlin/de/fhg/aisec/ids/webconsole/api/PortainerCompatibilityIT.kt @@ -0,0 +1,75 @@ +/*- + * ========================LICENSE_START================================= + * ids-webconsole + * %% + * Copyright (C) 2019 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.webconsole.api + +import com.fasterxml.jackson.databind.ObjectMapper +import de.fhg.aisec.ids.api.cm.ApplicationContainer +import org.junit.Assert +import org.junit.Test +import java.io.BufferedReader +import java.io.IOException +import java.io.InputStreamReader +import java.net.HttpURLConnection +import java.net.URL + +class PortainerCompatibilityIT { + /** + * Retrieves portainer templates as JSON and tries to map it to java using Jackson objectmapper. + * + * @throws IOException + */ + @Test + @Throws(IOException::class) + fun test() { + val url = "https://raw.githubusercontent.com/portainer/templates/master/templates.json" + val u = URL(url) + val c = u.openConnection() as HttpURLConnection + c.requestMethod = "GET" + c.setRequestProperty("Content-length", "0") + c.useCaches = false + c.allowUserInteraction = false + c.connectTimeout = 3000 + c.readTimeout = 3000 + c.connect() + val status = c.responseCode + var json = "" + when (status) { + 200, 201 -> { + val br = BufferedReader(InputStreamReader(c.inputStream)) + val sb = StringBuilder() + var line: String + while (br.readLine().also { line = it } != null) { + sb.append( + """ + $line + + """.trimIndent() + ) + } + br.close() + json = sb.toString() + } + } + val mapper = ObjectMapper() + val cont = mapper.readValue(json.toByteArray(), Array::class.java) + Assert.assertNotNull(cont) + Assert.assertTrue(cont.isNotEmpty()) + } +} diff --git a/ids-webconsole/src/test/kotlin/de/fhg/aisec/ids/webconsole/api/RestApiTests.kt b/ids-webconsole/src/test/kotlin/de/fhg/aisec/ids/webconsole/api/RestApiTests.kt new file mode 100644 index 000000000..912923f1f --- /dev/null +++ b/ids-webconsole/src/test/kotlin/de/fhg/aisec/ids/webconsole/api/RestApiTests.kt @@ -0,0 +1,251 @@ +/*- + * ========================LICENSE_START================================= + * ids-webconsole + * %% + * Copyright (C) 2019 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.webconsole.api + +import com.fasterxml.jackson.databind.ObjectMapper +import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider +import de.fhg.aisec.ids.api.settings.ConnectorConfig +import de.fhg.aisec.ids.api.settings.Settings +import de.fhg.aisec.ids.webconsole.api.data.Cert +import de.fhg.aisec.ids.webconsole.api.data.Identity +import de.fhg.aisec.ids.webconsole.api.data.User +import org.apache.cxf.endpoint.Server +import org.apache.cxf.jaxrs.JAXRSServerFactoryBean +import org.apache.cxf.jaxrs.client.WebClient +import org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider +import org.apache.cxf.transport.local.LocalConduit +import org.junit.AfterClass +import org.junit.Assert +import org.junit.Assume +import org.junit.Before +import org.junit.BeforeClass +import org.junit.Ignore +import org.junit.Test +import org.mockito.Mockito +import javax.ws.rs.core.GenericType +import javax.ws.rs.core.MediaType +import javax.ws.rs.core.Response +import kotlin.String + +class RestApiTests : Assert() { + private fun newClient(vararg token: String): WebClient { + // Client uses Jackson for JSON mapping + val jackson = JacksonJsonProvider() + jackson.setMapper(ObjectMapper()) + val client = WebClient.create(ENDPOINT_ADDRESS, listOf(jackson)) + WebClient.getConfig(client).requestContext[LocalConduit.DIRECT_DISPATCH] = true + if (token.isNotEmpty()) { + client.header("Authorization", "Bearer: " + token[0]) + } + return client + } + + @Before + fun before() { + val certApi = CertApi(settings) + val idSpec = Identity() + idSpec.c = "c" + idSpec.cn = "common name" + idSpec.l = "location" + idSpec.s = "subject" + certApi.createIdentity(idSpec) + } + + @Test + fun testListCerts() { + val token = login() + val client = newClient(token!!) + client.accept(MediaType.APPLICATION_JSON) + client.path("/certs/list_certs") + val certs: List = client.get(object : GenericType>() {}) + assertNotNull(certs) + assertTrue(certs.isNotEmpty()) + } + + @Test + fun testListIdentities() { + val token = login() + val client = newClient(token!!) + client.accept(MediaType.APPLICATION_JSON) + client.path("/certs/list_identities") + val keys: List = client.get(object : GenericType>() {}) + assertNotNull(keys) + assertTrue(keys.isNotEmpty()) + } + + @Test + fun testCreateIdentity() { + val token = login() + val client = newClient(token!!) + val idSpec = Identity() + idSpec.c = "c" + idSpec.cn = "common name" + idSpec.l = "location" + idSpec.s = "subject" + client.accept(MediaType.APPLICATION_JSON) + client.header("Content-type", MediaType.APPLICATION_JSON) + client.path("/certs/create_identity") + val alias = client.post(idSpec, String::class.java) + assertTrue(alias.length > 5) + } + + @Test + fun testDeleteIdentity() { + val token = login() + + // Get list of identities + var client = newClient(token!!) + client.accept(MediaType.APPLICATION_JSON) + client.path("/certs/list_identities") + val certs: List = client.get(object : GenericType>() {}) + Assume.assumeFalse(certs.isEmpty()) + + // Choose an identity and delete it + client = newClient(token) + val alias = certs[0].alias + client.header("Content-type", MediaType.APPLICATION_JSON) + client.path("/certs/delete_identity") + val resp = client.post(alias) + assertEquals(Response.Status.OK.statusCode.toLong(), resp.status.toLong()) + + // Confirm it has been deleted + client = newClient(token) + client.path("/certs/list_identities") + val keys: List = client.get(object : GenericType>() {}) + var contained = false + for (k in keys) { + contained = contained or (alias == k.alias) + } + assertFalse(contained) + } + + @Ignore("Needs Fix, non-critical") + @Test + fun deleteCerts() { + val token = login() + + // Get list of certs + var client = newClient(token!!) + client.accept(MediaType.APPLICATION_JSON) + client.path("/certs/list_certs") + val certs: List = client.get(object : GenericType>() {}) + Assume.assumeFalse(certs.isEmpty()) + + // Choose a cert and delete it + client = newClient(token) + val alias = certs[0].alias + client.header("Content-type", MediaType.APPLICATION_JSON) + client.path("/certs/delete_cert") + val resp = client.post(alias) + assertEquals(Response.Status.OK.statusCode.toLong(), resp.status.toLong()) + + // Confirm it has been deleted + client = newClient(token) + client.path("/certs/list_certs") + val keys: List = client.get(object : GenericType>() {}) + var contained = false + for (k in keys) { + contained = contained or (alias == k.alias) + } + assertFalse(contained) + } + + // Access a protected endpoint + @get:Test + val metrics: Unit + get() { + val token = login() + + // Access a protected endpoint + val c = newClient(token!!) + c.accept(MediaType.APPLICATION_JSON) + c.path("/metric/get") + val metrics: Map = + c.get(object : GenericType>() {}) + Assume.assumeFalse(metrics.isEmpty()) + } + + /** + * Retrieves a fresh JWT from server. + * + * @return The generated authentication token + */ + private fun login(): String? { + val c = newClient() + c.path("/user/login") + c.accept(MediaType.APPLICATION_JSON) + c.header("Content-type", MediaType.APPLICATION_JSON) + val u = User() + u.username = "ids" + u.password = "ids" + val result: Map = + c.post(u, object : GenericType>() {}) + val token = result["token"] + c.header("Authorization", "Bearer: $token") + return token + } + + companion object { + private const val ENDPOINT_ADDRESS = "local://testserver" + private var server: Server? = null + private val settings = Mockito.mock( + Settings::class.java + ) + + @BeforeClass + @JvmStatic + fun initialize() { + val connectorConfig = ConnectorConfig() + Mockito.`when`(settings.connectorConfig).thenReturn(connectorConfig) + startServer() + } + + /** Starts a test server. Note that REST endpoints must be registered manually here. */ + private fun startServer() { + val sf = JAXRSServerFactoryBean() + sf.setResourceClasses(CertApi::class.java) + sf.setResourceClasses(MetricAPI::class.java) + sf.setResourceClasses(UserApi::class.java) + + // Server uses Jackson for JSON mapping + val providers: MutableList = ArrayList() + val jackson = JacksonJsonProvider() + jackson.setMapper(ObjectMapper()) + providers.add(jackson) + providers.add(JWTRestAPIFilter()) + // add custom providers if any + sf.providers = providers + sf.setResourceProvider(CertApi::class.java, SingletonResourceProvider(CertApi(settings), true)) + sf.setResourceProvider(MetricAPI::class.java, SingletonResourceProvider(MetricAPI(), true)) + sf.setResourceProvider(UserApi::class.java, SingletonResourceProvider(UserApi(), true)) + sf.address = ENDPOINT_ADDRESS + server = sf.create() + } + + @AfterClass + @JvmStatic + fun destroy() { + server?.run { + stop() + destroy() + } + } + } +} From 90d0af81cc65b8bf3f680bd0d9f843ea6b7d3932 Mon Sep 17 00:00:00 2001 From: Jean-Luc Reding Date: Tue, 18 May 2021 18:38:46 +0200 Subject: [PATCH 48/54] REST functions for user management --- .../fhg/aisec/ids/webconsole/api/UserApi.kt | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/UserApi.kt b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/UserApi.kt index 1074ebe15..2210d5d16 100644 --- a/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/UserApi.kt +++ b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/UserApi.kt @@ -126,4 +126,35 @@ class UserApi { ctx.login() return true } + + @POST + @Path("/setPassword") + @AuthorizationRequired + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + fun setPassword(password: String) { + // find user + // val u:User = null + + // set password + // u.password = password + + // save user + } + + @POST + @Path("/addUser") + @AuthorizationRequired + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + fun addUser(user: User) { + } + + @POST + @Path("/removeUser") + @AuthorizationRequired + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + fun removeUser(username: String) { + } } From d166d13cd987bd502577544e43184bdded1d8f1f Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Tue, 18 May 2021 21:37:45 +0200 Subject: [PATCH 49/54] Implemented user database --- .../de/fhg/aisec/ids/api/settings/Settings.kt | 4 + .../aisec/ids/settings/SettingsComponent.kt | 21 +++ .../ids/webconsole/api/JWTRestAPIFilter.kt | 2 +- .../fhg/aisec/ids/webconsole/api/UserApi.kt | 124 ++++++++---------- .../fhg/aisec/ids/webconsole/api/data/User.kt | 2 - 5 files changed, 78 insertions(+), 75 deletions(-) diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/settings/Settings.kt b/ids-api/src/main/java/de/fhg/aisec/ids/api/settings/Settings.kt index 59fcf33f8..019a0a06a 100644 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/settings/Settings.kt +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/settings/Settings.kt @@ -28,4 +28,8 @@ interface Settings { fun getConnectionSettings(connection: String): ConnectionSettings fun setConnectionSettings(connection: String, cSettings: ConnectionSettings) val allConnectionSettings: Map + fun isUserStoreEmpty(): Boolean + fun getUserHash(username: String): String? + fun saveUser(username: String, hash: String) + fun removeUser(username: String) } diff --git a/ids-settings/src/main/kotlin/de/fhg/aisec/ids/settings/SettingsComponent.kt b/ids-settings/src/main/kotlin/de/fhg/aisec/ids/settings/SettingsComponent.kt index 79d2a512a..5762d52cb 100644 --- a/ids-settings/src/main/kotlin/de/fhg/aisec/ids/settings/SettingsComponent.kt +++ b/ids-settings/src/main/kotlin/de/fhg/aisec/ids/settings/SettingsComponent.kt @@ -139,6 +139,20 @@ class SettingsComponent : Settings { override val allConnectionSettings: MutableMap get() = Collections.unmodifiableMap(connectionSettings) + override fun isUserStoreEmpty() = userStore.isEmpty() + + override fun getUserHash(username: String) = userStore[username] + + override fun saveUser(username: String, hash: String) { + userStore += username to hash + mapDB.commit() + } + + override fun removeUser(username: String) { + userStore.remove(username) + mapDB.commit() + } + companion object { internal const val DB_VERSION_KEY = "db_version" internal const val CURRENT_DB_VERSION = 3 @@ -163,5 +177,12 @@ class SettingsComponent : Settings { .valueSerializer(OsgiElsaSerializer()) .createOrOpen() } + private val userStore: ConcurrentMap by lazy { + mapDB + .hashMap("user_store") + .keySerializer(Serializer.STRING) + .valueSerializer(Serializer.STRING) + .createOrOpen() + } } } diff --git a/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/JWTRestAPIFilter.kt b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/JWTRestAPIFilter.kt index dc2f18967..8eac9cc85 100644 --- a/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/JWTRestAPIFilter.kt +++ b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/JWTRestAPIFilter.kt @@ -53,7 +53,7 @@ class JWTRestAPIFilter : ContainerRequestFilter { // Verify token val jwt = authorizationHeader.substring(7).trim { it <= ' ' } - val algorithm: Algorithm = Algorithm.HMAC256(UserApi.key!!.encoded) + val algorithm: Algorithm = Algorithm.HMAC256(UserApi.key) val verifier = JWT.require(algorithm).withIssuer("ids-connector").build() // Reusable verifier instance verifier.verify(jwt) } catch (e: Exception) { diff --git a/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/UserApi.kt b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/UserApi.kt index 2210d5d16..0049100c1 100644 --- a/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/UserApi.kt +++ b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/UserApi.kt @@ -21,19 +21,16 @@ package de.fhg.aisec.ids.webconsole.api import com.auth0.jwt.JWT import com.auth0.jwt.algorithms.Algorithm +import de.fhg.aisec.ids.api.settings.Settings import de.fhg.aisec.ids.webconsole.api.data.User import io.swagger.annotations.Api import org.slf4j.LoggerFactory +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.security.crypto.argon2.Argon2PasswordEncoder import org.springframework.stereotype.Component -import java.security.Key -import java.security.NoSuchAlgorithmException +import java.nio.charset.StandardCharsets +import java.security.SecureRandom import java.util.Calendar -import javax.crypto.KeyGenerator -import javax.security.auth.callback.Callback -import javax.security.auth.callback.NameCallback -import javax.security.auth.callback.PasswordCallback -import javax.security.auth.login.Configuration -import javax.security.auth.login.LoginContext import javax.security.auth.login.LoginException import javax.ws.rs.Consumes import javax.ws.rs.POST @@ -47,20 +44,7 @@ import javax.ws.rs.core.Response @Api(value = "User Authentication") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) -class UserApi { - companion object { - private val LOG = LoggerFactory.getLogger(UserApi::class.java) - var key: Key? = null - - init { - try { - key = KeyGenerator.getInstance("HmacSHA256").generateKey() - } catch (e: NoSuchAlgorithmException) { - e.printStackTrace() - } - } - } - +class UserApi(@Autowired private val settings: Settings) { /** * Given a correct username/password, this method returns a JWT token that is valid for one day. * @@ -72,29 +56,31 @@ class UserApi { @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) fun authenticateUser(user: User): Response { - return try { - // Authenticate the user using the credentials provided - if (!authenticate(user.username, user.password)) { - return Response.status(Response.Status.UNAUTHORIZED).build() + if (user.username.isNullOrBlank() || user.password.isNullOrBlank()) { + LOG.error("Username or password blank, please provide valid login credentials!") + } else { + try { + // Authenticate the user using the credentials provided + if (!authenticate(user.username!!, user.password!!)) { + return Response.status(Response.Status.UNAUTHORIZED).build() + } + // Issue a token for the user + val token = issueToken(user.username) + return Response.ok().entity(mapOf("token" to token)).build() + } catch (e: Throwable) { + e.printStackTrace() } - // Issue a token for the user - val token = issueToken(user.username) - Response.ok().entity(mapOf("token" to token)).build() - } catch (e: Throwable) { - e.printStackTrace() - Response.status(Response.Status.UNAUTHORIZED).build() } + return Response.status(Response.Status.UNAUTHORIZED).build() } private fun issueToken(username: String?): String { - val cal = Calendar.getInstance() - cal.timeInMillis = cal.timeInMillis + 86400000 - val tomorrow = cal.time + val tomorrow = Calendar.getInstance().apply { timeInMillis += 86400000 }.time return JWT.create() .withClaim("user", username) .withExpiresAt(tomorrow) .withIssuer("ids-connector") - .sign(Algorithm.HMAC256(key!!.encoded)) + .sign(Algorithm.HMAC256(key)) } /** @@ -103,51 +89,32 @@ class UserApi { * can be configured as needed without changing this code here. */ @Throws(LoginException::class) - private fun authenticate(user: String?, password: String?): Boolean { - if (Configuration.getConfiguration().getAppConfigurationEntry("karaf") == null) { - LOG.warn( - "No LoginModules configured for karaf. This is okay if running as unit test. " + - "If this message appears in Karaf container, make sure that JAAS is available." - ) - return "ids" == user && "ids" == password - } - val ctx = LoginContext( - "karaf" - ) { callbacks: Array -> - for (cb in callbacks) { - if (cb is PasswordCallback) { - cb.password = password?.toCharArray() - } - if (cb is NameCallback) { - cb.name = user - } + private fun authenticate(username: String, password: String): Boolean { + return if (settings.isUserStoreEmpty()) { + LOG.warn("WARNING: User store is empty! This is insecure! Please create an admin user via the REST API!") + username == "ids" && password == "ids" + } else { + val expectedHash = settings.getUserHash(username) ?: randomHash + val loginOk = argonEncoder.matches(password, expectedHash) + // Upgrade hashing difficulty if necessary + if (loginOk && argonEncoder.upgradeEncoding(expectedHash)) { + settings.saveUser(username, argonEncoder.encode(password)) } + loginOk } - ctx.login() - return true } @POST - @Path("/setPassword") - @AuthorizationRequired - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - fun setPassword(password: String) { - // find user - // val u:User = null - - // set password - // u.password = password - - // save user - } - - @POST - @Path("/addUser") + @Path("/saveUser") @AuthorizationRequired @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) fun addUser(user: User) { + if (user.username.isNullOrBlank() || user.password.isNullOrBlank()) { + LOG.error("Username or password blank, please provide valid credentials!") + } else { + settings.saveUser(user.username!!, argonEncoder.encode(user.password)) + } } @POST @@ -156,5 +123,18 @@ class UserApi { @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) fun removeUser(username: String) { + settings.removeUser(username) + } + + companion object { + private val LOG = LoggerFactory.getLogger(UserApi::class.java) + val argonEncoder = Argon2PasswordEncoder(16, 32, 1, 1 shl 13, 10) + var key = ByteArray(32).apply { SecureRandom().nextBytes(this) } + val randomHash: String = argonEncoder.encode(String(key, StandardCharsets.UTF_8)) + } + + init { + LOG.info(String(key, StandardCharsets.UTF_8)) + LOG.info(randomHash) } } diff --git a/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/data/User.kt b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/data/User.kt index fe829d118..d7c6ce4ae 100644 --- a/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/data/User.kt +++ b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/data/User.kt @@ -20,8 +20,6 @@ package de.fhg.aisec.ids.webconsole.api.data class User { - @kotlin.jvm.JvmField var username: String? = null - @kotlin.jvm.JvmField var password: String? = null } From dafc465635fd41f01858314361536dfc928c30f9 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Wed, 19 May 2021 12:11:51 +0200 Subject: [PATCH 50/54] Reactivated examples project and removed old example ZIPs --- examples/trusted-connector-examples_1.0.zip | Bin 21958 -> 0 bytes examples/trusted-connector-examples_2.0.0.zip | Bin 32151 -> 0 bytes examples/trusted-connector-examples_3.0.0.zip | Bin 34539 -> 0 bytes examples/trusted-connector-examples_3.0.1.zip | Bin 34539 -> 0 bytes examples/trusted-connector-examples_3.0.2.zip | Bin 34291 -> 0 bytes examples/trusted-connector-examples_4.0.0.zip | Bin 34453 -> 0 bytes examples/trusted-connector-examples_develop.zip | Bin 55348 -> 0 bytes examples/trusted-connector-examples_latest.zip | Bin 34287 -> 0 bytes settings.gradle.kts | 1 + 9 files changed, 1 insertion(+) delete mode 100644 examples/trusted-connector-examples_1.0.zip delete mode 100644 examples/trusted-connector-examples_2.0.0.zip delete mode 100644 examples/trusted-connector-examples_3.0.0.zip delete mode 100644 examples/trusted-connector-examples_3.0.1.zip delete mode 100644 examples/trusted-connector-examples_3.0.2.zip delete mode 100644 examples/trusted-connector-examples_4.0.0.zip delete mode 100644 examples/trusted-connector-examples_develop.zip delete mode 100644 examples/trusted-connector-examples_latest.zip diff --git a/examples/trusted-connector-examples_1.0.zip b/examples/trusted-connector-examples_1.0.zip deleted file mode 100644 index aab5f7ba104dbbd7253515545ccf4c50fc2201c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21958 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 diff --git a/examples/trusted-connector-examples_2.0.0.zip b/examples/trusted-connector-examples_2.0.0.zip deleted file mode 100644 index 2b10d58b947bada8707e7772a76e655c642ca0e4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32151 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 CRfYrr diff --git a/examples/trusted-connector-examples_3.0.0.zip b/examples/trusted-connector-examples_3.0.0.zip deleted file mode 100644 index 210ecc4e6e24095117420fb78292ef98d54a20f8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 34539 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 i^*4jq5k}sx+6|T%vdw$ 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 diff --git a/examples/trusted-connector-examples_develop.zip b/examples/trusted-connector-examples_develop.zip deleted file mode 100644 index 4a1a8aaf424f6ce3155bf464b13e5ea5ce467d26..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 55348 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 diff --git a/examples/trusted-connector-examples_latest.zip b/examples/trusted-connector-examples_latest.zip deleted file mode 100644 index 55b18a4353b6d41ec30f3fbad82e7cd7df0a2cb9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 34287 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 P48@iMiSwP^ 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 diff --git a/settings.gradle.kts b/settings.gradle.kts index 4b872887d..d674a655f 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -2,6 +2,7 @@ rootProject.name = "trusted-connector-core" include(":camel-influxdb") include(":camel-multipart-processor") +include(":examples") include(":ids-acme") include(":ids-api") include(":ids-container-manager") From 12a983c15761cecff31de1b92d34c8c27c5954ca Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Wed, 19 May 2021 14:36:36 +0200 Subject: [PATCH 51/54] Reduced log verbosity --- ids-connector/src/main/resources/application.yml | 2 +- .../main/kotlin/de/fhg/aisec/ids/webconsole/api/UserApi.kt | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/ids-connector/src/main/resources/application.yml b/ids-connector/src/main/resources/application.yml index bd3267f4f..5e2db051e 100644 --- a/ids-connector/src/main/resources/application.yml +++ b/ids-connector/src/main/resources/application.yml @@ -1,7 +1,7 @@ logging: level: ROOT: INFO - de.fhg.aisec: TRACE + de.fhg.aisec: DEBUG spring: resources: diff --git a/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/UserApi.kt b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/UserApi.kt index 0049100c1..091a44276 100644 --- a/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/UserApi.kt +++ b/ids-webconsole/src/main/kotlin/de/fhg/aisec/ids/webconsole/api/UserApi.kt @@ -132,9 +132,4 @@ class UserApi(@Autowired private val settings: Settings) { var key = ByteArray(32).apply { SecureRandom().nextBytes(this) } val randomHash: String = argonEncoder.encode(String(key, StandardCharsets.UTF_8)) } - - init { - LOG.info(String(key, StandardCharsets.UTF_8)) - LOG.info(randomHash) - } } From fb452fdbb6c27b65c6713655a51fffc2184bbd89 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Wed, 19 May 2021 14:38:30 +0200 Subject: [PATCH 52/54] Fixed usage control --- .../aisec/ids/Idscp2UsageControlComponent.kt | 39 +++++++++++++++++++ .../dataflowcontrol/PolicyDecisionPoint.kt | 29 +++++++------- .../de/fhg/aisec/ids/rm/XmlDeployWatcher.kt | 15 +++++-- 3 files changed, 64 insertions(+), 19 deletions(-) create mode 100644 ids-connector/src/main/kotlin/de/fhg/aisec/ids/Idscp2UsageControlComponent.kt diff --git a/ids-connector/src/main/kotlin/de/fhg/aisec/ids/Idscp2UsageControlComponent.kt b/ids-connector/src/main/kotlin/de/fhg/aisec/ids/Idscp2UsageControlComponent.kt new file mode 100644 index 000000000..b6cb7204f --- /dev/null +++ b/ids-connector/src/main/kotlin/de/fhg/aisec/ids/Idscp2UsageControlComponent.kt @@ -0,0 +1,39 @@ +/*- + * ========================LICENSE_START================================= + * ids-connector + * %% + * Copyright (C) 2021 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids + +import de.fhg.aisec.ids.api.idscp2.Idscp2UsageControlInterface +import de.fhg.aisec.ids.camel.idscp2.UsageControlMaps +import org.apache.camel.Exchange +import org.springframework.stereotype.Component +import java.net.URI + +@Component +class Idscp2UsageControlComponent : Idscp2UsageControlInterface { + override fun getExchangeContract(exchange: Exchange) = + UsageControlMaps.getExchangeContract(exchange) + + override fun isProtected(exchange: Exchange) = UsageControlMaps.isProtected(exchange) + + override fun protectBody(exchange: Exchange, contractUri: URI) = + UsageControlMaps.protectBody(exchange, contractUri) + + override fun unprotectBody(exchange: Exchange) = UsageControlMaps.unprotectBody(exchange) +} diff --git a/ids-dataflow-control/src/main/kotlin/de/fhg/aisec/ids/dataflowcontrol/PolicyDecisionPoint.kt b/ids-dataflow-control/src/main/kotlin/de/fhg/aisec/ids/dataflowcontrol/PolicyDecisionPoint.kt index 2c9c9050c..de55977ff 100644 --- a/ids-dataflow-control/src/main/kotlin/de/fhg/aisec/ids/dataflowcontrol/PolicyDecisionPoint.kt +++ b/ids-dataflow-control/src/main/kotlin/de/fhg/aisec/ids/dataflowcontrol/PolicyDecisionPoint.kt @@ -42,7 +42,8 @@ import de.fhg.aisec.ids.dataflowcontrol.lucon.TuPrologHelper.listStream import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Component -import java.io.File +import java.nio.file.FileSystems +import java.nio.file.Files import java.util.LinkedList import java.util.concurrent.ExecutionException import java.util.concurrent.TimeUnit @@ -141,29 +142,25 @@ class PolicyDecisionPoint : PDP, PAP { @PostConstruct fun loadPolicies() { - // Try to load existing policies from deploy dir at activation - // val dir = File(System.getProperty("karaf.base") + File.separator + "deploy") - val url = Thread.currentThread().contextClassLoader.getResource("deploy") ?: return - val file = File(url.path) - - val directoryListing = file.listFiles() - if (directoryListing == null || !file.isDirectory) { - LOG.warn("Unexpected or not running in karaf: Not a directory: " + file.absolutePath) + // Try to load existing policies from deploy folder at activation + val fs = FileSystems.getDefault() + val deployPath = fs.getPath("deploy") + if (Files.notExists(deployPath)) { + LOG.info("No deploy folder found, skipping start of XML deploy watcher.") return } - var loaded = false - for (f in directoryListing) { - if (f.name.endsWith(LUCON_FILE_EXTENSION)) { + Files.walk(deployPath) + .filter { Files.isRegularFile(it) && it.toString().endsWith(LUCON_FILE_EXTENSION) } + .forEach { if (!loaded) { - LOG.info("Loading Lucon policy from " + f.absolutePath) - loadPolicy(f.readText()) + LOG.info("Loading Lucon policy from $it") + loadPolicy(Files.readString(it)) loaded = true } else { - LOG.warn("Multiple policy files. Will load only one! " + f.absolutePath) + LOG.warn("Multiple policy files. Will load only one!") } } - } } override fun requestTranformations(lastServiceNode: ServiceNode): TransformationDecision { diff --git a/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/XmlDeployWatcher.kt b/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/XmlDeployWatcher.kt index 4553cfc44..b5ae3a82b 100644 --- a/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/XmlDeployWatcher.kt +++ b/ids-route-manager/src/main/kotlin/de/fhg/aisec/ids/rm/XmlDeployWatcher.kt @@ -22,6 +22,8 @@ package de.fhg.aisec.ids.rm import org.slf4j.Logger import org.slf4j.LoggerFactory import org.springframework.boot.context.event.ApplicationReadyEvent +import org.springframework.context.ApplicationContext +import org.springframework.context.ApplicationContextAware import org.springframework.context.event.EventListener import org.springframework.context.support.AbstractXmlApplicationContext import org.springframework.context.support.FileSystemXmlApplicationContext @@ -34,13 +36,20 @@ import java.nio.file.WatchKey import java.util.concurrent.CompletableFuture @Component("xmlDeployWatcher") -class XmlDeployWatcher { +class XmlDeployWatcher : ApplicationContextAware { + + private lateinit var applicationContext: ApplicationContext + + override fun setApplicationContext(applicationContext: ApplicationContext) { + this.applicationContext = applicationContext + } + private val xmlContexts = mutableMapOf>() private fun startXmlApplicationContext(xmlPath: String) { LOG.info("XML file {} detected, creating XmlApplicationContext...", xmlPath) val xmlContextFuture: CompletableFuture = CompletableFuture.supplyAsync { - FileSystemXmlApplicationContext(xmlPath) + FileSystemXmlApplicationContext(arrayOf(xmlPath), applicationContext) } xmlContexts += xmlPath to xmlContextFuture } @@ -59,7 +68,7 @@ class XmlDeployWatcher { ctxFuture.thenAccept { ctx -> ctx.stop() val xmlContextFuture: CompletableFuture = CompletableFuture.supplyAsync { - FileSystemXmlApplicationContext(xmlPath) + FileSystemXmlApplicationContext(arrayOf(xmlPath), applicationContext) } xmlContexts += xmlPath to xmlContextFuture } From 87fa9e49bb6b7ca0ec3eda8a8145fe83c4752830 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Wed, 19 May 2021 14:38:57 +0200 Subject: [PATCH 53/54] Example fixes and cleanup --- examples/build.gradle.kts | 3 +- examples/deploy/allow-all-flows.pl | 45 ++++++++++++++++++ .../consumer-keystore.p12 | Bin .../provider-keystore.p12 | Bin examples/etc/settings2.mapdb | Bin 0 -> 2097152 bytes examples/{cert-stores => etc}/truststore.p12 | Bin .../docker-compose.yaml | 8 ++-- .../docker-compose-client.yaml | 7 +-- .../docker-compose-server.yaml | 7 +-- .../docker-compose-broadcast-client.yaml | 7 +-- .../docker-compose-broadcast-server.yaml | 7 +-- .../example-idscp2/docker-compose-client.yaml | 7 +-- .../example-idscp2/docker-compose-server.yaml | 7 +-- 13 files changed, 74 insertions(+), 24 deletions(-) create mode 100644 examples/deploy/allow-all-flows.pl rename examples/{cert-stores => etc}/consumer-keystore.p12 (100%) rename examples/{cert-stores => etc}/provider-keystore.p12 (100%) create mode 100644 examples/etc/settings2.mapdb rename examples/{cert-stores => etc}/truststore.p12 (100%) diff --git a/examples/build.gradle.kts b/examples/build.gradle.kts index 99a9efb2f..f8ef1eafd 100644 --- a/examples/build.gradle.kts +++ b/examples/build.gradle.kts @@ -7,8 +7,7 @@ val copyExample = tasks.create("copyExample") { delete(project.buildDir) } from(project.projectDir) { - include("example-*/**", "tpmsim/tpmsim_data.tar", "tpmsim/rootCA.crt", "cert-stores/*") - exclude("example-idscp/example-client", "example-idscp/example-server") + include("example-*/**", "deploy/*", "etc/*") } into(project.buildDir) } diff --git a/examples/deploy/allow-all-flows.pl b/examples/deploy/allow-all-flows.pl new file mode 100644 index 000000000..5d94233a6 --- /dev/null +++ b/examples/deploy/allow-all-flows.pl @@ -0,0 +1,45 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Prolog representation of a data flow policy +% +% Source: default +% +% Do not edit this file, it has been generated automatically +% by XText/Xtend. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% Only required for SWI-Prolog +% Allow the following predicates to be scattered around the prolog file. +% Otherwise Prolog will issue a warning if they are not stated in subsequent lines. +%:- discontiguous service/1. +%:- discontiguous has_endpoint/2. +%:- discontiguous creates_label/2. +%:- discontiguous removes_label/2. +%:- discontiguous rule/1. +%:- discontiguous rule_priority/2. +%:- discontiguous receives_label/1. +%:- discontiguous has_decision/2. +%:- discontiguous has_target/2. +%:- discontiguous has_capability/2. +%:- discontiguous has_property/3. +%:- discontiguous requires_prerequisites/2. +%:- discontiguous has_alternativedecision/2. +%:- discontiguous has_obligation/2. + +%%%%%%%%% Basic Blocking Rule %%%%%%%%%% +rule(dropAll). +rule_priority(dropAll,0). +has_decision(dropAll,drop). +receives_label(dropAll). +has_target(dropAll,serviceAll). + +%%%%%%%%%% Catch All Service %%%%%%%%%%% +service(serviceAll). +has_endpoint(serviceAll,'.*'). + +%%%%%%%%%%%%%%%% Rules %%%%%%%%%%%%%%%%% +% Allow everything +rule(allowAll). +rule_priority(allowAll, 1). +has_target(allowAll, serviceAll). +receives_label(allowAll). +has_decision(allowAll, allow). \ No newline at end of file diff --git a/examples/cert-stores/consumer-keystore.p12 b/examples/etc/consumer-keystore.p12 similarity index 100% rename from examples/cert-stores/consumer-keystore.p12 rename to examples/etc/consumer-keystore.p12 diff --git a/examples/cert-stores/provider-keystore.p12 b/examples/etc/provider-keystore.p12 similarity index 100% rename from examples/cert-stores/provider-keystore.p12 rename to examples/etc/provider-keystore.p12 diff --git a/examples/etc/settings2.mapdb b/examples/etc/settings2.mapdb new file mode 100644 index 0000000000000000000000000000000000000000..8f917658d00d1fe438e29c26f12cec9cde499d40 GIT binary patch literal 2097152 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 z7PTfu!v*)q`u_NS@}qlXJhu;He|#t3 z{$ID3*d{=L009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly ZK!5-N0t5&UAV7cs0RjXF5coe3_#fb$(>MSC literal 0 HcmV?d00001 diff --git a/examples/cert-stores/truststore.p12 b/examples/etc/truststore.p12 similarity index 100% rename from examples/cert-stores/truststore.p12 rename to examples/etc/truststore.p12 diff --git a/examples/example-getting-started/docker-compose.yaml b/examples/example-getting-started/docker-compose.yaml index 74c99da8c..548c0d5ee 100644 --- a/examples/example-getting-started/docker-compose.yaml +++ b/examples/example-getting-started/docker-compose.yaml @@ -7,12 +7,12 @@ services: tty: true stdin_open: true volumes: - - ../log/:/root/log/ - /var/run/docker.sock:/var/run/docker.sock + - ../deploy/allow-all-flows.pl:/root/deploy/allow-all-flows.pl - ../etc/settings.mapdb:/root/etc/settings.mapdb - - ../cert-stores/consumer-keystore.p12:/root/etc/consumer-keystore.p12 - - ../cert-stores/provider-keystore.p12:/root/etc/provider-keystore.p12 - - ../cert-stores/truststore.p12:/root/etc/truststore.p12 + - ../etc/consumer-keystore.p12:/root/etc/consumer-keystore.p12 + - ../etc/provider-keystore.p12:/root/etc/provider-keystore.p12 + - ../etc/truststore.p12:/root/etc/truststore.p12 - ./example-idscp2-localloop.xml:/root/deploy/example-idscp2-localloop.xml ports: - "8080:8080" diff --git a/examples/example-idscp2-uc/docker-compose-client.yaml b/examples/example-idscp2-uc/docker-compose-client.yaml index 55f60e83f..d53db169a 100644 --- a/examples/example-idscp2-uc/docker-compose-client.yaml +++ b/examples/example-idscp2-uc/docker-compose-client.yaml @@ -7,10 +7,11 @@ services: tty: true stdin_open: true volumes: - - ../log/:/root/log/ - /var/run/docker.sock:/var/run/docker.sock - - ../cert-stores/provider-keystore.p12:/root/etc/provider-keystore.p12 - - ../cert-stores/truststore.p12:/root/etc/truststore.p12 + - ../deploy/allow-all-flows.pl:/root/deploy/allow-all-flows.pl + - ../etc/settings2.mapdb:/root/etc/settings.mapdb + - ../etc/consumer-keystore.p12:/root/etc/consumer-keystore.p12 + - ../etc/truststore.p12:/root/etc/truststore.p12 - ./example-idscp2-client.xml:/root/deploy/example-idscp2-client.xml # Enable this port mappings for debugging or UI access from localhost # ports: diff --git a/examples/example-idscp2-uc/docker-compose-server.yaml b/examples/example-idscp2-uc/docker-compose-server.yaml index 024c3546f..b7306a899 100644 --- a/examples/example-idscp2-uc/docker-compose-server.yaml +++ b/examples/example-idscp2-uc/docker-compose-server.yaml @@ -7,10 +7,11 @@ services: tty: true stdin_open: true volumes: - - ../log/:/root/log/ - /var/run/docker.sock:/var/run/docker.sock - - ../cert-stores/consumer-keystore.p12:/root/etc/consumer-keystore.p12 - - ../cert-stores/truststore.p12:/root/etc/truststore.p12 + - ../deploy/allow-all-flows.pl:/root/deploy/allow-all-flows.pl + - ../etc/settings.mapdb:/root/etc/settings.mapdb + - ../etc/provider-keystore.p12:/root/etc/provider-keystore.p12 + - ../etc/truststore.p12:/root/etc/truststore.p12 - ./example-idscp2-server.xml:/root/deploy/example-idscp2-server.xml # Enable this port mappings for debugging or UI access from localhost # ports: diff --git a/examples/example-idscp2/docker-compose-broadcast-client.yaml b/examples/example-idscp2/docker-compose-broadcast-client.yaml index 8a0ed97aa..df13218ec 100644 --- a/examples/example-idscp2/docker-compose-broadcast-client.yaml +++ b/examples/example-idscp2/docker-compose-broadcast-client.yaml @@ -7,10 +7,11 @@ services: tty: true stdin_open: true volumes: - - ../log/:/root/log/ - /var/run/docker.sock:/var/run/docker.sock - - ../cert-stores/consumer-keystore.p12:/root/etc/consumer-keystore.p12 - - ../cert-stores/truststore.p12:/root/etc/truststore.p12 + - ../deploy/allow-all-flows.pl:/root/deploy/allow-all-flows.pl + - ../etc/settings2.mapdb:/root/etc/settings.mapdb + - ../etc/consumer-keystore.p12:/root/etc/consumer-keystore.p12 + - ../etc/truststore.p12:/root/etc/truststore.p12 - ./example-idscp2-client-broadcast.xml:/root/deploy/example-idscp2-client.xml # Enable this port mappings for debugging or UI access from localhost # ports: diff --git a/examples/example-idscp2/docker-compose-broadcast-server.yaml b/examples/example-idscp2/docker-compose-broadcast-server.yaml index 77a29a9fb..e40271bd8 100644 --- a/examples/example-idscp2/docker-compose-broadcast-server.yaml +++ b/examples/example-idscp2/docker-compose-broadcast-server.yaml @@ -7,10 +7,11 @@ services: tty: true stdin_open: true volumes: - - ../log/:/root/log/ - /var/run/docker.sock:/var/run/docker.sock - - ../cert-stores/provider-keystore.p12:/root/etc/provider-keystore.p12 - - ../cert-stores/truststore.p12:/root/etc/truststore.p12 + - ../deploy/allow-all-flows.pl:/root/deploy/allow-all-flows.pl + - ../etc/settings.mapdb:/root/etc/settings.mapdb + - ../etc/provider-keystore.p12:/root/etc/provider-keystore.p12 + - ../etc/truststore.p12:/root/etc/truststore.p12 - ./example-idscp2-server-broadcast.xml:/root/deploy/example-idscp2-server.xml # Enable this port mappings for debugging or UI access from localhost # ports: diff --git a/examples/example-idscp2/docker-compose-client.yaml b/examples/example-idscp2/docker-compose-client.yaml index fe1124ffd..ba8d9bd3e 100644 --- a/examples/example-idscp2/docker-compose-client.yaml +++ b/examples/example-idscp2/docker-compose-client.yaml @@ -7,10 +7,11 @@ services: tty: true stdin_open: true volumes: - - ../log/:/root/log/ - /var/run/docker.sock:/var/run/docker.sock - - ../cert-stores/provider-keystore.p12:/root/etc/provider-keystore.p12 - - ../cert-stores/truststore.p12:/root/etc/truststore.p12 + - ../deploy/allow-all-flows.pl:/root/deploy/allow-all-flows.pl + - ../etc/settings2.mapdb:/root/etc/settings.mapdb + - ../etc/provider-keystore.p12:/root/etc/provider-keystore.p12 + - ../etc/truststore.p12:/root/etc/truststore.p12 - ./example-idscp2-client.xml:/root/deploy/example-idscp2-client.xml # Enable this port mappings for debugging or UI access from localhost # ports: diff --git a/examples/example-idscp2/docker-compose-server.yaml b/examples/example-idscp2/docker-compose-server.yaml index 8d5ea6152..e21abf293 100644 --- a/examples/example-idscp2/docker-compose-server.yaml +++ b/examples/example-idscp2/docker-compose-server.yaml @@ -7,10 +7,11 @@ services: tty: true stdin_open: true volumes: - - ../log/:/root/log/ - /var/run/docker.sock:/var/run/docker.sock - - ../cert-stores/consumer-keystore.p12:/root/etc/consumer-keystore.p12 - - ../cert-stores/truststore.p12:/root/etc/truststore.p12 + - ../deploy/allow-all-flows.pl:/root/deploy/allow-all-flows.pl + - ../etc/settings.mapdb:/root/etc/settings.mapdb + - ../etc/consumer-keystore.p12:/root/etc/consumer-keystore.p12 + - ../etc/truststore.p12:/root/etc/truststore.p12 - ./example-idscp2-server.xml:/root/deploy/example-idscp2-server.xml # Enable this port mappings for debugging or UI access from localhost # ports: From 919073e49ebe0d9325d24043298f864aa9356463 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Wed, 19 May 2021 14:51:30 +0200 Subject: [PATCH 54/54] Added examples ZIP --- examples/trusted-connector-examples_5.0.0.zip | Bin 0 -> 32111 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 examples/trusted-connector-examples_5.0.0.zip diff --git a/examples/trusted-connector-examples_5.0.0.zip b/examples/trusted-connector-examples_5.0.0.zip new file mode 100644 index 0000000000000000000000000000000000000000..f3dfe8147b809a7b650ee3bf69d2abd7ec1c292f GIT binary patch literal 32111 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