From d65ca1b010e4595fae83214a363543e9dd2509f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=20S=C3=B5mermaa?= Date: Tue, 22 Dec 2020 00:40:54 +0200 Subject: [PATCH 001/116] Add license --- example/LICENSE | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 example/LICENSE diff --git a/example/LICENSE b/example/LICENSE new file mode 100644 index 0000000..0b8eeef --- /dev/null +++ b/example/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 The Web eID Project + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From f02ef492e942fdcc60b795a1c16b0e7a8b80173f Mon Sep 17 00:00:00 2001 From: Mart Somermaa Date: Tue, 22 Dec 2020 01:06:02 +0200 Subject: [PATCH 002/116] Initial commit Signed-off-by: Mart Somermaa --- example/.gitattributes | 19 + example/.gitignore | 34 + .../.mvn/wrapper/MavenWrapperDownloader.java | 121 +++ example/.mvn/wrapper/maven-wrapper.jar | Bin 0 -> 50710 bytes example/.mvn/wrapper/maven-wrapper.properties | 2 + example/.prettierrc.yaml | 7 + example/README.md | 106 +++ example/docker-compose.yml | 7 + example/mvnw | 310 +++++++ example/mvnw.cmd | 182 ++++ example/pom.xml | 143 ++++ .../WebEidSpringbootExampleApplication.java | 34 + .../config/ApplicationConfiguration.java | 81 ++ .../config/ValidationConfiguration.java | 143 ++++ .../org/webeid/example/config/YAMLConfig.java | 70 ++ .../AuthTokenDTOAuthenticationProvider.java | 94 +++ .../WebEidAjaxLoginProcessingFilter.java | 76 ++ .../AjaxAuthenticationFailureHandler.java | 55 ++ .../AjaxAuthenticationSuccessHandler.java | 86 ++ .../example/security/dto/AuthTokenDTO.java | 38 + .../example/service/SigningService.java | 176 ++++ .../example/service/dto/CertificateDTO.java | 75 ++ .../example/service/dto/ChallengeDTO.java | 35 + .../webeid/example/service/dto/DigestDTO.java | 44 + .../webeid/example/service/dto/FileDTO.java | 67 ++ .../service/dto/SignatureAlgorithmDTO.java | 61 ++ .../example/service/dto/SignatureDTO.java | 57 ++ .../webeid/example/web/WelcomeController.java | 47 ++ .../example/web/rest/ChallengeController.java | 49 ++ .../example/web/rest/SigningController.java | 75 ++ .../src/main/resources/application.properties | 1 + example/src/main/resources/application.yaml | 11 + .../main/resources/certs/ESTEID-SK_2015.cer | Bin 0 -> 1652 bytes .../src/main/resources/certs/ESTEID2018.cer | Bin 0 -> 1371 bytes .../certs/TEST_of_ESTEID-SK_2015.cer | Bin 0 -> 1671 bytes .../resources/certs/TEST_of_ESTEID2018.cer | Bin 0 -> 1408 bytes .../resources/certs/trusted_certificates.jks | Bin 0 -> 1345 bytes .../src/main/resources/static/css/main.css | 69 ++ .../firefox-web-eid-extension-updates.json | 12 + .../firefox/web-eid-webextension-0.9.1.xpi | Bin 0 -> 78545 bytes .../firefox/web-eid-webextension-latest.xpi | Bin 0 -> 78545 bytes .../resources/static/img/eu-fund-flags.svg | 787 ++++++++++++++++++ example/src/main/resources/static/index.html | 150 ++++ .../main/resources/static/js/error-message.js | 45 + .../main/resources/static/js/web-eid-0.9.0.js | 521 ++++++++++++ .../src/main/resources/templates/welcome.html | 143 ++++ .../AuthenticationRestControllerTest.java | 57 ++ .../webeid/example/WebApplicationTest.java | 109 +++ .../org/webeid/example/testutil/Dates.java | 48 ++ .../webeid/example/testutil/FakeNonce.java | 36 + .../webeid/example/testutil/HttpHelper.java | 101 +++ .../webeid/example/testutil/ObjectMother.java | 141 ++++ .../org/webeid/example/testutil/Tokens.java | 29 + example/src/test/resources/signout.p12 | Bin 0 -> 3061 bytes 54 files changed, 4554 insertions(+) create mode 100644 example/.gitattributes create mode 100644 example/.gitignore create mode 100644 example/.mvn/wrapper/MavenWrapperDownloader.java create mode 100644 example/.mvn/wrapper/maven-wrapper.jar create mode 100644 example/.mvn/wrapper/maven-wrapper.properties create mode 100644 example/.prettierrc.yaml create mode 100644 example/README.md create mode 100644 example/docker-compose.yml create mode 100644 example/mvnw create mode 100644 example/mvnw.cmd create mode 100644 example/pom.xml create mode 100644 example/src/main/java/org/webeid/example/WebEidSpringbootExampleApplication.java create mode 100644 example/src/main/java/org/webeid/example/config/ApplicationConfiguration.java create mode 100644 example/src/main/java/org/webeid/example/config/ValidationConfiguration.java create mode 100644 example/src/main/java/org/webeid/example/config/YAMLConfig.java create mode 100644 example/src/main/java/org/webeid/example/security/AuthTokenDTOAuthenticationProvider.java create mode 100644 example/src/main/java/org/webeid/example/security/WebEidAjaxLoginProcessingFilter.java create mode 100644 example/src/main/java/org/webeid/example/security/ajax/AjaxAuthenticationFailureHandler.java create mode 100644 example/src/main/java/org/webeid/example/security/ajax/AjaxAuthenticationSuccessHandler.java create mode 100644 example/src/main/java/org/webeid/example/security/dto/AuthTokenDTO.java create mode 100644 example/src/main/java/org/webeid/example/service/SigningService.java create mode 100644 example/src/main/java/org/webeid/example/service/dto/CertificateDTO.java create mode 100644 example/src/main/java/org/webeid/example/service/dto/ChallengeDTO.java create mode 100644 example/src/main/java/org/webeid/example/service/dto/DigestDTO.java create mode 100644 example/src/main/java/org/webeid/example/service/dto/FileDTO.java create mode 100644 example/src/main/java/org/webeid/example/service/dto/SignatureAlgorithmDTO.java create mode 100644 example/src/main/java/org/webeid/example/service/dto/SignatureDTO.java create mode 100644 example/src/main/java/org/webeid/example/web/WelcomeController.java create mode 100644 example/src/main/java/org/webeid/example/web/rest/ChallengeController.java create mode 100644 example/src/main/java/org/webeid/example/web/rest/SigningController.java create mode 100644 example/src/main/resources/application.properties create mode 100644 example/src/main/resources/application.yaml create mode 100644 example/src/main/resources/certs/ESTEID-SK_2015.cer create mode 100644 example/src/main/resources/certs/ESTEID2018.cer create mode 100644 example/src/main/resources/certs/TEST_of_ESTEID-SK_2015.cer create mode 100644 example/src/main/resources/certs/TEST_of_ESTEID2018.cer create mode 100644 example/src/main/resources/certs/trusted_certificates.jks create mode 100644 example/src/main/resources/static/css/main.css create mode 100644 example/src/main/resources/static/files/firefox/firefox-web-eid-extension-updates.json create mode 100644 example/src/main/resources/static/files/firefox/web-eid-webextension-0.9.1.xpi create mode 100644 example/src/main/resources/static/files/firefox/web-eid-webextension-latest.xpi create mode 100644 example/src/main/resources/static/img/eu-fund-flags.svg create mode 100644 example/src/main/resources/static/index.html create mode 100644 example/src/main/resources/static/js/error-message.js create mode 100644 example/src/main/resources/static/js/web-eid-0.9.0.js create mode 100644 example/src/main/resources/templates/welcome.html create mode 100644 example/src/test/java/org/webeid/example/AuthenticationRestControllerTest.java create mode 100644 example/src/test/java/org/webeid/example/WebApplicationTest.java create mode 100644 example/src/test/java/org/webeid/example/testutil/Dates.java create mode 100644 example/src/test/java/org/webeid/example/testutil/FakeNonce.java create mode 100644 example/src/test/java/org/webeid/example/testutil/HttpHelper.java create mode 100644 example/src/test/java/org/webeid/example/testutil/ObjectMother.java create mode 100644 example/src/test/java/org/webeid/example/testutil/Tokens.java create mode 100644 example/src/test/resources/signout.p12 diff --git a/example/.gitattributes b/example/.gitattributes new file mode 100644 index 0000000..9115584 --- /dev/null +++ b/example/.gitattributes @@ -0,0 +1,19 @@ +* text=auto +*.java text eol=lf +*.xml text eol=lf +*.pl text eol=lf +*.py text eol=lf +*.html text eol=lf +*.scss text eol=lf +*.css text eol=lf +*.js text eol=lf +*.bat text eol=crlf +*.cmd text eol=crlf +MANIFEST.MF text eol=lf +commit-msg text eol=lf +.gitattributes text eol=lf +.gitignore text eol=lf +*.deb filter=lfs diff=lfs merge=lfs -text +*.pkg filter=lfs diff=lfs merge=lfs -text +*.msi filter=lfs diff=lfs merge=lfs -text +*.zip filter=lfs diff=lfs merge=lfs -text diff --git a/example/.gitignore b/example/.gitignore new file mode 100644 index 0000000..535d7b5 --- /dev/null +++ b/example/.gitignore @@ -0,0 +1,34 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/** +!**/src/test/** + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ + +### VS Code ### +.vscode/ + +### Vim ### +*.swp diff --git a/example/.mvn/wrapper/MavenWrapperDownloader.java b/example/.mvn/wrapper/MavenWrapperDownloader.java new file mode 100644 index 0000000..bb16fac --- /dev/null +++ b/example/.mvn/wrapper/MavenWrapperDownloader.java @@ -0,0 +1,121 @@ +/* + * 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 + * + * https://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.io.*; +import java.net.*; +import java.nio.channels.*; +import java.util.Properties; + +public class MavenWrapperDownloader { + private static final String WRAPPER_VERSION = "0.5.6"; + /** + * 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/example/.mvn/wrapper/maven-wrapper.jar b/example/.mvn/wrapper/maven-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..2cc7d4a55c0cd0092912bf49ae38b3a9e3fd0054 GIT binary patch literal 50710 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 EfAhh=DF6Tf literal 0 HcmV?d00001 diff --git a/example/.mvn/wrapper/maven-wrapper.properties b/example/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000..642d572 --- /dev/null +++ b/example/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,2 @@ +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip +wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar diff --git a/example/.prettierrc.yaml b/example/.prettierrc.yaml new file mode 100644 index 0000000..04450cb --- /dev/null +++ b/example/.prettierrc.yaml @@ -0,0 +1,7 @@ +trailingComma: "none" +useTabs: false +tabWidth: 4 +semi: true +singleQuote: false +printWidth: 120 + diff --git a/example/README.md b/example/README.md new file mode 100644 index 0000000..dcd160a --- /dev/null +++ b/example/README.md @@ -0,0 +1,106 @@ +# Web eID Spring Boot example + +![European Regional Development Fund](https://github.com/e-gov/RIHA-Frontend/raw/master/logo/EU/EU.png) + +Example Spring Boot web application that uses Web eID for strong authentication +and digital signing with electronic ID smart cards. + +## Setup + +Note that although the browser considers localhost to be a secure context, it does not have a certificate, +therefore you need to use e.g. Ngrok.io for local testing. + +Download ngrok and run locally using two parameters: +```sh +ngrok http 8080 +``` + +## Configuration + +Open application.yaml file and set up the `local-origin` and `fingerprint` fields: + +- The `local-origin` field must contain the url, which was generated by ngrok. +- The `fingerprint` field must contain the SHA256 fingerprint of the certificate, which you can retrieve from the browser by navigating to the ngrok url and exploring the server certificate details. Here is a [quick guide](https://www.globalsign.com/en/blog/how-to-view-ssl-certificate-details) and for different browsers. + +```yaml +spring: + profiles: dev + servlet: + multipart: + max-file-size: 5000KB + max-request-size: 5000KB +token: + validation: + local-origin: "https://ade0973a6557.ngrok.io" + fingerprint: "11:D8:AE:60:EC:19:10:C7:94:D7:4C:82:C8:0D:96:B2:07:88:B5:6A:D2:65:FF:F9:B5:14:C8:75:F7:90:08:E1" + keystore-password: "changeit" +``` + +Additionally, you can set up the keystore password, and the maximum size of the files to be uploaded. + +## Running + +Once the `local-origin` and `fingerprint` fields are set, you can run the application with the following command: +```sh +./mvnw spring-boot:run +``` +and then navigate the browser to the url, that was generated by ngrok. + + +## Testing + +In case you don't have the Web eID extension installed or want to test `web-eid.js` message handling manually, +you can use the browser developer tools to mock the authentication response from the extension with +`window.postMessage()` as follows: + +1. Click *Authenticate* +2. Paste the following snippet into developer tools console: + +```js +var loginResponse = await fetch("/auth/login", { + method: "POST", + headers: { + 'Content-Type': 'application/json' + }, + body: '{"auth-token":"eyJhbGciOiJFUzM4NCIsInR5cCI6IkpXVCIsIng1YyI6WyJNSUlFQXpDQ0EyV2dBd0lCQWdJUU9Xa0JXWE5ESm0xYnlGZDNYc1drdmpBS0JnZ3Foa2pPUFFRREJEQmdNUXN3Q1FZRFZRUUdFd0pGUlRFYk1Ca0dBMVVFQ2d3U1Uwc2dTVVFnVTI5c2RYUnBiMjV6SUVGVE1SY3dGUVlEVlFSaERBNU9WRkpGUlMweE1EYzBOekF4TXpFYk1Ca0dBMVVFQXd3U1ZFVlRWQ0J2WmlCRlUxUkZTVVF5TURFNE1CNFhEVEU0TVRBeE9EQTVOVEEwTjFvWERUSXpNVEF4TnpJeE5UazFPVm93ZnpFTE1Ba0dBMVVFQmhNQ1JVVXhLakFvQmdOVkJBTU1JVXJEbFVWUFVrY3NTa0ZCU3kxTFVrbFRWRXBCVGl3ek9EQXdNVEE0TlRjeE9ERVFNQTRHQTFVRUJBd0hTc09WUlU5U1J6RVdNQlFHQTFVRUtnd05Ta0ZCU3kxTFVrbFRWRXBCVGpFYU1CZ0dBMVVFQlJNUlVFNVBSVVV0TXpnd01ERXdPRFUzTVRnd2RqQVFCZ2NxaGtqT1BRSUJCZ1VyZ1FRQUlnTmlBQVI1azFsWHp2U2VJOU8vMXMxcFp2amhFVzhuSXRKb0cwRUJGeG1MRVk2UzdraTF2RjJRM1RFRHg2ZE56dEkxWHR4OTZjczhyNHpZVHdkaVFvRGc3azNkaVV1UjluVFdHeFFFTU8xRkRvNFk5ZkFtaVBHV1QrK0d1T1ZvWlFZM1h4aWpnZ0hETUlJQnZ6QUpCZ05WSFJNRUFqQUFNQTRHQTFVZER3RUIvd1FFQXdJRGlEQkhCZ05WSFNBRVFEQStNRElHQ3lzR0FRUUJnNUVoQVFJQk1DTXdJUVlJS3dZQkJRVUhBZ0VXRldoMGRIQnpPaTh2ZDNkM0xuTnJMbVZsTDBOUVV6QUlCZ1lFQUk5NkFRSXdId1lEVlIwUkJCZ3dGb0VVTXpnd01ERXdPRFUzTVRoQVpXVnpkR2t1WldVd0hRWURWUjBPQkJZRUZPUXN2VFFKRUJWTU1TbWh5Wlg1YmliWUp1YkFNR0VHQ0NzR0FRVUZCd0VEQkZVd1V6QlJCZ1lFQUk1R0FRVXdSekJGRmo5b2RIUndjem92TDNOckxtVmxMMlZ1TDNKbGNHOXphWFJ2Y25rdlkyOXVaR2wwYVc5dWN5MW1iM0l0ZFhObExXOW1MV05sY25ScFptbGpZWFJsY3k4VEFrVk9NQ0FHQTFVZEpRRUIvd1FXTUJRR0NDc0dBUVVGQndNQ0JnZ3JCZ0VGQlFjREJEQWZCZ05WSFNNRUdEQVdnQlRBaEprcHhFNmZPd0kwOXBuaENsWUFDQ2srZXpCekJnZ3JCZ0VGQlFjQkFRUm5NR1V3TEFZSUt3WUJCUVVITUFHR0lHaDBkSEE2THk5aGFXRXVaR1Z0Ynk1emF5NWxaUzlsYzNSbGFXUXlNREU0TURVR0NDc0dBUVVGQnpBQ2hpbG9kSFJ3T2k4dll5NXpheTVsWlM5VVpYTjBYMjltWDBWVFZFVkpSREl3TVRndVpHVnlMbU55ZERBS0JnZ3Foa2pPUFFRREJBT0Jpd0F3Z1ljQ1FnSDFVc21NZHRMWnRpNTFGcTJRUjR3VWtBd3BzbmhzQlYySFFxVVhGWUJKN0VYbkxDa2FYamRaS2tIcEFCZk0wUUV4N1VVaGFJNGk1M2ppSjdFMVk3V09BQUpCRFg0ejYxcG5pSEphcEkxYmtNSWlKUS90aTdoYThmZEpTTVNwQWRzNUN5SEl5SGtReldsVnk4NmY5bUE3RXUzb1JPLzFxK2VGVXpEYk5OM1Z2eTdnUVdRPSJdfQ.eyJhdWQiOlsiaHR0cHM6Ly9yaWEuZWUiLCJ1cm46Y2VydDpzaGEtMjU2OjZmMGRmMjQ0ZTRhODU2Yjk0YjNiM2I0NzU4MmEwYTUxYTMyZDY3NGRiYzcxMDcyMTFlZDIzZDRiZWM2ZDljNzIiXSwiZXhwIjoiMTU4Njg3MTE2OSIsImlhdCI6IjE1ODY4NzA4NjkiLCJpc3MiOiJ3ZWItZWlkIGFwcCB2MC45LjAtMS1nZTZlODlmYSIsIm5vbmNlIjoiMTIzNDU2NzgxMjM0NTY3ODEyMzQ1Njc4MTIzNDU2NzgiLCJzdWIiOiJKw5VFT1JHLEpBQUstS1JJU1RKQU4sMzgwMDEwODU3MTgifQ.0Y5CdMiSZ14rOnd7sbp-XeBQ7qrJVd21yTmAbiRnzAXtwqW8ZROg4jL4J7bpQ2fwyUz4-dVwLoVRVnxfJY82b8NXuxXrDb-8MXXmVYrMW0q0kPbEzqFbEnPYHjNnKAN0"}' +}); + +window.postMessage({ + action: webeid.Action.AUTHENTICATE_SUCCESS, + response: { + status: 200, + headers: {}, + body: await loginResponse.json() + } +}); +``` + +## Testing with curl + +```shell script +$ curl 'http://localhost:8080/auth/login' -H 'Content-type: application/json' --data-raw '{"auth-token":"eyJhbGciOiJFUzM4NCIsInR5cCI6IkpXVCIsIng1YyI6WyJNSUlFQXpDQ0EyV2dBd0lCQWdJUU9Xa0JXWE5ESm0xYnlGZDNYc1drdmpBS0JnZ3Foa2pPUFFRREJEQmdNUXN3Q1FZRFZRUUdFd0pGUlRFYk1Ca0dBMVVFQ2d3U1Uwc2dTVVFnVTI5c2RYUnBiMjV6SUVGVE1SY3dGUVlEVlFSaERBNU9WRkpGUlMweE1EYzBOekF4TXpFYk1Ca0dBMVVFQXd3U1ZFVlRWQ0J2WmlCRlUxUkZTVVF5TURFNE1CNFhEVEU0TVRBeE9EQTVOVEEwTjFvWERUSXpNVEF4TnpJeE5UazFPVm93ZnpFTE1Ba0dBMVVFQmhNQ1JVVXhLakFvQmdOVkJBTU1JVXJEbFVWUFVrY3NTa0ZCU3kxTFVrbFRWRXBCVGl3ek9EQXdNVEE0TlRjeE9ERVFNQTRHQTFVRUJBd0hTc09WUlU5U1J6RVdNQlFHQTFVRUtnd05Ta0ZCU3kxTFVrbFRWRXBCVGpFYU1CZ0dBMVVFQlJNUlVFNVBSVVV0TXpnd01ERXdPRFUzTVRnd2RqQVFCZ2NxaGtqT1BRSUJCZ1VyZ1FRQUlnTmlBQVI1azFsWHp2U2VJOU8vMXMxcFp2amhFVzhuSXRKb0cwRUJGeG1MRVk2UzdraTF2RjJRM1RFRHg2ZE56dEkxWHR4OTZjczhyNHpZVHdkaVFvRGc3azNkaVV1UjluVFdHeFFFTU8xRkRvNFk5ZkFtaVBHV1QrK0d1T1ZvWlFZM1h4aWpnZ0hETUlJQnZ6QUpCZ05WSFJNRUFqQUFNQTRHQTFVZER3RUIvd1FFQXdJRGlEQkhCZ05WSFNBRVFEQStNRElHQ3lzR0FRUUJnNUVoQVFJQk1DTXdJUVlJS3dZQkJRVUhBZ0VXRldoMGRIQnpPaTh2ZDNkM0xuTnJMbVZsTDBOUVV6QUlCZ1lFQUk5NkFRSXdId1lEVlIwUkJCZ3dGb0VVTXpnd01ERXdPRFUzTVRoQVpXVnpkR2t1WldVd0hRWURWUjBPQkJZRUZPUXN2VFFKRUJWTU1TbWh5Wlg1YmliWUp1YkFNR0VHQ0NzR0FRVUZCd0VEQkZVd1V6QlJCZ1lFQUk1R0FRVXdSekJGRmo5b2RIUndjem92TDNOckxtVmxMMlZ1TDNKbGNHOXphWFJ2Y25rdlkyOXVaR2wwYVc5dWN5MW1iM0l0ZFhObExXOW1MV05sY25ScFptbGpZWFJsY3k4VEFrVk9NQ0FHQTFVZEpRRUIvd1FXTUJRR0NDc0dBUVVGQndNQ0JnZ3JCZ0VGQlFjREJEQWZCZ05WSFNNRUdEQVdnQlRBaEprcHhFNmZPd0kwOXBuaENsWUFDQ2srZXpCekJnZ3JCZ0VGQlFjQkFRUm5NR1V3TEFZSUt3WUJCUVVITUFHR0lHaDBkSEE2THk5aGFXRXVaR1Z0Ynk1emF5NWxaUzlsYzNSbGFXUXlNREU0TURVR0NDc0dBUVVGQnpBQ2hpbG9kSFJ3T2k4dll5NXpheTVsWlM5VVpYTjBYMjltWDBWVFZFVkpSREl3TVRndVpHVnlMbU55ZERBS0JnZ3Foa2pPUFFRREJBT0Jpd0F3Z1ljQ1FnSDFVc21NZHRMWnRpNTFGcTJRUjR3VWtBd3BzbmhzQlYySFFxVVhGWUJKN0VYbkxDa2FYamRaS2tIcEFCZk0wUUV4N1VVaGFJNGk1M2ppSjdFMVk3V09BQUpCRFg0ejYxcG5pSEphcEkxYmtNSWlKUS90aTdoYThmZEpTTVNwQWRzNUN5SEl5SGtReldsVnk4NmY5bUE3RXUzb1JPLzFxK2VGVXpEYk5OM1Z2eTdnUVdRPSJdfQ.eyJhdWQiOlsiaHR0cHM6Ly9yaWEuZWUiLCJ1cm46Y2VydDpzaGEtMjU2OjZmMGRmMjQ0ZTRhODU2Yjk0YjNiM2I0NzU4MmEwYTUxYTMyZDY3NGRiYzcxMDcyMTFlZDIzZDRiZWM2ZDljNzIiXSwiZXhwIjoiMTU4Njg3MTE2OSIsImlhdCI6IjE1ODY4NzA4NjkiLCJpc3MiOiJ3ZWItZWlkIGFwcCB2MC45LjAtMS1nZTZlODlmYSIsIm5vbmNlIjoiMTIzNDU2NzgxMjM0NTY3ODEyMzQ1Njc4MTIzNDU2NzgiLCJzdWIiOiJKw5VFT1JHLEpBQUstS1JJU1RKQU4sMzgwMDEwODU3MTgifQ.0Y5CdMiSZ14rOnd7sbp-XeBQ7qrJVd21yTmAbiRnzAXtwqW8ZROg4jL4J7bpQ2fwyUz4-dVwLoVRVnxfJY82b8NXuxXrDb-8MXXmVYrMW0q0kPbEzqFbEnPYHjNnKAN0"}' +{"sub":"JÕEORG,JAAK-KRISTJAN,38001085718","auth":["ROLE_USER"]} +``` + +## Formatting code + +We use *prettier-java* for formatting code, install and run it as follows: + +```shell script +npm install -g prettier prettier-plugin-java +prettier --write "**/*.{java,js,html}" +``` + +## Deployment + +Build Docker image with Jib as follows: + +```sh +mvn com.google.cloud.tools:jib-maven-plugin:dockerBuild +``` + +and deploy with Docker Compose as follows: + +```sh +docker-compose up -d +``` diff --git a/example/docker-compose.yml b/example/docker-compose.yml new file mode 100644 index 0000000..005e79e --- /dev/null +++ b/example/docker-compose.yml @@ -0,0 +1,7 @@ +version: '2' +services: + web-eid-springboot-example: + image: web-eid-springboot-example:1.0.0-SNAPSHOT + restart: always + ports: + - '127.0.0.1:8380:8080' diff --git a/example/mvnw b/example/mvnw new file mode 100644 index 0000000..a16b543 --- /dev/null +++ b/example/mvnw @@ -0,0 +1,310 @@ +#!/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 +# +# https://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. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven 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.6/maven-wrapper-0.5.6.jar" + else + jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.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/example/mvnw.cmd b/example/mvnw.cmd new file mode 100644 index 0000000..c8d4337 --- /dev/null +++ b/example/mvnw.cmd @@ -0,0 +1,182 @@ +@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 https://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 Maven 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 keystroke 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.6/maven-wrapper-0.5.6.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.6/maven-wrapper-0.5.6.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/example/pom.xml b/example/pom.xml new file mode 100644 index 0000000..d8048c4 --- /dev/null +++ b/example/pom.xml @@ -0,0 +1,143 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.2.5.RELEASE + + + org.webeid.example + web-eid-springboot-example + 1.0.0-SNAPSHOT + web-eid-springboot-example + Example Spring Boot project that demonstrates how to use Web eID for authentication and digital + signing + + + + 1.8 + 2.22.1 + 1.44 + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.security + spring-security-config + + + + javax.cache + cache-api + 1.1.1 + + + com.hazelcast + hazelcast + + + + org.hibernate.validator + hibernate-validator + + + com.google.guava + guava + 20.0 + + + + org.digidoc4j + digidoc4j + 4.0.3 + + + org.webeid.security + authtoken-validation + 1.0.0-SNAPSHOT + + + + org.springframework.boot + spring-boot-devtools + true + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.junit.vintage + junit-vintage-engine + + + + + org.springframework.security + spring-security-test + test + + + + org.jmockit + jmockit + ${jmockit.version} + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + maven-surefire-plugin + ${maven-surefire-plugin.version} + + + -javaagent:${settings.localRepository}/org/jmockit/jmockit/${jmockit.version}/jmockit-${jmockit.version}.jar + + true + + + + + + + + gitlab-maven + https://gitlab.com/api/v4/projects/19948337/packages/maven + + + + + + gitlab-maven + https://gitlab.com/api/v4/projects/19948337/packages/maven + + + + gitlab-maven + https://gitlab.com/api/v4/projects/19948337/packages/maven + + + + diff --git a/example/src/main/java/org/webeid/example/WebEidSpringbootExampleApplication.java b/example/src/main/java/org/webeid/example/WebEidSpringbootExampleApplication.java new file mode 100644 index 0000000..12c43dc --- /dev/null +++ b/example/src/main/java/org/webeid/example/WebEidSpringbootExampleApplication.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2020 The Web eID Project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.webeid.example; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class WebEidSpringbootExampleApplication { + + public static void main(String[] args) { + SpringApplication.run(WebEidSpringbootExampleApplication.class, args); + } +} diff --git a/example/src/main/java/org/webeid/example/config/ApplicationConfiguration.java b/example/src/main/java/org/webeid/example/config/ApplicationConfiguration.java new file mode 100644 index 0000000..59e088f --- /dev/null +++ b/example/src/main/java/org/webeid/example/config/ApplicationConfiguration.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2020 The Web eID Project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.webeid.example.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.security.web.authentication.logout.HttpStatusReturningLogoutSuccessHandler; +import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import org.webeid.example.security.AuthTokenDTOAuthenticationProvider; +import org.webeid.example.security.WebEidAjaxLoginProcessingFilter; + +@Configuration +@EnableWebSecurity +@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true) +public class ApplicationConfiguration extends WebSecurityConfigurerAdapter implements WebMvcConfigurer { + final AuthTokenDTOAuthenticationProvider authTokenDTOAuthenticationProvider; + + public ApplicationConfiguration(AuthTokenDTOAuthenticationProvider authTokenDTOAuthenticationProvider) { + this.authTokenDTOAuthenticationProvider = authTokenDTOAuthenticationProvider; + } + + @Override + protected void configure(AuthenticationManagerBuilder authenticationManagerBuilder) { + authenticationManagerBuilder.authenticationProvider(authTokenDTOAuthenticationProvider); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + // @formatter:off + http + .addFilterBefore( + new WebEidAjaxLoginProcessingFilter("/auth/login", authenticationManager()), + UsernamePasswordAuthenticationFilter.class) + .authorizeRequests() + .antMatchers("/auth/challenge", "/auth/login", "/") + .permitAll() + .antMatchers("/welcome") + .authenticated() + .and() + .logout() + .logoutUrl("/logout") + .deleteCookies("JSESSIONID") + .logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler()) + .and() + .csrf() + .disable(); + // @formatter:on + } + + public void addViewControllers(ViewControllerRegistry registry) { + registry.addViewController("/welcome").setViewName("welcome"); + } + + +} diff --git a/example/src/main/java/org/webeid/example/config/ValidationConfiguration.java b/example/src/main/java/org/webeid/example/config/ValidationConfiguration.java new file mode 100644 index 0000000..dc2ae7e --- /dev/null +++ b/example/src/main/java/org/webeid/example/config/ValidationConfiguration.java @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2020 The Web eID Project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.webeid.example.config; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.Resource; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.webeid.security.nonce.NonceGenerator; +import org.webeid.security.nonce.NonceGeneratorBuilder; +import org.webeid.security.validator.AuthTokenValidator; +import org.webeid.security.validator.AuthTokenValidatorBuilder; + +import javax.cache.Cache; +import javax.cache.CacheManager; +import javax.cache.Caching; +import javax.cache.configuration.CompleteConfiguration; +import javax.cache.configuration.MutableConfiguration; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +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.time.LocalDateTime; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; + +@Configuration +public class ValidationConfiguration { + + private static final Logger LOG = LoggerFactory.getLogger(ValidationConfiguration.class); + private static final String CACHE_NAME = "nonceCache"; + + @Bean + public Cache nonceCache() { + CacheManager cacheManager = Caching.getCachingProvider().getCacheManager(); + Cache cache = cacheManager.getCache(CACHE_NAME); + + if (cache == null) { + CompleteConfiguration cacheConfig = new MutableConfiguration().setTypes(String.class, LocalDateTime.class); + cache = cacheManager.createCache(CACHE_NAME, cacheConfig); + } + return cache; + } + + @Bean + public NonceGenerator generator() { + return new NonceGeneratorBuilder() + .withNonceCache(nonceCache()) + .build(); + } + + @Bean + public X509Certificate[] trustedCertificateAuthorities() { + List caCertificates = new ArrayList<>(); + + try { + CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); + + PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); + Resource[] resources = resolver.getResources("/certs/*.cer"); + + for (Resource resource : resources) { + X509Certificate caCertificate = (X509Certificate) certFactory.generateCertificate(resource.getInputStream()); + caCertificates.add(caCertificate); + } + + } catch (CertificateException | IOException e) { + LOG.error("Error initializing trusted CA certificates.", e); + throw new RuntimeException("Error initializing trusted CA certificates.", e); + } + + return caCertificates.toArray(new X509Certificate[0]); + } + + @Bean + public X509Certificate[] initializeTrustedCACertificatesFromKeyStore() { + List caCertificates = new ArrayList<>(); + + try (InputStream is = ValidationConfiguration.class.getResourceAsStream("/certs/trusted_certificates.jks")) { + KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType()); + keystore.load(is, yamlConfig().getKeystorePassword().toCharArray()); + Enumeration aliases = keystore.aliases(); + while (aliases.hasMoreElements()) { + String alias = aliases.nextElement(); + X509Certificate certificate = (X509Certificate) keystore.getCertificate(alias); + caCertificates.add(certificate); + } + } catch (IOException | CertificateException | KeyStoreException | NoSuchAlgorithmException e) { + LOG.error("Error initializing trusted CA certificates from trust store.", e); + throw new RuntimeException("Error initializing trusted CA certificates from trust store.", e); + } + + return caCertificates.toArray(new X509Certificate[0]); + } + + + @Bean + public AuthTokenValidator validator() { + return new AuthTokenValidatorBuilder() + .withSiteOrigin(URI.create(yamlConfig().getLocalOrigin())) + // FIXME: decide what should validation library do when cert fingerprint validation is enabled but fingerprint is null (as in Chrome) +// .withSiteCertificateSha256Fingerprint(yamlConfig().getFingerprint()) + .withNonceCache(nonceCache()) + .withTrustedCertificateAuthorities(trustedCertificateAuthorities()) + .withTrustedCertificateAuthorities(initializeTrustedCACertificatesFromKeyStore()) + // FIXME: investigate why for Idemia test card OcspUtils.ocspUri() -> null so that "User certificate revocation check has failed: The CA/certificate doesn't have an OCSP responder" + .withoutUserCertificateRevocationCheckWithOcsp() + .build(); + } + + @Bean + public YAMLConfig yamlConfig() { + return new YAMLConfig(); + } +} diff --git a/example/src/main/java/org/webeid/example/config/YAMLConfig.java b/example/src/main/java/org/webeid/example/config/YAMLConfig.java new file mode 100644 index 0000000..d756101 --- /dev/null +++ b/example/src/main/java/org/webeid/example/config/YAMLConfig.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2020 The Web eID Project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.webeid.example.config; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableConfigurationProperties +@ConfigurationProperties(prefix = "token.validation") +public class YAMLConfig { + + private final String FINGERPRINT_PREFIX = "urn:cert:sha-256:"; + + @Value("local-origin") + private String localOrigin; + private String fingerprint; + + @Value("keystore-password") + private String keystorePassword; + + public String getLocalOrigin() { + return localOrigin; + } + + public void setLocalOrigin(String localOrigin) { + this.localOrigin = localOrigin; + } + + public String getFingerprint() { + if(fingerprint != null && !fingerprint.startsWith(FINGERPRINT_PREFIX)) { + fingerprint = FINGERPRINT_PREFIX + fingerprint.replace(":", "").toLowerCase(); + } + return fingerprint; + } + + public void setFingerprint(String fingerprint) { + this.fingerprint = fingerprint; + } + + public String getKeystorePassword() { + return keystorePassword; + } + + public void setKeystorePassword(String keystorePassword) { + this.keystorePassword = keystorePassword; + } +} diff --git a/example/src/main/java/org/webeid/example/security/AuthTokenDTOAuthenticationProvider.java b/example/src/main/java/org/webeid/example/security/AuthTokenDTOAuthenticationProvider.java new file mode 100644 index 0000000..de22a3c --- /dev/null +++ b/example/src/main/java/org/webeid/example/security/AuthTokenDTOAuthenticationProvider.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2020 The Web eID Project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.webeid.example.security; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.authentication.AuthenticationServiceException; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken; +import org.springframework.stereotype.Component; +import org.webeid.example.security.dto.AuthTokenDTO; +import org.webeid.security.exceptions.TokenValidationException; +import org.webeid.security.util.CertUtil; +import org.webeid.security.validator.AuthTokenValidator; + +import java.security.cert.CertificateEncodingException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.List; + +/** + * Parses JWT from token string inside AuthTokenDTO and attempts authentication. + */ +@Component +public class AuthTokenDTOAuthenticationProvider implements AuthenticationProvider { + public static final String ROLE_USER = "ROLE_USER"; + private static final GrantedAuthority USER_ROLE = new SimpleGrantedAuthority(ROLE_USER); + + private static final Logger LOG = LoggerFactory.getLogger(AuthTokenDTOAuthenticationProvider.class); + + @Autowired + private AuthTokenValidator tokenValidator; + + @Override + public Authentication authenticate(Authentication auth) throws AuthenticationException { + LOG.info("authenticate(): {}", auth); + + final PreAuthenticatedAuthenticationToken authentication = (PreAuthenticatedAuthenticationToken) auth; + + final String token = ((AuthTokenDTO) authentication.getCredentials()).getToken(); + + final List authorities = new ArrayList<>(2); + authorities.add(USER_ROLE); + + try { + X509Certificate userCertificate = tokenValidator.validate(token); + return new PreAuthenticatedAuthenticationToken(getPrincipalFromCertificate(userCertificate), null, authorities); + } catch (TokenValidationException e) { + LOG.warn("Token validation has failed", e); + throw new AuthenticationServiceException("Token validation failed: " + e.getMessage()); + } catch (CertificateEncodingException e) { + LOG.warn("Failed to extract subject fields from certificate", e); + throw new AuthenticationServiceException("Incorrect certificate subject fields: " + e.getMessage()); + } + } + + @Override + public boolean supports(Class authentication) { + LOG.info("supports(): {}", authentication); + return PreAuthenticatedAuthenticationToken.class.equals(authentication); + } + + // FIXME: create a proper principal object + private String getPrincipalFromCertificate(X509Certificate userCertificate) throws CertificateEncodingException { + return CertUtil.getSubjectGivenName(userCertificate) + ' ' + + CertUtil.getSubjectSurname(userCertificate) + ", " + + CertUtil.getSubjectIdCode(userCertificate); + } +} diff --git a/example/src/main/java/org/webeid/example/security/WebEidAjaxLoginProcessingFilter.java b/example/src/main/java/org/webeid/example/security/WebEidAjaxLoginProcessingFilter.java new file mode 100644 index 0000000..b78b54f --- /dev/null +++ b/example/src/main/java/org/webeid/example/security/WebEidAjaxLoginProcessingFilter.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2020 The Web eID Project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.webeid.example.security; + +import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpMethod; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.AuthenticationServiceException; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; +import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken; +import org.webeid.example.security.ajax.AjaxAuthenticationFailureHandler; +import org.webeid.example.security.ajax.AjaxAuthenticationSuccessHandler; +import org.webeid.example.security.dto.AuthTokenDTO; + +public class WebEidAjaxLoginProcessingFilter extends AbstractAuthenticationProcessingFilter { + private static final Logger LOG = LoggerFactory.getLogger(WebEidAjaxLoginProcessingFilter.class); + + public WebEidAjaxLoginProcessingFilter( + String defaultFilterProcessesUrl, + AuthenticationManager authenticationManager + ) { + super(defaultFilterProcessesUrl); + this.setAuthenticationManager(authenticationManager); + this.setAuthenticationSuccessHandler(new AjaxAuthenticationSuccessHandler()); + this.setAuthenticationFailureHandler(new AjaxAuthenticationFailureHandler()); + } + + @Override + public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) + throws AuthenticationException, IOException { + if (!HttpMethod.POST.name().equals(request.getMethod())) { + LOG.warn("HttpMethod not supported: {}", request.getMethod()); + throw new AuthenticationServiceException("HttpMethod not supported: " + request.getMethod()); + } + final String contentType = request.getHeader("Content-type"); + if (contentType == null || !contentType.startsWith("application/json")) { + LOG.warn("Content type not supported: {}", contentType); + throw new AuthenticationServiceException("Content type not supported: " + contentType); + } + + LOG.info("attemptAuthentication(): Reading request body"); + final ObjectMapper objectMapper = new ObjectMapper(); + final AuthTokenDTO authTokenDTO = objectMapper.readValue(request.getReader(), AuthTokenDTO.class); + LOG.info("attemptAuthentication(): Creating token"); + final PreAuthenticatedAuthenticationToken token = new PreAuthenticatedAuthenticationToken(null, authTokenDTO); + LOG.info("attemptAuthentication(): Calling authentication manager"); + return getAuthenticationManager().authenticate(token); + } +} diff --git a/example/src/main/java/org/webeid/example/security/ajax/AjaxAuthenticationFailureHandler.java b/example/src/main/java/org/webeid/example/security/ajax/AjaxAuthenticationFailureHandler.java new file mode 100644 index 0000000..d173206 --- /dev/null +++ b/example/src/main/java/org/webeid/example/security/ajax/AjaxAuthenticationFailureHandler.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2020 The Web eID Project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.webeid.example.security.ajax; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import java.io.IOException; + +public class AjaxAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler { + private static final Logger LOG = LoggerFactory.getLogger(AjaxAuthenticationFailureHandler.class); + + public static final String AUTHENTICATION_FAILED = "Authentication failed: "; + + @Override + public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, + AuthenticationException exception) throws IOException { + final String message = AUTHENTICATION_FAILED + exception.getMessage(); + LOG.warn("onAuthenticationFailure(): exception {}, returning {} {}", + exception, + HttpServletResponse.SC_UNAUTHORIZED, + message); + final HttpSession session = request.getSession(false); + if (session != null) { + LOG.info("Invalidating session"); + session.invalidate(); + } + response.sendError(HttpServletResponse.SC_UNAUTHORIZED, message); + } +} diff --git a/example/src/main/java/org/webeid/example/security/ajax/AjaxAuthenticationSuccessHandler.java b/example/src/main/java/org/webeid/example/security/ajax/AjaxAuthenticationSuccessHandler.java new file mode 100644 index 0000000..2d2ccc7 --- /dev/null +++ b/example/src/main/java/org/webeid/example/security/ajax/AjaxAuthenticationSuccessHandler.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2020 The Web eID Project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.webeid.example.security.ajax; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler; +import org.springframework.stereotype.Component; + +/** + * Write custom response on having user successfully authenticated. + *

+ * This is not required in production application, but to demonstrate that + * authentication and authorization steps have been passed. + */ +@Component +public class AjaxAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler { + private static final Logger LOG = LoggerFactory.getLogger(AjaxAuthenticationSuccessHandler.class); + + @Override + public void onAuthenticationSuccess( + HttpServletRequest request, + HttpServletResponse response, + Authentication authentication + ) + throws IOException { + LOG.info("onAuthenticationSuccess(): {}", authentication); + + response.setStatus(HttpServletResponse.SC_OK); + response.setHeader("Content-Type", "application/json; charset=utf-8"); + + response.getWriter().write(AuthSuccessDTO.asJson(authentication)); + } + + public static class AuthSuccessDTO { + private final ObjectMapper objectMapper = new ObjectMapper(); + + @JsonProperty("sub") + private String sub; + + @JsonProperty("auth") + private List auth; + + public static String asJson(Authentication authentication) throws JsonProcessingException { + final AuthSuccessDTO dto = new AuthSuccessDTO(); + dto.sub = authentication.getName(); + dto.auth = convertAuthorities(authentication.getAuthorities()); + return dto.objectMapper.writeValueAsString(dto); + } + + private static List convertAuthorities(Collection authorities) { + return authorities.stream().map(GrantedAuthority::toString).collect(Collectors.toList()); + } + } +} diff --git a/example/src/main/java/org/webeid/example/security/dto/AuthTokenDTO.java b/example/src/main/java/org/webeid/example/security/dto/AuthTokenDTO.java new file mode 100644 index 0000000..7235404 --- /dev/null +++ b/example/src/main/java/org/webeid/example/security/dto/AuthTokenDTO.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2020 The Web eID Project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.webeid.example.security.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class AuthTokenDTO { + @JsonProperty("auth-token") + private String token; + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } +} diff --git a/example/src/main/java/org/webeid/example/service/SigningService.java b/example/src/main/java/org/webeid/example/service/SigningService.java new file mode 100644 index 0000000..e790204 --- /dev/null +++ b/example/src/main/java/org/webeid/example/service/SigningService.java @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2020 The Web eID Project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.webeid.example.service; + +import com.google.common.io.ByteStreams; +import org.apache.commons.io.FilenameUtils; +import org.digidoc4j.*; +import org.digidoc4j.utils.TokenAlgorithmSupport; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.ObjectFactory; +import org.springframework.core.io.ByteArrayResource; +import org.springframework.stereotype.Service; +import org.webeid.example.service.dto.CertificateDTO; +import org.webeid.example.service.dto.DigestDTO; +import org.webeid.example.service.dto.FileDTO; +import org.webeid.example.service.dto.SignatureDTO; +import org.webeid.example.web.rest.SigningController; + +import javax.servlet.http.HttpSession; +import javax.xml.bind.DatatypeConverter; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.Base64; +import java.util.Objects; + +@Service +public class SigningService { + + private static final String SESSION_ATTR_FILE = "file-to-sign"; + private static final String SESSION_ATTR_CONTAINER = "container-to-sign"; + private static final String SESSION_ATTR_DATA = "data-to-sign"; + private static final Logger LOG = LoggerFactory.getLogger(SigningController.class); + private final Configuration signingConfiguration; + + ObjectFactory httpSessionFactory; + + public SigningService(ObjectFactory httpSessionFactory) { + // FIXME: use PROD conf + real OCSP (with IP whitelisting) + this.signingConfiguration = Configuration.of(Configuration.Mode.TEST); + this.httpSessionFactory = httpSessionFactory; + } + + private HttpSession currentSession() { + return httpSessionFactory.getObject(); + } + + /** + * Creates a {@link Container} using given name and files. + * + * @param fileDTO container file + * @return new {@link Container} instance + */ + public FileDTO createContainer(FileDTO fileDTO) { + + LOG.info("Creating container for file '{}'", fileDTO.getName()); + ContainerBuilder builder = ContainerBuilder.aContainer(Container.DocumentType.ASICE); + + byte[] fileBytes = Base64.getDecoder().decode(fileDTO.getBase64String().getBytes(StandardCharsets.UTF_8)); + DataFile dataFile = new DataFile(fileBytes, fileDTO.getName(), fileDTO.getContentType()); + builder.withDataFile(dataFile); + + LOG.info("Successfully created container '{}'", fileDTO.getName()); + Container containerToSign = builder.withConfiguration(signingConfiguration).build(); + + currentSession().setAttribute(SESSION_ATTR_CONTAINER, containerToSign); + currentSession().setAttribute(SESSION_ATTR_FILE, fileDTO); + + FileDTO newFileDTO = new FileDTO(); + newFileDTO.setName(fileDTO.getName()); + + return newFileDTO; + } + + /** + * Prepares given container {@link Container} for the signature process. + * + * @param certificateDTO user's X.509 certificate + * @return data to be signed + */ + public DigestDTO prepareContainer(CertificateDTO certificateDTO) throws CertificateException, NoSuchAlgorithmException { + X509Certificate certificate = certificateDTO.toX509Certificate(); + FileDTO fileDTO = (FileDTO) Objects.requireNonNull(currentSession().getAttribute(SESSION_ATTR_FILE)); + Container containerToPrepare = (Container) Objects.requireNonNull(currentSession().getAttribute(SESSION_ATTR_CONTAINER)); + + String containerName = generateContainerName(fileDTO.getName()); + LOG.info("Preparing container for signing for file '{}'", containerName); + + DataToSign dataToSign = SignatureBuilder. + aSignature(containerToPrepare). + withSigningCertificate(certificate). + withSignatureDigestAlgorithm(TokenAlgorithmSupport.determineSignatureDigestAlgorithm(certificate)). + buildDataToSign(); + + currentSession().setAttribute(SESSION_ATTR_DATA, dataToSign); + + LOG.info("Successfully prepared container for signing for file '{}'", containerName); + + final String digestAlgorithm = certificateDTO.getSupportedAlgorithmNames().contains("SHA384") ? + "SHA-384" : "SHA-256"; + + final byte[] digest = MessageDigest.getInstance(digestAlgorithm).digest(dataToSign.getDataToSign()); + + DigestDTO digestDTO = new DigestDTO(); + digestDTO.setHash(DatatypeConverter.printBase64Binary(digest)); + digestDTO.setAlgorithm(digestAlgorithm); + + return digestDTO; + } + + /** + * Signs a {@link Container} using given {@link SignatureDTO}. + * Container to sign is taken from the current session. + * + * @param signatureDTO signature DTO + * @return fileDTO + */ + public FileDTO signContainer(SignatureDTO signatureDTO) { + try { + FileDTO fileDTO = (FileDTO) Objects.requireNonNull(currentSession().getAttribute(SESSION_ATTR_FILE)); + Container containerToSign = (Container) Objects.requireNonNull(currentSession().getAttribute(SESSION_ATTR_CONTAINER)); + DataToSign dataToSign = (DataToSign) Objects.requireNonNull(currentSession().getAttribute(SESSION_ATTR_DATA)); + + byte[] signatureBytes = DatatypeConverter.parseBase64Binary(signatureDTO.getBase64Signature()); + Signature signature = dataToSign.finalize(signatureBytes); + containerToSign.addSignature(signature); + currentSession().setAttribute(SESSION_ATTR_CONTAINER, containerToSign); + + FileDTO result = new FileDTO(); + result.setName(generateContainerName(fileDTO.getName())); + return result; + } catch (Exception ex) { + LOG.error("Signing of container caused an error", ex); + throw new RuntimeException("Signing of container caused an error"); + } + } + + private String generateContainerName(String fileName) { + return FilenameUtils.removeExtension(fileName) + ".asice"; + } + + + public String getContainerName() { + FileDTO fileDTO = (FileDTO) Objects.requireNonNull(currentSession().getAttribute(SESSION_ATTR_FILE)); + return generateContainerName(fileDTO.getName()); + } + + public ByteArrayResource getSignedContainerAsResource() throws IOException { + Container signedContainer = (Container) Objects.requireNonNull(currentSession().getAttribute(SESSION_ATTR_CONTAINER)); + return new ByteArrayResource(ByteStreams.toByteArray(signedContainer.saveAsStream())); + } +} diff --git a/example/src/main/java/org/webeid/example/service/dto/CertificateDTO.java b/example/src/main/java/org/webeid/example/service/dto/CertificateDTO.java new file mode 100644 index 0000000..0f81e39 --- /dev/null +++ b/example/src/main/java/org/webeid/example/service/dto/CertificateDTO.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2020 The Web eID Project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.webeid.example.service.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Base64; +import java.util.List; +import java.util.stream.Collectors; + +public class CertificateDTO { + + @JsonProperty("certificate") + private String base64String; + + @JsonProperty("supported-signature-algos") + private List supportedSignatureAlgorithms; + + public String getBase64String() { + return base64String; + } + + public void setBase64String(String base64String) { + this.base64String = base64String; + } + + public List getSupportedSignatureAlgorithms() { + return supportedSignatureAlgorithms; + } + + public void setSupportedSignatureAlgorithms(List supportedSignatureAlgorithms) { + this.supportedSignatureAlgorithms = supportedSignatureAlgorithms; + } + + public X509Certificate toX509Certificate() throws CertificateException { + byte[] certificateBytes = Base64.getDecoder().decode(base64String); + InputStream inStream = new ByteArrayInputStream(certificateBytes); + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + return (X509Certificate) cf.generateCertificate(inStream); + } + + public List getSupportedAlgorithmNames() { + return supportedSignatureAlgorithms == null ? new ArrayList<>() : supportedSignatureAlgorithms + .stream() + .map(SignatureAlgorithmDTO::getHashAlgorithm) + .distinct() + .collect(Collectors.toList()); + } +} diff --git a/example/src/main/java/org/webeid/example/service/dto/ChallengeDTO.java b/example/src/main/java/org/webeid/example/service/dto/ChallengeDTO.java new file mode 100644 index 0000000..e0fd24b --- /dev/null +++ b/example/src/main/java/org/webeid/example/service/dto/ChallengeDTO.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2020 The Web eID Project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.webeid.example.service.dto; + +public class ChallengeDTO { + private String nonce; + + public String getNonce() { + return nonce; + } + + public void setNonce(String nonce) { + this.nonce = nonce; + } +} diff --git a/example/src/main/java/org/webeid/example/service/dto/DigestDTO.java b/example/src/main/java/org/webeid/example/service/dto/DigestDTO.java new file mode 100644 index 0000000..dbb3e6f --- /dev/null +++ b/example/src/main/java/org/webeid/example/service/dto/DigestDTO.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2020 The Web eID Project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.webeid.example.service.dto; + +public class DigestDTO { + private String hash; + private String algorithm; + + public String getHash() { + return hash; + } + + public void setHash(String hash) { + this.hash = hash; + } + + public String getAlgorithm() { + return algorithm; + } + + public void setAlgorithm(String algorithm) { + this.algorithm = algorithm; + } +} diff --git a/example/src/main/java/org/webeid/example/service/dto/FileDTO.java b/example/src/main/java/org/webeid/example/service/dto/FileDTO.java new file mode 100644 index 0000000..09c82de --- /dev/null +++ b/example/src/main/java/org/webeid/example/service/dto/FileDTO.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2020 The Web eID Project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.webeid.example.service.dto; + +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; +import java.util.Base64; +import java.util.Objects; + +public class FileDTO { + private String name; + private String base64String; + private String contentType; + + public static FileDTO fromMultipartFile(MultipartFile file) throws IOException { + FileDTO dto = new FileDTO(); + dto.name = Objects.requireNonNull(file.getOriginalFilename()); + dto.contentType = Objects.requireNonNull(file.getContentType()); + dto.base64String = Base64.getEncoder().encodeToString(Objects.requireNonNull(file.getBytes())); + return dto; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getBase64String() { + return base64String; + } + + public void setBase64String(String base64String) { + this.base64String = base64String; + } + + public String getContentType() { + return contentType; + } + + public void setContentType(String contentType) { + this.contentType = contentType; + } +} diff --git a/example/src/main/java/org/webeid/example/service/dto/SignatureAlgorithmDTO.java b/example/src/main/java/org/webeid/example/service/dto/SignatureAlgorithmDTO.java new file mode 100644 index 0000000..31373de --- /dev/null +++ b/example/src/main/java/org/webeid/example/service/dto/SignatureAlgorithmDTO.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2020 The Web eID Project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.webeid.example.service.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class SignatureAlgorithmDTO { + + @JsonProperty("crypto-algo") + private String cryptoAlgorithm; + + @JsonProperty("hash-algo") + private String hashAlgorithm; + + @JsonProperty("padding-algo") + private String paddingAlgorithm; + + public String getCryptoAlgorithm() { + return cryptoAlgorithm; + } + + public void setCryptoAlgorithm(String cryptoAlgorithm) { + this.cryptoAlgorithm = cryptoAlgorithm; + } + + public String getHashAlgorithm() { + return hashAlgorithm; + } + + public void setHashAlgorithm(String hashAlgorithm) { + this.hashAlgorithm = hashAlgorithm; + } + + public String getPaddingAlgorithm() { + return paddingAlgorithm; + } + + public void setPaddingAlgorithm(String paddingAlgorithm) { + this.paddingAlgorithm = paddingAlgorithm; + } +} diff --git a/example/src/main/java/org/webeid/example/service/dto/SignatureDTO.java b/example/src/main/java/org/webeid/example/service/dto/SignatureDTO.java new file mode 100644 index 0000000..5253a48 --- /dev/null +++ b/example/src/main/java/org/webeid/example/service/dto/SignatureDTO.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2020 The Web eID Project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.webeid.example.service.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class SignatureDTO { + private String hash; + private String algorithm; + + @JsonProperty("signature") + private String base64Signature; + + public String getHash() { + return hash; + } + + public void setHash(String hash) { + this.hash = hash; + } + + public String getAlgorithm() { + return algorithm; + } + + public void setAlgorithm(String algorithm) { + this.algorithm = algorithm; + } + + public String getBase64Signature() { + return base64Signature; + } + + public void setBase64Signature(String base64Signature) { + this.base64Signature = base64Signature; + } +} diff --git a/example/src/main/java/org/webeid/example/web/WelcomeController.java b/example/src/main/java/org/webeid/example/web/WelcomeController.java new file mode 100644 index 0000000..66d34d3 --- /dev/null +++ b/example/src/main/java/org/webeid/example/web/WelcomeController.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2020 The Web eID Project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.webeid.example.web; + +import static org.webeid.example.security.AuthTokenDTOAuthenticationProvider.ROLE_USER; + +import java.security.Principal; +import javax.validation.constraints.NotNull; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; + +@Controller +public class WelcomeController { + private static final Logger LOG = LoggerFactory.getLogger(WelcomeController.class); + + @PreAuthorize("hasAuthority('" + ROLE_USER + "')") + @GetMapping("welcome") + public String welcome(Model model, @NotNull Principal principal) { + LOG.info("Showing welcome page, logged in as principal={}", principal.getName()); + model.addAttribute("principalName", principal.getName()); + return "welcome"; + } +} diff --git a/example/src/main/java/org/webeid/example/web/rest/ChallengeController.java b/example/src/main/java/org/webeid/example/web/rest/ChallengeController.java new file mode 100644 index 0000000..602a11d --- /dev/null +++ b/example/src/main/java/org/webeid/example/web/rest/ChallengeController.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2020 The Web eID Project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.webeid.example.web.rest; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.webeid.example.service.dto.ChallengeDTO; +import org.webeid.security.nonce.NonceGenerator; + +@RestController +@RequestMapping("auth") +public class ChallengeController { + + private final NonceGenerator nonceGenerator; + + public ChallengeController(NonceGenerator nonceGenerator) { + this.nonceGenerator = nonceGenerator; + } + + @GetMapping("challenge") + public ChallengeDTO challenge() { + final ChallengeDTO challenge = new ChallengeDTO(); + challenge.setNonce(nonceGenerator.generateAndStoreNonce()); + return challenge; + } +} diff --git a/example/src/main/java/org/webeid/example/web/rest/SigningController.java b/example/src/main/java/org/webeid/example/web/rest/SigningController.java new file mode 100644 index 0000000..c049630 --- /dev/null +++ b/example/src/main/java/org/webeid/example/web/rest/SigningController.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2020 The Web eID Project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.webeid.example.web.rest; + +import org.springframework.core.io.ByteArrayResource; +import org.springframework.core.io.Resource; +import org.springframework.http.HttpHeaders; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import org.webeid.example.service.SigningService; +import org.webeid.example.service.dto.CertificateDTO; +import org.webeid.example.service.dto.DigestDTO; +import org.webeid.example.service.dto.FileDTO; +import org.webeid.example.service.dto.SignatureDTO; + +import java.io.IOException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; + +@RestController +@RequestMapping("sign") +public class SigningController { + + private final SigningService signingService; + + public SigningController(SigningService signingService) { + this.signingService = signingService; + } + + @PostMapping(value = "upload", produces = "application/json") + public FileDTO upload(@RequestParam("file") MultipartFile multipartFile) throws IOException { + return signingService.createContainer(FileDTO.fromMultipartFile(multipartFile)); + } + + @PostMapping("prepare") + public DigestDTO prepare(@RequestBody CertificateDTO data) throws CertificateException, NoSuchAlgorithmException { + return signingService.prepareContainer(data); + } + + @PostMapping("sign") + public FileDTO sign(@RequestBody SignatureDTO data) { + return signingService.signContainer(data); + } + + @GetMapping(value = "download", produces = "application/vnd.etsi.asic-e+zip") + public ResponseEntity download() throws IOException { + + ByteArrayResource resource = signingService.getSignedContainerAsResource(); + return ResponseEntity.ok() + .contentLength(resource.contentLength()) + .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + signingService.getContainerName()) + .body(resource); + } +} diff --git a/example/src/main/resources/application.properties b/example/src/main/resources/application.properties new file mode 100644 index 0000000..cbb42d2 --- /dev/null +++ b/example/src/main/resources/application.properties @@ -0,0 +1 @@ +spring.profiles.active=dev diff --git a/example/src/main/resources/application.yaml b/example/src/main/resources/application.yaml new file mode 100644 index 0000000..ba1e78c --- /dev/null +++ b/example/src/main/resources/application.yaml @@ -0,0 +1,11 @@ +spring: + profiles: dev + servlet: + multipart: + max-file-size: 5000KB + max-request-size: 5000KB +token: + validation: + local-origin: "https://web-eid.eu" + fingerprint: "11:D8:AE:60:EC:19:10:C7:94:D7:4C:82:C8:0D:96:B2:07:88:B5:6A:D2:65:FF:F9:B5:14:C8:75:F7:90:08:E1" + keystore-password: "changeit" diff --git a/example/src/main/resources/certs/ESTEID-SK_2015.cer b/example/src/main/resources/certs/ESTEID-SK_2015.cer new file mode 100644 index 0000000000000000000000000000000000000000..b16695560fd7f7498f20dedd8ac67098f6eeee57 GIT binary patch literal 1652 zcmXqLVk7~D2aMlsHU>`aH^Y`xS}0|jwj zLsLT|LvuqTV+#}GC<%Te17ib_fRVAOrKx3# zz|hzbD#6Ud=NcU1>gl2z?5$vAU}$R4#H55AAdIXG%uP)E3_x)%rY0svhD(jVu3Y$- zdv)*Rlc$-Z+A{VrzWXzG;oX))^Dp^`Io@Z~RhZCS=H;?cUo-Y&lG_^QuoG;OyZ1TY z&s`VxQ>X7!_pTEYrSzX%f6IEM*H+bX4M&76M}F!Q1#6Zl*>x_bA4KU)e5SWd!23qP zUT&sj9i88z`6i*7+Fow_>y%EOnrrkR^xyWPr3-vOBNkXD#Lh-*2P4$x$Xx&sBFWoh{-1IZgvIBe5mKc1o zY3y7Ttz-CNoqCgT7GrdSOPh(Q>?3uxOCrJ_G$&MgZk60RkF{HF#Sb6H`f7&&@0dwf zPp34UYA}8ywRHub`R|7^otx`Uh?~ykHcRW;Q{?ZX?RMyhv0RXg$oZvl4p~)SI{Tb< z8$4b$`Ml@aQm!+eJDy&$6xg_)+!b zO7ANoGYw=x3iw#WSVT6j?$|T)YSNNcEsnEWWQ(kui`)YZ_(0P9jEw(TSb&+6&7d5_ zS70eH$TQ$zV`E|HuVQ2ZW=3`vhVC~GK&Am3r#2fS3*$L?Mn(f=14T9tAeWVuorzIQ zG^3=Xpx8=Zzr4I$51gg+odbdmxDh&-kU7lA92Ns1kj26vhj19M0V!ZgH*f@r$+1`& zSS&O%U;$L4RjSriQ9U@m3mgtM67EEa8CVDv>$|$fqm)KK9;h^m2bD(g&W?I1 zsYQCpMI{EdAZN<6m>HND7%ebZpx35@VPH{eL4I*&Nq$kKesWPxv3_c5a&l2}B2aq{ za(MwPK$)8u85v5#c#_QReYI~LUOw&9aV`Hi;jMq~KKb|XU2x?R9jl3!XIVo0ZYv(S z&p2Op@V?mgOcP?e^&Swgg`8Lk9Lwc8aMT*f_WD$n`_=Ts!uy z^C+wf{uaFH+$!mv8#xO1CVihh;a)`luN!XPYX3c|U8ml7TE^l~-|g$S%5Hpp!sL4X zx$eIe>(5o)ubH-nS`!$APM4d@dyQbD|osn1n1|JmSpDV6)QLf8;To|jqaF|x60H?lA&GdH#|urMCCkj#JU zbxl}#{4EZD8=UiQ7|m7nS=nAVC+d`}>%&(UQ<|iY@8C_jVX|U&gv&Fph3r#v zmY6TgXKhvyo)F2{r~Fs;A0VE5xKdh;C6i7z9~NzJlW^I=z_`GSz1B{d?0Cl zM#ldvEWns%GY|stg+Y7{12!PV#K>UK#CR4Ys=(63cm&8fV8Fq~#=_8F#mEGVc6Jtq z?l%rVrV$&rHX9=gWAj8sMn*;hWdlVv4xj)lD?1aTm}o{xNkOrdzJ7Umxn6O$UTUho zb3m{GFR~scByK&(2ozaXR4yATmmQVMjLKy}<#M2MIZ?S>s9bJTE)Ob~7nRG0%H>Dp z3ZQZYQMp2>TwzqM2oe_|dZPvVVbG6UH}SY?B4WDlk$LGZUeanwqMco?n)n2+l$JaHULb%21`rP=&~u zTrVZHNH4jl#6SY3fsvVo$AAlx&idSdNx=Z*VtE!#19bz{1ryv>4iIF*z|RuVU`CR9u&?WpdKyHoH@>(wk*DibsxH vHN+Il?|g7yGCo*=t>@%SyV|wW>~DXbCmgq(g@^f~dx!()8JmCmqDx}|!-qnr literal 0 HcmV?d00001 diff --git a/example/src/main/resources/certs/TEST_of_ESTEID-SK_2015.cer b/example/src/main/resources/certs/TEST_of_ESTEID-SK_2015.cer new file mode 100644 index 0000000000000000000000000000000000000000..7749286c895084bf2d7bacb98b742a01cd684122 GIT binary patch literal 1671 zcmb7EX;4#F6wZ5ji4YT@LXe$^l>i-*`vL)3WD$Z;z=c%QO6{Uz|Nti5Ys|*EzrHLU@nPI%pFormh!Q(M}UdIaK zh5^P>8p=gE=t|&>IygG=jdVG{ z0pJd2jsw?)>%s>~|DWJeK-UnAqw1^;3*qtXQQ++83{VHu5}3bcZn(faG>jMEYabfO z-~f~h6tLCX4T4Anq5{?>;C>3MfFXkFHX*9@YOKZPhws_e%qlnOxqQNRwIF&n`~1KE|CGi>^}+HLlswpy~$=6&4-s8xoQu zPWZNaI-1?K_1m)=i%?y>INNxazUcC3=NFXg{Lh`Ad45@PS*LrIYTEetNUfHrv#Vuz z!^?qN&#WMG!<^jJDzbBy1YKXU#6!Pztk|T2UvZ`;T2i5xe=9g>AlSFJ&0{qDxBce} zGxzCtI8=KbySVY7swKF3L{S$NR�?itslb-bPA?nh!_1G3$MPD2FPu$I{g%r!&R2 z7Wd~~5Wl%Zb&m2WF~aUx^f0H!IT=uI@RRV8ox@z?+~Vy|8D@qT+J=qy&-q8w#2zEW z2o9}C(Yo!lu)kE2_u_8K=yLn6HRI5`n zsa6&tfKJg0aY#En=1H<22%?{K4E76 z{^(l5NYEX2cK46HW>pDOFcBg^RSKAfPlPtG#D~dzIf763E`#%ql=4$-y(^>3bedFk z*cwyfw%J$HX0C%6A_f7?lfEw4%`!hX+RE7Mx;}dwWi`;zyw`=GIRwF%l?)O!n1Kku zM*t;LJ|IH~)L}`4Ag~-PBWvN9L|OzxhV;#HxkTp5W~Zg4v0kka+h=_!puY74eg_fX zK?qo)$)m5ys|CpTg%39H*7z(CSFrN96F~4iumY4^Ey9}vta2Ii_J7@gsrh0B!T=WY zWQp1f7QA2~VE5j606|D5*a=q5V*n|QHPzw8C15GyH`NK_1Y)5~0zwwTV5Q%iuzz|W z#1%-!)-1L_oG9S&1n)=^jx>@a&`6TN$D5UaNm)Xv9QbHRTO#fNue{Q!(oxCzcXy?j zL@X1@#nN=PP?{`b%Q2Z;fMG(RR2YYUlKi%0;F?NQKoFtDWzSej1FN!l*U`=!Cn?sn zJBhYMN6%(Y5V8znN<+$f>|Emwh@a_k>IXiqZaCYfpj)CtH)li_+}E{7H<1W@=XS#^ zk5pEZ4tXR;>CsZo?QFTW^+PAsUsa#xxl6cvJp#_n^fag0JjuBf6Th2TRy19ex5>-q zfckldT}3N)JvnlfKYgd2=Q$TXbg#>X!ff?V+wV{=G&xpz=_SnV;64Ak!`EPhIYw8ESfeZIIag&l~psrr8d>b^~V literal 0 HcmV?d00001 diff --git a/example/src/main/resources/certs/TEST_of_ESTEID2018.cer b/example/src/main/resources/certs/TEST_of_ESTEID2018.cer new file mode 100644 index 0000000000000000000000000000000000000000..6a96fb083686e6210a1c5f14cfd0cf7780227843 GIT binary patch literal 1408 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 + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/example/src/main/resources/static/index.html b/example/src/main/resources/static/index.html new file mode 100644 index 0000000..4ccc697 --- /dev/null +++ b/example/src/main/resources/static/index.html @@ -0,0 +1,150 @@ + + + + + + Web eID test page + + + + +

+
+
+

Web eID test page

+

+ The Web eID project enables usage of European Union electronic identity (eID) smart cards for + secure authentication and digital signing of documents on the web using public-key cryptography. +

+

Estonian, Finnish, Latvian and Lithuanian eID cards are supported, but only Estonian eID card support + is currently enabled in this test service.

+

+ Technical overview of the solution is available in the project + system architecture document. +

+ +
+

Testing

+

+ Instructions for testing in Firefox, Chrome, Edge or Opera (support for Safari has been already + added as well, but it is not yet published): +

+
    +
  1. Currently you need an Estonian eID test card for testing, and + the authentication and signing certificates of the test card must be uploaded to the + demo.sk.ee OCSP responder database. +
  2. +
  3. + Download and install the Web eID native app: +
      +
    • + for Ubuntu Linux 20.04 from here +
    • +
    • for macOS 10.13 or later from here
    • +
    • for Windows 10 from here.
    • +
    +
  4. +
  5. + The installer will install the browser extension for Chrome and Edge automatically. + The extension must be manually enabled in Edge and may require manual enabling in Chrome + as well under certain circumstances. +
  6. +
  7. The installer will also install the browser extension for Firefox automatically in + Ubuntu Linux and macOS. In Windows, the Firefox browser extension has to be manually + installed: +
      +
    • download the extension from here +
    • +
    • in Firefox, open the Firefox menu and click Add-ons
    • +
    • from the settings cog, open Install Add-on From File
    • +
    • browse to and open the XPI file from the location where it was saved
    • +
    • When prompted click Add
    • +
    +
  8. +
  9. + Attach a smart card reader to the computer and insert the eID card into the reader. +
  10. +
  11. Click Authenticate below.
  12. +
+ +

+ +

+ +
+

Debugging and logs

+
    +
  • + To debug the extension, open the extension page and select + Inspect to open browser developer tools in extension mode. You can examine extension + logs in the Console tab, put breakpoints in extension code in the Debugger tab + and inspect extension network communication in the Network tab. +
  • +
  • + The native app logs are stored in +
      +
    • ~/.local/share/RIA/web-eid/web-eid.log in Linux
    • +
    • ~/Library/Application Support/RIA/web-eid/web-eid.log in macOS
    • +
    • + C:/Users/<USER>/AppData/Local/RIA/web-eid/web-eid.log in Windows. +
    • +
    +
  • +
+
+
+
+ +
+ EU fund flags +
+ + + + diff --git a/example/src/main/resources/static/js/error-message.js b/example/src/main/resources/static/js/error-message.js new file mode 100644 index 0000000..840b942 --- /dev/null +++ b/example/src/main/resources/static/js/error-message.js @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2020 The Web eID Project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +"use strict"; + +const alertUi = { + alert: document.querySelector("#error-message"), + alertMessage: document.querySelector("#error-message .message"), + alertDetails: document.querySelector("#error-message .details") +}; + +export function hideErrorMessage() { + alertUi.alert.style.display = "none"; +} + +export function showErrorMessage(error) { + const message = "Authentication failed"; + const details = + `[Code]\n${error.code}` + + `\n\n[Message]\n${error.message}` + + (error.response ? `\n\n[response]\n${JSON.stringify(error.response, null, " ")}` : ""); + + alertUi.alertMessage.innerText = message; + alertUi.alertDetails.innerText = details; + alertUi.alert.style.display = "block"; +} diff --git a/example/src/main/resources/static/js/web-eid-0.9.0.js b/example/src/main/resources/static/js/web-eid-0.9.0.js new file mode 100644 index 0000000..b5b7419 --- /dev/null +++ b/example/src/main/resources/static/js/web-eid-0.9.0.js @@ -0,0 +1,521 @@ +/* + * Copyright (c) 2020 The Web eID Project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +var config = Object.freeze({ + VERSION: "0.9.0", + EXTENSION_HANDSHAKE_TIMEOUT: 1000, + NATIVE_APP_HANDSHAKE_TIMEOUT: 5 * 1000, + DEFAULT_USER_INTERACTION_TIMEOUT: 2 * 60 * 1000, + DEFAULT_SERVER_REQUEST_TIMEOUT: 20 * 1000, +}); + +var ErrorCode; +(function (ErrorCode) { + // Timeout errors + ErrorCode["ERR_WEBEID_ACTION_TIMEOUT"] = "ERR_WEBEID_ACTION_TIMEOUT"; + ErrorCode["ERR_WEBEID_USER_TIMEOUT"] = "ERR_WEBEID_USER_TIMEOUT"; + ErrorCode["ERR_WEBEID_SERVER_TIMEOUT"] = "ERR_WEBEID_SERVER_TIMEOUT"; + // Health errors + ErrorCode["ERR_WEBEID_VERSION_MISMATCH"] = "ERR_WEBEID_VERSION_MISMATCH"; + ErrorCode["ERR_WEBEID_VERSION_INVALID"] = "ERR_WEBEID_VERSION_INVALID"; + ErrorCode["ERR_WEBEID_EXTENSION_UNAVAILABLE"] = "ERR_WEBEID_EXTENSION_UNAVAILABLE"; + ErrorCode["ERR_WEBEID_NATIVE_UNAVAILABLE"] = "ERR_WEBEID_NATIVE_UNAVAILABLE"; + ErrorCode["ERR_WEBEID_UNKNOWN_ERROR"] = "ERR_WEBEID_UNKNOWN_ERROR"; + // Security errors + ErrorCode["ERR_WEBEID_CONTEXT_INSECURE"] = "ERR_WEBEID_CONTEXT_INSECURE"; + ErrorCode["ERR_WEBEID_PROTOCOL_INSECURE"] = "ERR_WEBEID_PROTOCOL_INSECURE"; + ErrorCode["ERR_WEBEID_TLS_CONNECTION_BROKEN"] = "ERR_WEBEID_TLS_CONNECTION_BROKEN"; + ErrorCode["ERR_WEBEID_TLS_CONNECTION_INSECURE"] = "ERR_WEBEID_TLS_CONNECTION_INSECURE"; + ErrorCode["ERR_WEBEID_TLS_CONNECTION_WEAK"] = "ERR_WEBEID_TLS_CONNECTION_WEAK"; + ErrorCode["ERR_WEBEID_CERTIFICATE_CHANGED"] = "ERR_WEBEID_CERTIFICATE_CHANGED"; + ErrorCode["ERR_WEBEID_ORIGIN_MISMATCH"] = "ERR_WEBEID_ORIGIN_MISMATCH"; + // Third party errors + ErrorCode["ERR_WEBEID_SERVER_REJECTED"] = "ERR_WEBEID_SERVER_REJECTED"; + ErrorCode["ERR_WEBEID_USER_CANCELLED"] = "ERR_WEBEID_USER_CANCELLED"; + ErrorCode["ERR_WEBEID_NATIVE_FATAL"] = "ERR_WEBEID_NATIVE_FATAL"; + // Developer mistakes + ErrorCode["ERR_WEBEID_ACTION_PENDING"] = "ERR_WEBEID_ACTION_PENDING"; + ErrorCode["ERR_WEBEID_MISSING_PARAMETER"] = "ERR_WEBEID_MISSING_PARAMETER"; +})(ErrorCode || (ErrorCode = {})); +var ErrorCode$1 = ErrorCode; + +var Action; +(function (Action) { + Action["STATUS"] = "web-eid:status"; + Action["STATUS_ACK"] = "web-eid:status-ack"; + Action["STATUS_SUCCESS"] = "web-eid:status-success"; + Action["STATUS_FAILURE"] = "web-eid:status-failure"; + Action["AUTHENTICATE"] = "web-eid:authenticate"; + Action["AUTHENTICATE_ACK"] = "web-eid:authenticate-ack"; + Action["AUTHENTICATE_SUCCESS"] = "web-eid:authenticate-success"; + Action["AUTHENTICATE_FAILURE"] = "web-eid:authenticate-failure"; + Action["SIGN"] = "web-eid:sign"; + Action["SIGN_ACK"] = "web-eid:sign-ack"; + Action["SIGN_SUCCESS"] = "web-eid:sign-success"; + Action["SIGN_FAILURE"] = "web-eid:sign-failure"; +})(Action || (Action = {})); +var Action$1 = Action; + +class CertificateChangedError extends Error { + constructor(message = "server certificate changed between requests") { + super(message); + this.name = this.constructor.name; + this.code = ErrorCode$1.ERR_WEBEID_CERTIFICATE_CHANGED; + } +} + +class OriginMismatchError extends Error { + constructor(message = "URLs for a single operation require the same origin") { + super(message); + this.name = this.constructor.name; + this.code = ErrorCode$1.ERR_WEBEID_ORIGIN_MISMATCH; + } +} + +const SECURE_CONTEXTS_INFO_URL = "https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts"; +class ContextInsecureError extends Error { + constructor(message = "Secure context required, see " + SECURE_CONTEXTS_INFO_URL) { + super(message); + this.name = this.constructor.name; + this.code = ErrorCode$1.ERR_WEBEID_CONTEXT_INSECURE; + } +} + +class ExtensionUnavailableError extends Error { + constructor(message = "Web-eID extension is not available") { + super(message); + this.name = this.constructor.name; + this.code = ErrorCode$1.ERR_WEBEID_EXTENSION_UNAVAILABLE; + } +} + +class ActionPendingError extends Error { + constructor(message = "same action for Web-eID browser extension is already pending") { + super(message); + this.name = this.constructor.name; + this.code = ErrorCode$1.ERR_WEBEID_ACTION_PENDING; + } +} + +class NativeFatalError extends Error { + constructor(message = "native application terminated with a fatal error") { + super(message); + this.name = this.constructor.name; + this.code = ErrorCode$1.ERR_WEBEID_NATIVE_FATAL; + } +} + +class NativeUnavailableError extends Error { + constructor(message = "Web-eID native application is not available") { + super(message); + this.name = this.constructor.name; + this.code = ErrorCode$1.ERR_WEBEID_NATIVE_UNAVAILABLE; + } +} + +class ServerRejectedError extends Error { + constructor(message = "server rejected the request") { + super(message); + this.name = this.constructor.name; + this.code = ErrorCode$1.ERR_WEBEID_SERVER_REJECTED; + } +} + +class UserTimeoutError extends Error { + constructor(message = "user failed to respond in time") { + super(message); + this.name = this.constructor.name; + this.code = ErrorCode$1.ERR_WEBEID_USER_TIMEOUT; + } +} + +class UserCancelledError extends Error { + constructor(message = "request was cancelled by the user") { + super(message); + this.name = this.constructor.name; + this.code = ErrorCode$1.ERR_WEBEID_USER_CANCELLED; + } +} + +function tmpl(strings, requiresUpdate) { + return `Update required for Web-eID ${requiresUpdate}`; +} +class VersionMismatchError extends Error { + constructor(message, versions, requiresUpdate) { + if (!message) { + if (!requiresUpdate) { + message = "requiresUpdate not provided"; + } + else if (requiresUpdate.extension && requiresUpdate.nativeApp) { + message = tmpl `${"extension and native app"}`; + } + else if (requiresUpdate.extension) { + message = tmpl `${"extension"}`; + } + else if (requiresUpdate.nativeApp) { + message = tmpl `${"native app"}`; + } + } + super(message); + this.name = this.constructor.name; + this.code = ErrorCode$1.ERR_WEBEID_VERSION_MISMATCH; + this.requiresUpdate = requiresUpdate; + if (versions) { + const { library, extension, nativeApp } = versions; + Object.assign(this, { library, extension, nativeApp }); + } + } +} + +class TlsConnectionBrokenError extends Error { + constructor(message = "TLS connection was broken") { + super(message); + this.name = this.constructor.name; + this.code = ErrorCode$1.ERR_WEBEID_TLS_CONNECTION_BROKEN; + } +} + +class TlsConnectionInsecureError extends Error { + constructor(message = "TLS connection was insecure") { + super(message); + this.name = this.constructor.name; + this.code = ErrorCode$1.ERR_WEBEID_TLS_CONNECTION_INSECURE; + } +} + +class TlsConnectionWeakError extends Error { + constructor(message = "TLS connection was weak") { + super(message); + this.name = this.constructor.name; + this.code = ErrorCode$1.ERR_WEBEID_TLS_CONNECTION_WEAK; + } +} + +class ProtocolInsecureError extends Error { + constructor(message = "HTTPS required") { + super(message); + this.name = this.constructor.name; + this.code = ErrorCode$1.ERR_WEBEID_PROTOCOL_INSECURE; + } +} + +class ActionTimeoutError extends Error { + constructor(message = "extension message timeout") { + super(message); + this.name = this.constructor.name; + this.code = ErrorCode$1.ERR_WEBEID_ACTION_TIMEOUT; + } +} + +class VersionInvalidError extends Error { + constructor(message = "invalid version string") { + super(message); + this.name = this.constructor.name; + this.code = ErrorCode$1.ERR_WEBEID_VERSION_INVALID; + } +} + +class ServerTimeoutError extends Error { + constructor(message = "server failed to respond in time") { + super(message); + this.name = this.constructor.name; + this.code = ErrorCode$1.ERR_WEBEID_SERVER_TIMEOUT; + } +} + +class UnknownError extends Error { + constructor(message = "an unknown error occurred") { + super(message); + this.name = this.constructor.name; + this.code = ErrorCode$1.ERR_WEBEID_UNKNOWN_ERROR; + } +} + +const errorCodeToErrorClass = { + [ErrorCode$1.ERR_WEBEID_ACTION_PENDING]: ActionPendingError, + [ErrorCode$1.ERR_WEBEID_ACTION_TIMEOUT]: ActionTimeoutError, + [ErrorCode$1.ERR_WEBEID_CERTIFICATE_CHANGED]: CertificateChangedError, + [ErrorCode$1.ERR_WEBEID_ORIGIN_MISMATCH]: OriginMismatchError, + [ErrorCode$1.ERR_WEBEID_CONTEXT_INSECURE]: ContextInsecureError, + [ErrorCode$1.ERR_WEBEID_EXTENSION_UNAVAILABLE]: ExtensionUnavailableError, + [ErrorCode$1.ERR_WEBEID_NATIVE_FATAL]: NativeFatalError, + [ErrorCode$1.ERR_WEBEID_NATIVE_UNAVAILABLE]: NativeUnavailableError, + [ErrorCode$1.ERR_WEBEID_PROTOCOL_INSECURE]: ProtocolInsecureError, + [ErrorCode$1.ERR_WEBEID_SERVER_REJECTED]: ServerRejectedError, + [ErrorCode$1.ERR_WEBEID_SERVER_TIMEOUT]: ServerTimeoutError, + [ErrorCode$1.ERR_WEBEID_TLS_CONNECTION_BROKEN]: TlsConnectionBrokenError, + [ErrorCode$1.ERR_WEBEID_TLS_CONNECTION_INSECURE]: TlsConnectionInsecureError, + [ErrorCode$1.ERR_WEBEID_TLS_CONNECTION_WEAK]: TlsConnectionWeakError, + [ErrorCode$1.ERR_WEBEID_USER_CANCELLED]: UserCancelledError, + [ErrorCode$1.ERR_WEBEID_USER_TIMEOUT]: UserTimeoutError, + [ErrorCode$1.ERR_WEBEID_VERSION_INVALID]: VersionInvalidError, + [ErrorCode$1.ERR_WEBEID_VERSION_MISMATCH]: VersionMismatchError, +}; +function deserializeError(errorObject) { + let error; + if (typeof errorObject.code == "string" && errorObject.code in errorCodeToErrorClass) { + const CustomError = errorCodeToErrorClass[errorObject.code]; + error = new CustomError(); + } + else { + error = new UnknownError(); + } + for (const [key, value] of Object.entries(errorObject)) { + error[key] = value; + } + return error; +} + +class WebExtensionService { + constructor() { + this.queue = []; + window.addEventListener("message", (event) => this.receive(event)); + } + receive(event) { + var _a, _b, _c, _d; + const message = event.data; + const suffix = (_b = (_a = message.action) === null || _a === void 0 ? void 0 : _a.match(/success$|failure$|ack$/)) === null || _b === void 0 ? void 0 : _b[0]; + const initialAction = this.getInitialAction(message.action); + const pending = this.getPendingMessage(initialAction); + if (suffix === "ack") { + console.log("ack message", message); + console.log("ack pending", pending === null || pending === void 0 ? void 0 : pending.message.action); + console.log("ack queue", JSON.stringify(this.queue)); + } + if (pending) { + switch (suffix) { + case "ack": { + clearTimeout(pending.ackTimer); + break; + } + case "success": { + (_c = pending.resolve) === null || _c === void 0 ? void 0 : _c.call(pending, message); + this.removeFromQueue(initialAction); + break; + } + case "failure": { + (_d = pending.reject) === null || _d === void 0 ? void 0 : _d.call(pending, message.error ? deserializeError(message.error) : message); + this.removeFromQueue(initialAction); + break; + } + } + } + } + send(message, timeout) { + if (this.getPendingMessage(message.action)) { + return Promise.reject(new ActionPendingError()); + } + else if (!window.isSecureContext) { + return Promise.reject(new ContextInsecureError()); + } + else { + const pending = { message }; + this.queue.push(pending); + pending.promise = new Promise((resolve, reject) => { + pending.resolve = resolve; + pending.reject = reject; + }); + pending.ackTimer = setTimeout(() => this.onAckTimeout(pending), config.EXTENSION_HANDSHAKE_TIMEOUT); + pending.replyTimer = setTimeout(() => this.onReplyTimeout(pending), timeout); + window.postMessage(message, "*"); + return pending.promise; + } + } + onReplyTimeout(pending) { + var _a; + console.log("onReplyTimeout", pending.message.action); + (_a = pending.reject) === null || _a === void 0 ? void 0 : _a.call(pending, new ActionTimeoutError()); + this.removeFromQueue(pending.message.action); + } + onAckTimeout(pending) { + var _a; + console.log("onAckTimeout", pending.message.action); + (_a = pending.reject) === null || _a === void 0 ? void 0 : _a.call(pending, new ExtensionUnavailableError()); + clearTimeout(pending.replyTimer); + } + getPendingMessage(action) { + return this.queue.find((pm) => { + return pm.message.action === action; + }); + } + getSuccessAction(action) { + return `${action}-success`; + } + getFailureAction(action) { + return `${action}-failure`; + } + getInitialAction(action) { + return action.replace(/-success$|-failure$|-ack$/, ""); + } + removeFromQueue(action) { + const pending = this.getPendingMessage(action); + clearTimeout(pending === null || pending === void 0 ? void 0 : pending.replyTimer); + this.queue = this.queue.filter((pending) => (pending.message.action !== action)); + } +} + +const semverPattern = new RegExp("^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)" + + "(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$"); +var IdentifierDiff; +(function (IdentifierDiff) { + IdentifierDiff[IdentifierDiff["NEWER"] = 1] = "NEWER"; + IdentifierDiff[IdentifierDiff["SAME"] = 0] = "SAME"; + IdentifierDiff[IdentifierDiff["OLDER"] = -1] = "OLDER"; +})(IdentifierDiff || (IdentifierDiff = {})); +function parseSemver(string = "") { + const result = string.match(semverPattern); + const [, majorStr, minorStr, patchStr, rc, build] = result ? result : []; + const major = parseInt(majorStr, 10); + const minor = parseInt(minorStr, 10); + const patch = parseInt(patchStr, 10); + for (const indentifier of [major, minor, patch]) { + if (Number.isNaN(indentifier)) { + throw new VersionInvalidError(`Invalid SemVer string '${string}'`); + } + } + return { major, minor, patch, rc, build, string }; +} +/** + * Compares two Semver objects. + * + * @param {Semver} a First SemVer object + * @param {Semver} b Second Semver object + * + * @returns {SemverDiff} Diff for major, minor and patch. + */ +function compareSemver(a, b) { + return { + major: Math.sign(a.major - b.major), + minor: Math.sign(a.minor - b.minor), + patch: Math.sign(a.patch - b.patch), + }; +} + +/** + * Checks if update is required. + * + * @param version Object containing SemVer version strings for library, extension and native app. + * + * @returns Object which specifies if the extension or native app should be updated. + */ +function checkCompatibility(version) { + const library = parseSemver(version.library); + const extension = parseSemver(version.extension); + const nativeApp = parseSemver(version.nativeApp); + const extensionDiff = compareSemver(extension, library); + const nativeAppDiff = compareSemver(nativeApp, library); + return { + extension: extensionDiff.major === IdentifierDiff.OLDER, + nativeApp: nativeAppDiff.major === IdentifierDiff.OLDER, + }; +} +/** + * Checks an object if 'library', 'extension' or 'nativeApp' properties are present. + * Values are not checked for SemVer validity. + * + * @param object Object which will be checked for version properties. + * + * @returns Were any of the version properties found in the provided object. + */ +function hasVersionProperties(object) { + if (typeof object === "object") { + for (const prop of ["library", "extension", "nativeApp"]) { + if (Object.hasOwnProperty.call(object, prop)) + return true; + } + } + return false; +} + +class MissingParameterError extends Error { + constructor(message) { + super(message); + this.name = this.constructor.name; + this.code = ErrorCode$1.ERR_WEBEID_MISSING_PARAMETER; + } +} + +function defer() { + return new Promise((resolve) => setTimeout(resolve)); +} + +const webExtensionService = new WebExtensionService(); +async function status() { + await defer(); // Give chrome a moment to load the extension content script + let statusResponse; + const library = config.VERSION; + const timeout = config.EXTENSION_HANDSHAKE_TIMEOUT + config.NATIVE_APP_HANDSHAKE_TIMEOUT; + const message = { action: Action$1.STATUS }; + try { + statusResponse = await webExtensionService.send(message, timeout); + } + catch (error) { + error.library = library; + throw error; + } + const versions = { library, ...statusResponse }; + const requiresUpdate = checkCompatibility(versions); + if (requiresUpdate.extension || requiresUpdate.nativeApp) { + throw new VersionMismatchError(undefined, versions, requiresUpdate); + } + return versions; +} +async function authenticate(options) { + await defer(); // Give chrome a moment to load the extension content script + if (typeof options != "object") { + throw new MissingParameterError("authenticate function requires an options object as parameter"); + } + if (!options.getAuthChallengeUrl) { + throw new MissingParameterError("getAuthChallengeUrl missing from authenticate options"); + } + if (!options.postAuthTokenUrl) { + throw new MissingParameterError("postAuthTokenUrl missing from authenticate options"); + } + const timeout = (config.EXTENSION_HANDSHAKE_TIMEOUT + + config.NATIVE_APP_HANDSHAKE_TIMEOUT + + (options.serverRequestTimeout || config.DEFAULT_SERVER_REQUEST_TIMEOUT) * 2 + + (options.userInteractionTimeout || config.DEFAULT_USER_INTERACTION_TIMEOUT)); + const message = { ...options, action: Action$1.AUTHENTICATE }; + const result = await webExtensionService.send(message, timeout); + return result.response; +} +async function sign(options) { + await defer(); // Give chrome a moment to load the extension content script + if (typeof options != "object") { + throw new MissingParameterError("sign function requires an options object as parameter"); + } + if (!options.postPrepareSigningUrl) { + throw new MissingParameterError("postPrepareSigningUrl missing from sign options"); + } + if (!options.postFinalizeSigningUrl) { + throw new MissingParameterError("postFinalizeSigningUrl missing from sign options"); + } + const timeout = (config.EXTENSION_HANDSHAKE_TIMEOUT + + config.NATIVE_APP_HANDSHAKE_TIMEOUT + + (options.serverRequestTimeout || config.DEFAULT_SERVER_REQUEST_TIMEOUT) * 2 + + (options.userInteractionTimeout || config.DEFAULT_USER_INTERACTION_TIMEOUT) * 2); + const message = { ...options, action: Action$1.SIGN }; + const result = await webExtensionService.send(message, timeout); + return result.response; +} + +export { Action$1 as Action, ErrorCode$1 as ErrorCode, authenticate, config, hasVersionProperties, sign, status }; diff --git a/example/src/main/resources/templates/welcome.html b/example/src/main/resources/templates/welcome.html new file mode 100644 index 0000000..c28462e --- /dev/null +++ b/example/src/main/resources/templates/welcome.html @@ -0,0 +1,143 @@ + + + + + + Welcome! + + + + +
+
+
+
+

Adding Signature

+

+
+
+
+
Drag file here for signing...
+

+ + +

+
+

+ + +

+
+ +
+
+ + + + + diff --git a/example/src/test/java/org/webeid/example/AuthenticationRestControllerTest.java b/example/src/test/java/org/webeid/example/AuthenticationRestControllerTest.java new file mode 100644 index 0000000..660b522 --- /dev/null +++ b/example/src/test/java/org/webeid/example/AuthenticationRestControllerTest.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2020 The Web eID Project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.webeid.example; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.webeid.example.security.ajax.AjaxAuthenticationSuccessHandler; +import org.webeid.example.web.rest.ChallengeController; + +import javax.servlet.http.HttpSession; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest +class AuthenticationRestControllerTest { + @Autowired + ChallengeController authRestController; + + @Autowired + AjaxAuthenticationSuccessHandler ajaxAuthenticationSuccessHandler; + + @Autowired + HttpSession httpSession; + + @Test + void contextLoads() { + assertThat(authRestController).isNotNull(); + } + + @Test + void challengeNotNull() { + assertThat(authRestController.challenge()).isNotNull(); + } + + // TODO: add tests here +} diff --git a/example/src/test/java/org/webeid/example/WebApplicationTest.java b/example/src/test/java/org/webeid/example/WebApplicationTest.java new file mode 100644 index 0000000..b86e655 --- /dev/null +++ b/example/src/test/java/org/webeid/example/WebApplicationTest.java @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2020 The Web eID Project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.webeid.example; + +import com.hazelcast.util.Base64; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.HttpStatus; +import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.mock.web.MockHttpSession; +import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; +import org.webeid.example.service.dto.DigestDTO; +import org.webeid.example.testutil.Dates; +import org.webeid.example.testutil.FakeNonce; +import org.webeid.example.testutil.HttpHelper; +import org.webeid.example.testutil.ObjectMother; + +import java.nio.charset.StandardCharsets; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; + +@SpringBootTest +@WebAppConfiguration +public class WebApplicationTest { + @Autowired + private WebApplicationContext context; + + @Autowired + private javax.servlet.Filter[] springSecurityFilterChain; + + private static final byte[] TEST_NONCE_BYTES = Base64.decode("a/wAFpMaXojLIaEmeOvviRNoBVqHBM/Mm9JV28ZcaIo=".getBytes(StandardCharsets.UTF_8)); + private static DefaultMockMvcBuilder mvcBuilder; + + @BeforeEach + public void setup() { + mvcBuilder = MockMvcBuilders.webAppContextSetup(context).addFilters(springSecurityFilterChain); + } + + @Test + public void testRoot() throws Exception { + // @formatter:off + MockHttpServletResponse response = mvcBuilder + .build() + .perform(get("/")) + .andReturn() + .getResponse(); + // @formatter:on + assertEquals(HttpStatus.OK.value(), response.getStatus()); + System.out.println(response.getContentAsString()); + } + + @Disabled // FIXME: fix and enable + @Test + public void testHappyFlow_LoginUploadPrepareSignDownload() throws Exception { + + final MockHttpSession session = new MockHttpSession(); + + FakeNonce.setMockedNonce(TEST_NONCE_BYTES); + Dates.setMockedDate(Dates.create("2020-04-14T13:36:49Z")); + + mvcBuilder.build().perform(get("/auth/challenge")); + + MockHttpServletResponse response = HttpHelper.login(mvcBuilder, session, ObjectMother.mockAuthToken()); + assertEquals("{\"sub\":\"JÕEORG,JAAK-KRISTJAN,38001085718\",\"auth\":[\"ROLE_USER\"]}", response.getContentAsString()); + + response = HttpHelper.upload(mvcBuilder, session, ObjectMother.mockMultipartFile()); + assertEquals(HttpStatus.OK.value(), response.getStatus()); + + response = HttpHelper.prepare(mvcBuilder, session, ObjectMother.mockPrepareRequest()); + assertEquals(HttpStatus.OK.value(), response.getStatus()); + + + DigestDTO digestDTO = ObjectMother.jsonStringToBean(response.getContentAsString(), DigestDTO.class); + + response = HttpHelper.sign(mvcBuilder, session, ObjectMother.mockSignRequest(digestDTO.getHash())); + assertEquals(HttpStatus.OK.value(), response.getStatus()); + + response = HttpHelper.download(mvcBuilder, session, ObjectMother.mockSignRequest(digestDTO.getHash())); + assertEquals(HttpStatus.OK.value(), response.getStatus()); + assertEquals("attachment; filename=test-file.asice", response.getHeader("Content-Disposition")); + } +} diff --git a/example/src/test/java/org/webeid/example/testutil/Dates.java b/example/src/test/java/org/webeid/example/testutil/Dates.java new file mode 100644 index 0000000..3b43c8c --- /dev/null +++ b/example/src/test/java/org/webeid/example/testutil/Dates.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2020 The Web eID Project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.webeid.example.testutil; + +import com.fasterxml.jackson.databind.util.StdDateFormat; +import mockit.Mock; +import mockit.MockUp; + +import java.text.ParseException; +import java.util.Date; + +public final class Dates { + private static final StdDateFormat STD_DATE_FORMAT = new StdDateFormat(); + + public static Date create(String iso8601Date) throws ParseException { + return STD_DATE_FORMAT.parse(iso8601Date); + } + + public static void setMockedDate(Date mockedDate) { + new MockUp() { + @Mock + public long currentTimeMillis() { + return mockedDate.getTime(); + } + }; + } + +} diff --git a/example/src/test/java/org/webeid/example/testutil/FakeNonce.java b/example/src/test/java/org/webeid/example/testutil/FakeNonce.java new file mode 100644 index 0000000..c923cb9 --- /dev/null +++ b/example/src/test/java/org/webeid/example/testutil/FakeNonce.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2020 The Web eID Project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.webeid.example.testutil; + +public final class FakeNonce { + + public static void setMockedNonce(byte[] nonce) { + // FIXME: +// new MockUp() { +// @Mock +// public byte[] getNonceBytes() { +// return nonce; +// } +// }; + } +} diff --git a/example/src/test/java/org/webeid/example/testutil/HttpHelper.java b/example/src/test/java/org/webeid/example/testutil/HttpHelper.java new file mode 100644 index 0000000..9ec2f99 --- /dev/null +++ b/example/src/test/java/org/webeid/example/testutil/HttpHelper.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2020 The Web eID Project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.webeid.example.testutil; + +import org.springframework.http.MediaType; +import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.mock.web.MockHttpSession; +import org.springframework.mock.web.MockMultipartFile; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder; +import org.webeid.example.security.dto.AuthTokenDTO; +import org.webeid.example.service.dto.CertificateDTO; +import org.webeid.example.service.dto.SignatureDTO; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; + +public class HttpHelper { + + public static MockHttpServletResponse login(DefaultMockMvcBuilder mvcBuilder, MockHttpSession session, AuthTokenDTO authTokenDTO) throws Exception { + // @formatter:off + return mvcBuilder + .build() + .perform(post("/auth/login") + .session(session) + .contentType(MediaType.APPLICATION_JSON) + .content(ObjectMother.toJson(authTokenDTO))) + .andReturn() + .getResponse(); + // @formatter:on + } + + public static MockHttpServletResponse upload(DefaultMockMvcBuilder mvcBuilder, MockHttpSession session, MockMultipartFile mockMultipartFile) throws Exception { + // @formatter:off + return mvcBuilder + .build() + .perform(MockMvcRequestBuilders.multipart("/sign/upload") + .file(mockMultipartFile) + .session(session)) + .andReturn() + .getResponse(); + // @formatter:on + } + + public static MockHttpServletResponse prepare(DefaultMockMvcBuilder mvcBuilder, MockHttpSession session, CertificateDTO certificateDTO) throws Exception { + // @formatter:off + return mvcBuilder + .build() + .perform(post("/sign/prepare") + .session(session) + .contentType(MediaType.APPLICATION_JSON) + .content(ObjectMother.toJson(certificateDTO))) + .andReturn() + .getResponse(); + // @formatter:on + } + + public static MockHttpServletResponse sign(DefaultMockMvcBuilder mvcBuilder, MockHttpSession session, SignatureDTO signatureDTO) throws Exception { + // @formatter:off + return mvcBuilder + .build() + .perform(post("/sign/sign") + .session(session) + .contentType(MediaType.APPLICATION_JSON) + .content(ObjectMother.toJson(signatureDTO))) + .andReturn() + .getResponse(); + // @formatter:on + } + + public static MockHttpServletResponse download(DefaultMockMvcBuilder mvcBuilder, MockHttpSession session, SignatureDTO mockSignRequest) throws Exception { + // @formatter:off + return mvcBuilder + .build() + .perform(get("/sign/download") + .session(session)) + .andReturn() + .getResponse(); + // @formatter:on + } +} diff --git a/example/src/test/java/org/webeid/example/testutil/ObjectMother.java b/example/src/test/java/org/webeid/example/testutil/ObjectMother.java new file mode 100644 index 0000000..678b576 --- /dev/null +++ b/example/src/test/java/org/webeid/example/testutil/ObjectMother.java @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2020 The Web eID Project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.webeid.example.testutil; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.commons.lang3.ArrayUtils; +import org.digidoc4j.DigestAlgorithm; +import org.digidoc4j.exceptions.DigiDoc4JException; +import org.springframework.mock.web.MockMultipartFile; +import org.webeid.example.security.dto.AuthTokenDTO; +import org.webeid.example.service.dto.CertificateDTO; +import org.webeid.example.service.dto.SignatureDTO; + +import javax.xml.bind.DatatypeConverter; +import java.io.FileInputStream; +import java.security.GeneralSecurityException; +import java.security.KeyStore; +import java.security.PrivateKey; +import java.security.cert.X509Certificate; +import java.util.Base64; + +public class ObjectMother { + + public static final String TEST_PKI_CONTAINER = "src/test/resources/signout.p12"; + public static final String TEST_PKI_CONTAINER_PASSWORD = "test"; + private static final ObjectMapper mapper = new ObjectMapper(); + + public static AuthTokenDTO mockAuthToken() throws JsonProcessingException { + AuthTokenDTO authToken = new AuthTokenDTO(); + authToken.setToken(Tokens.SIGNED); + return authToken; + } + + public static String toJson(Object object) throws JsonProcessingException { + return mapper.writeValueAsString(object); + } + + + public static MockMultipartFile mockMultipartFile() { + return new MockMultipartFile("file", "test-file.txt", "text/plain", "some xml".getBytes()); + } + + public static String mockCertificateInBase64() { + try { + X509Certificate certificate = getSigningCert(); + byte[] derEncodedCertificate = certificate.getEncoded(); + return DatatypeConverter.printBase64Binary(derEncodedCertificate); + } catch (Exception e) { + throw new RuntimeException("Certificate loading failed", e); + } + } + + public static String mockSignatureInBase64(String digestToSign) { + return signDigest(DatatypeConverter.parseBase64Binary(digestToSign)); + } + + public static T jsonStringToBean(String jsonString, Class valueType) throws JsonProcessingException { + return mapper.readValue(jsonString, valueType); + } + + public static CertificateDTO mockPrepareRequest() { + CertificateDTO certificateDTODTO = new CertificateDTO(); + certificateDTODTO.setBase64String(mockCertificateInBase64()); + return certificateDTODTO; + } + + public static SignatureDTO mockSignRequest(String digestToSign) { + SignatureDTO signatureDTO = new SignatureDTO(); + signatureDTO.setBase64Signature(mockSignatureInBase64(digestToSign)); + return signatureDTO; + } + + private static X509Certificate getSigningCert() { + try { + KeyStore keyStore = KeyStore.getInstance("PKCS12"); + try (FileInputStream stream = new FileInputStream(TEST_PKI_CONTAINER)) { + keyStore.load(stream, TEST_PKI_CONTAINER_PASSWORD.toCharArray()); + } + return (X509Certificate) keyStore.getCertificate("1"); + } catch (Exception e) { + throw new RuntimeException("Loading signer cert failed"); + } + } + + private static byte[] sign(byte[] dataToSign) { + try { + KeyStore keyStore = KeyStore.getInstance("PKCS12"); + try (FileInputStream stream = new FileInputStream(TEST_PKI_CONTAINER)) { + keyStore.load(stream, TEST_PKI_CONTAINER_PASSWORD.toCharArray()); + } + PrivateKey privateKey = (PrivateKey) keyStore.getKey("1", TEST_PKI_CONTAINER_PASSWORD.toCharArray()); + final String javaSignatureAlgorithm = "NONEwith" + privateKey.getAlgorithm(); + + return encrypt(javaSignatureAlgorithm, privateKey, addOID(dataToSign)); + } catch (Exception e) { + throw new DigiDoc4JException("Loading private key failed"); + } + } + + private static byte[] addOID(byte[] digest) { + return ArrayUtils.addAll(DigestAlgorithm.SHA256.digestInfoPrefix(), digest); + } + + private static byte[] encrypt(final String javaSignatureAlgorithm, final PrivateKey privateKey, final byte[] bytes) { + try { + java.security.Signature signature = java.security.Signature.getInstance(javaSignatureAlgorithm); + signature.initSign(privateKey); + signature.update(bytes); + return signature.sign(); + } catch (GeneralSecurityException e) { + throw new RuntimeException(e); + } + } + + private static String signDigest(byte[] digestToSign) { + byte[] signatureValue = sign(digestToSign); + return Base64.getEncoder().encodeToString(signatureValue); + } + +} diff --git a/example/src/test/java/org/webeid/example/testutil/Tokens.java b/example/src/test/java/org/webeid/example/testutil/Tokens.java new file mode 100644 index 0000000..4f213ff --- /dev/null +++ b/example/src/test/java/org/webeid/example/testutil/Tokens.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2020 The Web eID Project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.webeid.example.testutil; + +public class Tokens { + + public static final String SIGNED = + "eyJhbGciOiJFUzM4NCIsInR5cCI6IkpXVCIsIng1YyI6WyJNSUlFUkRDQ0E2YWdBd0lCQWdJUWF2WS81dFg4cVZKYmNxUlBML2k4VXpBS0JnZ3Foa2pPUFFRREJEQmdNUXN3Q1FZRFZRUUdFd0pGUlRFYk1Ca0dBMVVFQ2d3U1Uwc2dTVVFnVTI5c2RYUnBiMjV6SUVGVE1SY3dGUVlEVlFSaERBNU9WRkpGUlMweE1EYzBOekF4TXpFYk1Ca0dBMVVFQXd3U1ZFVlRWQ0J2WmlCRlUxUkZTVVF5TURFNE1CNFhEVEU0TURneE5EQTVORE0wTTFvWERUSXpNRGd4TWpJeE5UazFPVm93ZnpFTE1Ba0dBMVVFQmhNQ1JVVXhLakFvQmdOVkJBTU1JVXJEbFVWUFVrY3NTa0ZCU3kxTFVrbFRWRXBCVGl3ek9EQXdNVEE0TlRjeE9ERVFNQTRHQTFVRUJBd0hTc09WUlU5U1J6RVdNQlFHQTFVRUtnd05Ta0ZCU3kxTFVrbFRWRXBCVGpFYU1CZ0dBMVVFQlJNUlVFNVBSVVV0TXpnd01ERXdPRFUzTVRnd2RqQVFCZ2NxaGtqT1BRSUJCZ1VyZ1FRQUlnTmlBQVQ4akc4RXZzVVZvbVdoUXJNZ2xkVUU3QUNKR2lERklGa295SC9YRTQ2Z040SzJqWXF1NjVETGh0ZmxOMXRuWjRLT2YyYllUeUJ5N3ZmRTVMWjFrRXpLT3FCWWgxbm10cUxQb2FYdlpxYWREVktCU3UvaUxmRm43TFZtcnFDUWwraWpnZ0lFTUlJQ0FEQUpCZ05WSFJNRUFqQUFNQTRHQTFVZER3RUIvd1FFQXdJRGlEQkhCZ05WSFNBRVFEQStNRElHQ3lzR0FRUUJnNUVoQVFJQk1DTXdJUVlJS3dZQkJRVUhBZ0VXRldoMGRIQnpPaTh2ZDNkM0xuTnJMbVZsTDBOUVV6QUlCZ1lFQUk5NkFRSXdId1lEVlIwUkJCZ3dGb0VVTXpnd01ERXdPRFUzTVRoQVpXVnpkR2t1WldVd0hRWURWUjBPQkJZRUZOaUVZRHVQRnZpb1VwcFh4QXgwSUpJSVlOUmlNR0VHQ0NzR0FRVUZCd0VEQkZVd1V6QlJCZ1lFQUk1R0FRVXdSekJGRmo5b2RIUndjem92TDNOckxtVmxMMlZ1TDNKbGNHOXphWFJ2Y25rdlkyOXVaR2wwYVc5dWN5MW1iM0l0ZFhObExXOW1MV05sY25ScFptbGpZWFJsY3k4VEFrVk9NQ0FHQTFVZEpRRUIvd1FXTUJRR0NDc0dBUVVGQndNQ0JnZ3JCZ0VGQlFjREJEQWZCZ05WSFNNRUdEQVdnQlRBaEprcHhFNmZPd0kwOXBuaENsWUFDQ2srZXpCL0JnZ3JCZ0VGQlFjQkFRUnpNSEV3TEFZSUt3WUJCUVVITUFHR0lHaDBkSEE2THk5aGFXRXVaR1Z0Ynk1emF5NWxaUzlsYzNSbGFXUXlNREU0TUVFR0NDc0dBUVVGQnpBQ2hqVm9kSFJ3Y3pvdkwzTnJMbVZsTDNWd2JHOWhaQzltYVd4bGN5OVVSVk5VWDI5bVgwVlRWRVZKUkRJd01UZ3VaR1Z5TG1OeWREQXpCZ05WSFI4RUxEQXFNQ2lnSnFBa2hpSm9kSFJ3T2k4dll5NXpheTVsWlM5MFpYTjBYMlZ6ZEdWcFpESXdNVGd1WTNKc01Bb0dDQ3FHU000OUJBTUVBNEdMQURDQmh3SkNBZDdOR3VDTlhHeFRiNVRnUmVZeFJTZjVYaHByMXFhVGZZZG5Kb1lOWDM5bVg5bFkxZGd5ZmJta1BzTDVpejBiWUxLOXBxRnBKOHdablZpSmpSaTV5dUh4QWtFTjJIdk0vU3d4MEJxRE9uN1FzdjZ6aXgzaHBMUUluWEllRms4aXR2OVhsdnA0VlE1S0g3bXNFZUp6N2NIMEdOTnFaTnBIdkVkTEFjMkJyT2tXbGdadUtRPT0iXX0.eyJhdWQiOlsiaHR0cHM6Ly81MjhiYzlmMjE1MjAubmdyb2suaW8iLCJ1cm46Y2VydDpzaGEtMjU2OjExZDhhZTYwZWMxOTEwYzc5NGQ3NGM4MmM4MGQ5NmIyMDc4OGI1NmFkMjY1ZmZmOWI1MTRjODc1Zjc5MDA4ZTEiXSwiZXhwIjoiMTYwMTU0MTgzNiIsImlhdCI6IjE2MDE1NDE1MzYiLCJpc3MiOiJ3ZWItZWlkIGFwcCAwLjkuMi1yYzEiLCJub25jZSI6ImEvd0FGcE1hWG9qTElhRW1lT3Z2aVJOb0JWcUhCTS9NbTlKVjI4WmNhSW89Iiwic3ViIjoiSsOVRU9SRyxKQUFLLUtSSVNUSkFOLDM4MDAxMDg1NzE4In0.BwC7jocegvB23K8YbuiakF7UdjpW1Rvl4u8zdNdm75M0QygLSOCuW7Nmn5tjKmqNmZjcOBxLlt3uN95_yFxZQAjRpCrkW-7bqfbJVzaqKnBx5lyvrO-69tEMKW578qCz"; + } diff --git a/example/src/test/resources/signout.p12 b/example/src/test/resources/signout.p12 new file mode 100644 index 0000000000000000000000000000000000000000..c3454bc6ad75577b1eb2a898a12314f4278739fd GIT binary patch literal 3061 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 DF8QKu literal 0 HcmV?d00001 From 3222b3c055ba4e15d9c792781282a74a4df26f6f Mon Sep 17 00:00:00 2001 From: Mart Somermaa Date: Mon, 28 Dec 2020 21:51:13 +0200 Subject: [PATCH 003/116] Add macOS installer --- example/src/main/resources/static/files/web-eid-0.9.3.869.pkg | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 example/src/main/resources/static/files/web-eid-0.9.3.869.pkg diff --git a/example/src/main/resources/static/files/web-eid-0.9.3.869.pkg b/example/src/main/resources/static/files/web-eid-0.9.3.869.pkg new file mode 100644 index 0000000..2422585 --- /dev/null +++ b/example/src/main/resources/static/files/web-eid-0.9.3.869.pkg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aeb461c229974e8ac77863adb2c44005e6de97bce0d91f0c06585cab15897f10 +size 16356278 From 4170767fd10ec68761dd82432e42108f46b171c8 Mon Sep 17 00:00:00 2001 From: Mart Somermaa Date: Mon, 28 Dec 2020 21:52:28 +0200 Subject: [PATCH 004/116] Add Ubuntu and Windows installer --- .../src/main/resources/static/files/web-eid-0.9.3.869.x64.msi | 3 +++ .../main/resources/static/files/web-eid_0.9.3.869_amd64.deb | 3 +++ 2 files changed, 6 insertions(+) create mode 100644 example/src/main/resources/static/files/web-eid-0.9.3.869.x64.msi create mode 100644 example/src/main/resources/static/files/web-eid_0.9.3.869_amd64.deb diff --git a/example/src/main/resources/static/files/web-eid-0.9.3.869.x64.msi b/example/src/main/resources/static/files/web-eid-0.9.3.869.x64.msi new file mode 100644 index 0000000..61af046 --- /dev/null +++ b/example/src/main/resources/static/files/web-eid-0.9.3.869.x64.msi @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2fd08ee1e391963cfbed560a0a264ff0b1dec49b51a2aa152990170e693e009b +size 18817024 diff --git a/example/src/main/resources/static/files/web-eid_0.9.3.869_amd64.deb b/example/src/main/resources/static/files/web-eid_0.9.3.869_amd64.deb new file mode 100644 index 0000000..1c9c408 --- /dev/null +++ b/example/src/main/resources/static/files/web-eid_0.9.3.869_amd64.deb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:45191ae3e12f69f457e74afd5b852104f4099adb7a6861b011ccbef671cd4eae +size 113064 From 05ac09e29eb1aad6f8c655d0c3a78c013066b827 Mon Sep 17 00:00:00 2001 From: Mart Somermaa Date: Fri, 19 Feb 2021 21:42:05 +0200 Subject: [PATCH 005/116] build(deps): use GitHub Packages for authtoken-validation, update Guava and DigiDoc4j --- example/pom.xml | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/example/pom.xml b/example/pom.xml index d8048c4..e1ffd9e 100644 --- a/example/pom.xml +++ b/example/pom.xml @@ -57,18 +57,18 @@ com.google.guava guava - 20.0 + 30.1-jre org.digidoc4j digidoc4j - 4.0.3 + 4.1.0 org.webeid.security authtoken-validation - 1.0.0-SNAPSHOT + 1.0.0 @@ -123,21 +123,11 @@ - gitlab-maven - https://gitlab.com/api/v4/projects/19948337/packages/maven + github + + https://mrts:ffc291fb68b3d53d4edd14c847edf939fb2a15c5@maven.pkg.github.com/web-eid/web-eid-authtoken-validation-java - - - gitlab-maven - https://gitlab.com/api/v4/projects/19948337/packages/maven - - - - gitlab-maven - https://gitlab.com/api/v4/projects/19948337/packages/maven - - - From 0aeafc085d46037b9e269387a1dc365b10db5a2f Mon Sep 17 00:00:00 2001 From: Mart Somermaa Date: Fri, 19 Feb 2021 21:46:32 +0200 Subject: [PATCH 006/116] feat: add configurable support for DigiDoc4j prod mode, enable OCSP check --- .../example/config/ValidationConfiguration.java | 2 -- .../org/webeid/example/config/YAMLConfig.java | 15 +++++++++++++-- .../webeid/example/service/SigningService.java | 7 ++++--- example/src/main/resources/application.yaml | 3 ++- example/src/test/resources/application.yaml | 12 ++++++++++++ 5 files changed, 31 insertions(+), 8 deletions(-) create mode 100644 example/src/test/resources/application.yaml diff --git a/example/src/main/java/org/webeid/example/config/ValidationConfiguration.java b/example/src/main/java/org/webeid/example/config/ValidationConfiguration.java index dc2ae7e..386a205 100644 --- a/example/src/main/java/org/webeid/example/config/ValidationConfiguration.java +++ b/example/src/main/java/org/webeid/example/config/ValidationConfiguration.java @@ -131,8 +131,6 @@ public AuthTokenValidator validator() { .withNonceCache(nonceCache()) .withTrustedCertificateAuthorities(trustedCertificateAuthorities()) .withTrustedCertificateAuthorities(initializeTrustedCACertificatesFromKeyStore()) - // FIXME: investigate why for Idemia test card OcspUtils.ocspUri() -> null so that "User certificate revocation check has failed: The CA/certificate doesn't have an OCSP responder" - .withoutUserCertificateRevocationCheckWithOcsp() .build(); } diff --git a/example/src/main/java/org/webeid/example/config/YAMLConfig.java b/example/src/main/java/org/webeid/example/config/YAMLConfig.java index d756101..7a56bc2 100644 --- a/example/src/main/java/org/webeid/example/config/YAMLConfig.java +++ b/example/src/main/java/org/webeid/example/config/YAMLConfig.java @@ -29,7 +29,7 @@ @Configuration @EnableConfigurationProperties -@ConfigurationProperties(prefix = "token.validation") +@ConfigurationProperties(prefix = "web-eid-auth-token.validation") public class YAMLConfig { private final String FINGERPRINT_PREFIX = "urn:cert:sha-256:"; @@ -41,6 +41,9 @@ public class YAMLConfig { @Value("keystore-password") private String keystorePassword; + @Value("#{new Boolean('${web-eid-auth-token.validation.use-digidoc4j-prod-configuration}'.trim())}") + private Boolean useDigiDoc4jProdConfiguration; + public String getLocalOrigin() { return localOrigin; } @@ -50,7 +53,7 @@ public void setLocalOrigin(String localOrigin) { } public String getFingerprint() { - if(fingerprint != null && !fingerprint.startsWith(FINGERPRINT_PREFIX)) { + if (fingerprint != null && !fingerprint.startsWith(FINGERPRINT_PREFIX)) { fingerprint = FINGERPRINT_PREFIX + fingerprint.replace(":", "").toLowerCase(); } return fingerprint; @@ -67,4 +70,12 @@ public String getKeystorePassword() { public void setKeystorePassword(String keystorePassword) { this.keystorePassword = keystorePassword; } + + public boolean getUseDigiDoc4jProdConfiguration() { + return useDigiDoc4jProdConfiguration; + } + + public void setUseDigiDoc4jProdConfiguration(boolean useDigiDoc4jProdConfiguration) { + this.useDigiDoc4jProdConfiguration = useDigiDoc4jProdConfiguration; + } } diff --git a/example/src/main/java/org/webeid/example/service/SigningService.java b/example/src/main/java/org/webeid/example/service/SigningService.java index e790204..b94043b 100644 --- a/example/src/main/java/org/webeid/example/service/SigningService.java +++ b/example/src/main/java/org/webeid/example/service/SigningService.java @@ -31,6 +31,7 @@ import org.springframework.beans.factory.ObjectFactory; import org.springframework.core.io.ByteArrayResource; import org.springframework.stereotype.Service; +import org.webeid.example.config.YAMLConfig; import org.webeid.example.service.dto.CertificateDTO; import org.webeid.example.service.dto.DigestDTO; import org.webeid.example.service.dto.FileDTO; @@ -59,9 +60,9 @@ public class SigningService { ObjectFactory httpSessionFactory; - public SigningService(ObjectFactory httpSessionFactory) { - // FIXME: use PROD conf + real OCSP (with IP whitelisting) - this.signingConfiguration = Configuration.of(Configuration.Mode.TEST); + public SigningService(ObjectFactory httpSessionFactory, YAMLConfig yamlConfig) { + this.signingConfiguration = Configuration.of(yamlConfig.getUseDigiDoc4jProdConfiguration() ? + Configuration.Mode.PROD : Configuration.Mode.TEST); this.httpSessionFactory = httpSessionFactory; } diff --git a/example/src/main/resources/application.yaml b/example/src/main/resources/application.yaml index ba1e78c..05e7b8e 100644 --- a/example/src/main/resources/application.yaml +++ b/example/src/main/resources/application.yaml @@ -4,8 +4,9 @@ spring: multipart: max-file-size: 5000KB max-request-size: 5000KB -token: +web-eid-auth-token: validation: + use-digidoc4j-prod-configuration: true local-origin: "https://web-eid.eu" fingerprint: "11:D8:AE:60:EC:19:10:C7:94:D7:4C:82:C8:0D:96:B2:07:88:B5:6A:D2:65:FF:F9:B5:14:C8:75:F7:90:08:E1" keystore-password: "changeit" diff --git a/example/src/test/resources/application.yaml b/example/src/test/resources/application.yaml new file mode 100644 index 0000000..d7155cb --- /dev/null +++ b/example/src/test/resources/application.yaml @@ -0,0 +1,12 @@ +spring: + profiles: dev + servlet: + multipart: + max-file-size: 5000KB + max-request-size: 5000KB +web-eid-auth-token: + validation: + use-digidoc4j-prod-configuration: false + local-origin: "https://528bc9f21520.ngrok.io" + fingerprint: "unused" + keystore-password: "changeit" From f8b878f8a68718d7145277cd3e6a148c8429423c Mon Sep 17 00:00:00 2001 From: Mart Somermaa Date: Fri, 19 Feb 2021 21:48:06 +0200 Subject: [PATCH 007/116] fix: mock OCSP checks with JMock to make testHappyFlow_LoginUploadPrepareSignDownload() pass --- example/.github/workflows/maven-build.yml | 27 ++++++++++++ .../org/webeid/example/DateMockingTest.java | 22 ++++++++++ .../webeid/example/WebApplicationTest.java | 41 ++++++++++++++---- .../webeid/example/testutil/FakeNonce.java | 36 --------------- .../certs/TEST_of_ESTEID-SK_2015.cer | Bin .../resources/certs/TEST_of_ESTEID2018.cer | Bin 6 files changed, 81 insertions(+), 45 deletions(-) create mode 100644 example/.github/workflows/maven-build.yml create mode 100644 example/src/test/java/org/webeid/example/DateMockingTest.java delete mode 100644 example/src/test/java/org/webeid/example/testutil/FakeNonce.java rename example/src/{main => test}/resources/certs/TEST_of_ESTEID-SK_2015.cer (100%) rename example/src/{main => test}/resources/certs/TEST_of_ESTEID2018.cer (100%) diff --git a/example/.github/workflows/maven-build.yml b/example/.github/workflows/maven-build.yml new file mode 100644 index 0000000..ae38343 --- /dev/null +++ b/example/.github/workflows/maven-build.yml @@ -0,0 +1,27 @@ +name: Maven build + +on: [ push, pull_request ] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - uses: actions/setup-java@v1 + with: + java-version: 1.8 + + - name: Cache Maven packages + uses: actions/cache@v1 + with: + path: ~/.m2 + key: ${{ runner.os }}-m2-v8-${{ hashFiles('**/pom.xml') }} + restore-keys: ${{ runner.os }}-m2-v8 + + - name: Build + run: mvn --batch-mode compile + + - name: Test and package + run: mvn --batch-mode package diff --git a/example/src/test/java/org/webeid/example/DateMockingTest.java b/example/src/test/java/org/webeid/example/DateMockingTest.java new file mode 100644 index 0000000..f8bcee6 --- /dev/null +++ b/example/src/test/java/org/webeid/example/DateMockingTest.java @@ -0,0 +1,22 @@ +package org.webeid.example; + +import org.junit.jupiter.api.Test; +import org.webeid.example.testutil.Dates; + +import java.text.ParseException; +import java.util.Date; + +import static org.assertj.core.api.Assertions.assertThat; + +public class DateMockingTest { + + @Test + void testDateMocking() throws ParseException { + final Date date = Dates.create("2020-04-14T13:36:49Z"); + Dates.setMockedDate(date); + + // Mocking native methods is unreliable, see https://github.com/jmockit/jmockit1/issues/689#issuecomment-702965484 + assertThat(System.currentTimeMillis()).isEqualTo(date.getTime()); + } + +} diff --git a/example/src/test/java/org/webeid/example/WebApplicationTest.java b/example/src/test/java/org/webeid/example/WebApplicationTest.java index b86e655..9d32d4b 100644 --- a/example/src/test/java/org/webeid/example/WebApplicationTest.java +++ b/example/src/test/java/org/webeid/example/WebApplicationTest.java @@ -22,9 +22,11 @@ package org.webeid.example; -import com.hazelcast.util.Base64; +import mockit.Mock; +import mockit.MockUp; +import org.digidoc4j.impl.asic.AsicSignatureFinalizer; +import org.digidoc4j.impl.asic.xades.XadesSignature; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @@ -37,11 +39,13 @@ import org.springframework.web.context.WebApplicationContext; import org.webeid.example.service.dto.DigestDTO; import org.webeid.example.testutil.Dates; -import org.webeid.example.testutil.FakeNonce; import org.webeid.example.testutil.HttpHelper; import org.webeid.example.testutil.ObjectMother; +import org.webeid.security.validator.AuthTokenValidatorData; +import org.webeid.security.validator.validators.SubjectCertificateNotRevokedValidator; -import java.nio.charset.StandardCharsets; +import javax.cache.Cache; +import java.time.LocalDateTime; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; @@ -49,13 +53,17 @@ @SpringBootTest @WebAppConfiguration public class WebApplicationTest { + + @Autowired + Cache cache; + @Autowired private WebApplicationContext context; @Autowired private javax.servlet.Filter[] springSecurityFilterChain; - private static final byte[] TEST_NONCE_BYTES = Base64.decode("a/wAFpMaXojLIaEmeOvviRNoBVqHBM/Mm9JV28ZcaIo=".getBytes(StandardCharsets.UTF_8)); + private static final String TEST_NONCE = "a/wAFpMaXojLIaEmeOvviRNoBVqHBM/Mm9JV28ZcaIo="; private static DefaultMockMvcBuilder mvcBuilder; @BeforeEach @@ -76,19 +84,35 @@ public void testRoot() throws Exception { System.out.println(response.getContentAsString()); } - @Disabled // FIXME: fix and enable @Test public void testHappyFlow_LoginUploadPrepareSignDownload() throws Exception { + // Arrange + new MockUp() { + @Mock + public void validateCertificateNotRevoked(AuthTokenValidatorData actualTokenData) { + // Do not call real OCSP service in tests. + } + }; + + new MockUp() { + @Mock + public void validateOcspResponse(XadesSignature xadesSignature) { + // Do not call real OCSP service in tests. + } + }; + + cache.put(TEST_NONCE, LocalDateTime.now().plusMinutes(5)); + final MockHttpSession session = new MockHttpSession(); - FakeNonce.setMockedNonce(TEST_NONCE_BYTES); Dates.setMockedDate(Dates.create("2020-04-14T13:36:49Z")); + // Act and assert mvcBuilder.build().perform(get("/auth/challenge")); MockHttpServletResponse response = HttpHelper.login(mvcBuilder, session, ObjectMother.mockAuthToken()); - assertEquals("{\"sub\":\"JÕEORG,JAAK-KRISTJAN,38001085718\",\"auth\":[\"ROLE_USER\"]}", response.getContentAsString()); + assertEquals("{\"sub\":\"JAAK-KRISTJAN JÕEORG, PNOEE-38001085718\",\"auth\":[\"ROLE_USER\"]}", response.getContentAsString()); response = HttpHelper.upload(mvcBuilder, session, ObjectMother.mockMultipartFile()); assertEquals(HttpStatus.OK.value(), response.getStatus()); @@ -96,7 +120,6 @@ public void testHappyFlow_LoginUploadPrepareSignDownload() throws Exception { response = HttpHelper.prepare(mvcBuilder, session, ObjectMother.mockPrepareRequest()); assertEquals(HttpStatus.OK.value(), response.getStatus()); - DigestDTO digestDTO = ObjectMother.jsonStringToBean(response.getContentAsString(), DigestDTO.class); response = HttpHelper.sign(mvcBuilder, session, ObjectMother.mockSignRequest(digestDTO.getHash())); diff --git a/example/src/test/java/org/webeid/example/testutil/FakeNonce.java b/example/src/test/java/org/webeid/example/testutil/FakeNonce.java deleted file mode 100644 index c923cb9..0000000 --- a/example/src/test/java/org/webeid/example/testutil/FakeNonce.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2020 The Web eID Project - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.webeid.example.testutil; - -public final class FakeNonce { - - public static void setMockedNonce(byte[] nonce) { - // FIXME: -// new MockUp() { -// @Mock -// public byte[] getNonceBytes() { -// return nonce; -// } -// }; - } -} diff --git a/example/src/main/resources/certs/TEST_of_ESTEID-SK_2015.cer b/example/src/test/resources/certs/TEST_of_ESTEID-SK_2015.cer similarity index 100% rename from example/src/main/resources/certs/TEST_of_ESTEID-SK_2015.cer rename to example/src/test/resources/certs/TEST_of_ESTEID-SK_2015.cer diff --git a/example/src/main/resources/certs/TEST_of_ESTEID2018.cer b/example/src/test/resources/certs/TEST_of_ESTEID2018.cer similarity index 100% rename from example/src/main/resources/certs/TEST_of_ESTEID2018.cer rename to example/src/test/resources/certs/TEST_of_ESTEID2018.cer From 7e7b93a7dc4b46e5266b931d979c2651b4d47294 Mon Sep 17 00:00:00 2001 From: Mart Somermaa Date: Mon, 22 Feb 2021 14:08:52 +0200 Subject: [PATCH 008/116] ci: use GitLab Package Repository instead of GitHub as GitHub Packages does not allow unauthorized read access --- example/pom.xml | 9 +++++--- .../org/webeid/example/DateMockingTest.java | 22 +++++++++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/example/pom.xml b/example/pom.xml index e1ffd9e..2f67efe 100644 --- a/example/pom.xml +++ b/example/pom.xml @@ -123,10 +123,13 @@ + gitlab + https://gitlab.com/api/v4/projects/19948337/packages/maven + - https://mrts:ffc291fb68b3d53d4edd14c847edf939fb2a15c5@maven.pkg.github.com/web-eid/web-eid-authtoken-validation-java + https://maven.pkg.github.com/web-eid/web-eid-authtoken-validation-java + --> diff --git a/example/src/test/java/org/webeid/example/DateMockingTest.java b/example/src/test/java/org/webeid/example/DateMockingTest.java index f8bcee6..8dfa6d0 100644 --- a/example/src/test/java/org/webeid/example/DateMockingTest.java +++ b/example/src/test/java/org/webeid/example/DateMockingTest.java @@ -1,3 +1,25 @@ +/* + * Copyright (c) 2020 The Web eID Project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + package org.webeid.example; import org.junit.jupiter.api.Test; From 836e1fd9e7ff2fb7b51a82864e5419d6e0e7410e Mon Sep 17 00:00:00 2001 From: Mart Somermaa Date: Mon, 22 Feb 2021 19:08:54 +0200 Subject: [PATCH 009/116] deployment: add Fabric deployment script, fix okhttp version --- example/pom.xml | 20 +++++++++++++------- example/scripts/deployment/.gitignore | 2 ++ example/scripts/deployment/README.md | 20 ++++++++++++++++++++ example/scripts/deployment/fab.sh | 11 +++++++++++ example/scripts/deployment/fabfile.py | 18 ++++++++++++++++++ example/scripts/deployment/requirements.txt | 1 + 6 files changed, 65 insertions(+), 7 deletions(-) create mode 100644 example/scripts/deployment/.gitignore create mode 100644 example/scripts/deployment/README.md create mode 100644 example/scripts/deployment/fab.sh create mode 100644 example/scripts/deployment/fabfile.py create mode 100644 example/scripts/deployment/requirements.txt diff --git a/example/pom.xml b/example/pom.xml index 2f67efe..eaf2854 100644 --- a/example/pom.xml +++ b/example/pom.xml @@ -23,6 +23,7 @@ + org.springframework.boot spring-boot-starter-web @@ -40,25 +41,30 @@ spring-security-config - - javax.cache - cache-api - 1.1.1 - com.hazelcast hazelcast - org.hibernate.validator hibernate-validator + + + javax.cache + cache-api + 1.1.1 + com.google.guava guava 30.1-jre + + com.squareup.okhttp3 + okhttp + 4.9.0 + org.digidoc4j @@ -93,13 +99,13 @@ spring-security-test test - org.jmockit jmockit ${jmockit.version} test + diff --git a/example/scripts/deployment/.gitignore b/example/scripts/deployment/.gitignore new file mode 100644 index 0000000..af2ecbd --- /dev/null +++ b/example/scripts/deployment/.gitignore @@ -0,0 +1,2 @@ +*.swp +venv/ diff --git a/example/scripts/deployment/README.md b/example/scripts/deployment/README.md new file mode 100644 index 0000000..333b1e2 --- /dev/null +++ b/example/scripts/deployment/README.md @@ -0,0 +1,20 @@ +## Deploy new version to web-eid.eu server + +In the local machine: + +1. Setup virtualenv and install [Fabric](https://www.fabfile.org/) + + python3 -m venv venv + . venv/bin/activate # . venv/Scripts/activate on Windows + pip install -r requirements.txt + +2. Check the project path, server hostname, user and port in `fab.sh` + +4. Verify that Fabric is able to connect to the server by running `uname` + + ./fab.sh uname + +7. Deploy the project + + ./fab.sh deploy + diff --git a/example/scripts/deployment/fab.sh b/example/scripts/deployment/fab.sh new file mode 100644 index 0000000..e58e1dd --- /dev/null +++ b/example/scripts/deployment/fab.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +set -eu + +SERVER_ADDRESS=server +SERVER_USER=user +SERVER_PORT=22 + +export WEBEID_DIR='/path/' + +fab -e -H ${SERVER_USER}@${SERVER_ADDRESS}:${SERVER_PORT} "$@" diff --git a/example/scripts/deployment/fabfile.py b/example/scripts/deployment/fabfile.py new file mode 100644 index 0000000..c4612a3 --- /dev/null +++ b/example/scripts/deployment/fabfile.py @@ -0,0 +1,18 @@ +import os + +from fabric import task + + +@task +def uname(c): + c.run('uname -a') + + +@task +def deploy(c): + with c.cd(os.getenv('WEBEID_DIR')): + c.run('git pull') + c.run('mvn clean package com.google.cloud.tools:jib-maven-plugin:dockerBuild') + c.run('docker-compose down') + c.run('docker-compose up -d') + diff --git a/example/scripts/deployment/requirements.txt b/example/scripts/deployment/requirements.txt new file mode 100644 index 0000000..50d35bb --- /dev/null +++ b/example/scripts/deployment/requirements.txt @@ -0,0 +1 @@ +fabric < 3 From 3d298ea395cf3bed66f198fe7a263cfd00a8581a Mon Sep 17 00:00:00 2001 From: Mart Somermaa Date: Mon, 22 Feb 2021 20:55:56 +0200 Subject: [PATCH 010/116] refactor: use Caffeine instead of Hazelcast --- example/pom.xml | 24 ++++++++++++------- .../config/ValidationConfiguration.java | 24 +++++++++++++++++-- 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/example/pom.xml b/example/pom.xml index eaf2854..a7f8064 100644 --- a/example/pom.xml +++ b/example/pom.xml @@ -19,11 +19,11 @@ 1.8 2.22.1 + 2.8.5 1.44 - org.springframework.boot spring-boot-starter-web @@ -32,6 +32,10 @@ org.springframework.boot spring-boot-starter-thymeleaf + + org.springframework.boot + spring-boot-starter-cache + org.springframework.boot spring-boot-starter-security @@ -42,19 +46,21 @@ - com.hazelcast - hazelcast + javax.cache + cache-api + 1.1.1 - org.hibernate.validator - hibernate-validator + com.github.ben-manes.caffeine + caffeine + ${caffeine.version} - - javax.cache - cache-api - 1.1.1 + com.github.ben-manes.caffeine + jcache + ${caffeine.version} + com.google.guava guava diff --git a/example/src/main/java/org/webeid/example/config/ValidationConfiguration.java b/example/src/main/java/org/webeid/example/config/ValidationConfiguration.java index 386a205..09782dc 100644 --- a/example/src/main/java/org/webeid/example/config/ValidationConfiguration.java +++ b/example/src/main/java/org/webeid/example/config/ValidationConfiguration.java @@ -22,6 +22,7 @@ package org.webeid.example.config; +import com.github.benmanes.caffeine.jcache.spi.CaffeineCachingProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Bean; @@ -38,6 +39,8 @@ import javax.cache.Caching; import javax.cache.configuration.CompleteConfiguration; import javax.cache.configuration.MutableConfiguration; +import javax.cache.expiry.CreatedExpiryPolicy; +import javax.cache.expiry.Duration; import java.io.IOException; import java.io.InputStream; import java.net.URI; @@ -51,12 +54,21 @@ import java.util.ArrayList; import java.util.Enumeration; import java.util.List; +import java.util.concurrent.TimeUnit; + +import static javax.cache.configuration.FactoryBuilder.factoryOf; @Configuration public class ValidationConfiguration { private static final Logger LOG = LoggerFactory.getLogger(ValidationConfiguration.class); private static final String CACHE_NAME = "nonceCache"; + private static final long NONCE_TTL_MINUTES = 5; + + @Bean + public CacheManager cacheManager() { + return Caching.getCachingProvider(CaffeineCachingProvider.class.getName()).getCacheManager(); + } @Bean public Cache nonceCache() { @@ -64,8 +76,7 @@ public Cache nonceCache() { Cache cache = cacheManager.getCache(CACHE_NAME); if (cache == null) { - CompleteConfiguration cacheConfig = new MutableConfiguration().setTypes(String.class, LocalDateTime.class); - cache = cacheManager.createCache(CACHE_NAME, cacheConfig); + cache = createNonceCache(cacheManager); } return cache; } @@ -73,6 +84,7 @@ public Cache nonceCache() { @Bean public NonceGenerator generator() { return new NonceGeneratorBuilder() + .withNonceTtl(java.time.Duration.ofMinutes(NONCE_TTL_MINUTES)) .withNonceCache(nonceCache()) .build(); } @@ -138,4 +150,12 @@ public AuthTokenValidator validator() { public YAMLConfig yamlConfig() { return new YAMLConfig(); } + + private Cache createNonceCache(CacheManager cacheManager) { + CompleteConfiguration cacheConfig = new MutableConfiguration() + .setTypes(String.class, LocalDateTime.class) + .setExpiryPolicyFactory(factoryOf(new CreatedExpiryPolicy( + new Duration(TimeUnit.MINUTES, NONCE_TTL_MINUTES + 1)))); + return cacheManager.createCache(CACHE_NAME, cacheConfig); + } } From 99ede256517b87958ee7026c54067e6b01e3a511 Mon Sep 17 00:00:00 2001 From: Mart Somermaa Date: Tue, 23 Feb 2021 22:55:34 +0200 Subject: [PATCH 011/116] docs,installer: update installer packages to 0.9.4.76, update instructions in index.html, remove obsolete Firefox extension files --- .../config/ValidationConfiguration.java | 2 +- .../firefox-web-eid-extension-updates.json | 12 ------- .../firefox/web-eid-webextension-0.9.1.xpi | Bin 78545 -> 0 bytes .../firefox/web-eid-webextension-latest.xpi | Bin 78545 -> 0 bytes .../static/files/web-eid-0.9.3.869.pkg | 3 -- .../static/files/web-eid-0.9.3.869.x64.msi | 3 -- .../static/files/web-eid-0.9.4.76.pkg | 3 ++ .../static/files/web-eid-0.9.4.76.x64.msi | 3 ++ .../static/files/web-eid_0.9.3.869_amd64.deb | 3 -- .../static/files/web-eid_0.9.4.76_amd64.deb | 3 ++ example/src/main/resources/static/index.html | 32 ++++-------------- 11 files changed, 17 insertions(+), 47 deletions(-) delete mode 100644 example/src/main/resources/static/files/firefox/firefox-web-eid-extension-updates.json delete mode 100644 example/src/main/resources/static/files/firefox/web-eid-webextension-0.9.1.xpi delete mode 100644 example/src/main/resources/static/files/firefox/web-eid-webextension-latest.xpi delete mode 100644 example/src/main/resources/static/files/web-eid-0.9.3.869.pkg delete mode 100644 example/src/main/resources/static/files/web-eid-0.9.3.869.x64.msi create mode 100644 example/src/main/resources/static/files/web-eid-0.9.4.76.pkg create mode 100644 example/src/main/resources/static/files/web-eid-0.9.4.76.x64.msi delete mode 100644 example/src/main/resources/static/files/web-eid_0.9.3.869_amd64.deb create mode 100644 example/src/main/resources/static/files/web-eid_0.9.4.76_amd64.deb diff --git a/example/src/main/java/org/webeid/example/config/ValidationConfiguration.java b/example/src/main/java/org/webeid/example/config/ValidationConfiguration.java index 09782dc..efb30ca 100644 --- a/example/src/main/java/org/webeid/example/config/ValidationConfiguration.java +++ b/example/src/main/java/org/webeid/example/config/ValidationConfiguration.java @@ -138,7 +138,7 @@ public X509Certificate[] initializeTrustedCACertificatesFromKeyStore() { public AuthTokenValidator validator() { return new AuthTokenValidatorBuilder() .withSiteOrigin(URI.create(yamlConfig().getLocalOrigin())) - // FIXME: decide what should validation library do when cert fingerprint validation is enabled but fingerprint is null (as in Chrome) + // TODO: it is still open what the validation library should do when cert fingerprint validation is enabled but fingerprint is null (as in Chrome). // .withSiteCertificateSha256Fingerprint(yamlConfig().getFingerprint()) .withNonceCache(nonceCache()) .withTrustedCertificateAuthorities(trustedCertificateAuthorities()) diff --git a/example/src/main/resources/static/files/firefox/firefox-web-eid-extension-updates.json b/example/src/main/resources/static/files/firefox/firefox-web-eid-extension-updates.json deleted file mode 100644 index 776d6ed..0000000 --- a/example/src/main/resources/static/files/firefox/firefox-web-eid-extension-updates.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "addons": { - "{89bcad3c-5c95-4a6c-a5a5-64da932f6bf7}": { - "updates": [ - { - "version": "0.9.1", - "update_link": "https://web-eid.eu/files/firefox/web-eid-webextension-0.9.1.xpi" - } - ] - } - } -} \ No newline at end of file diff --git a/example/src/main/resources/static/files/firefox/web-eid-webextension-0.9.1.xpi b/example/src/main/resources/static/files/firefox/web-eid-webextension-0.9.1.xpi deleted file mode 100644 index c52b40fd5fe649f036b7a704f8a5edd8c82c1285..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 78545 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 added as well, but it is not yet published):

    -
  1. Currently you need an Estonian eID test card for testing, and - the authentication and signing certificates of the test card must be uploaded to the - demo.sk.ee OCSP responder database. -
  2. - Download and install the Web eID native app: + Download and run the Web eID native app and browser extension installer:
      -
    • - for Ubuntu Linux 20.04 from here -
    • -
    • for macOS 10.13 or later from here
    • -
    • for Windows 10 from here.
    • +
    • for Ubuntu Linux 20.04 from here
    • +
    • for macOS 10.13 or later from here
    • +
    • for Windows 10 from here.
  3. - The installer will install the browser extension for Chrome and Edge automatically. - The extension must be manually enabled in Edge and may require manual enabling in Chrome - as well under certain circumstances. -
  4. -
  5. The installer will also install the browser extension for Firefox automatically in - Ubuntu Linux and macOS. In Windows, the Firefox browser extension has to be manually - installed: -
      -
    • download the extension from here -
    • -
    • in Firefox, open the Firefox menu and click Add-ons
    • -
    • from the settings cog, open Install Add-on From File
    • -
    • browse to and open the XPI file from the location where it was saved
    • -
    • When prompted click Add
    • -
    + The installer will install the browser extension for Chrome, Edge and Firefox automatically. + The extension must be manually enabled from the browser extensions management page + and may need browser restart under certain circumstances.
  6. Attach a smart card reader to the computer and insert the eID card into the reader. From 91baa012b36acec10ad42eaa0a39b1bc1c722062 Mon Sep 17 00:00:00 2001 From: Mart Somermaa Date: Tue, 23 Feb 2021 23:03:19 +0200 Subject: [PATCH 012/116] feat: use AIA OCSP and LT profile during signing, bump authtoken-validation to v1.0.1 Signed-off-by: Mart Somermaa --- example/pom.xml | 9 ++++++++- .../webeid/example/service/SigningService.java | 17 ++++++++++------- example/src/main/resources/static/index.html | 4 ++-- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/example/pom.xml b/example/pom.xml index a7f8064..2023ab8 100644 --- a/example/pom.xml +++ b/example/pom.xml @@ -20,6 +20,7 @@ 1.8 2.22.1 2.8.5 + 1.0.1 1.44 @@ -80,7 +81,7 @@ org.webeid.security authtoken-validation - 1.0.0 + ${webeid.version} @@ -137,6 +138,12 @@ gitlab https://gitlab.com/api/v4/projects/19948337/packages/maven + + true + + + true + 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 XZz9n9el{XBaPz`JLPBTs)j|IQPi<*H literal 0 HcmV?d00001 diff --git a/example/src/main/resources/static/index.html b/example/src/main/resources/static/index.html index 439d7b9..c060f41 100644 --- a/example/src/main/resources/static/index.html +++ b/example/src/main/resources/static/index.html @@ -43,31 +43,45 @@

    Table of contents


    Usage

    - Instructions for installing and testing in Firefox, Chrome or Edge (support for Safari has been already - added as well, but it is not yet published): + Instructions for installing and testing version 1.0.0-rc1 in Firefox, Chrome, Edge or Safari:

    1. Download and run the Web eID native app and browser extension installer:
        -
      • for Ubuntu Linux 20.04 from here, +
      • for Firefox and Chrome on Ubuntu Linux 20.04 from here, install it with either the Ubuntu Software Center or from the console with
        - sudo apt install ./web-eid_0.9.4.141_amd64.deb + sudo apt install ./web-eid_1.0.0.354_amd64.deb
      • -
      • for macOS 10.13 or later from here +
      • on macOS 10.15 or later, +
          +
        • + for Firefox from here, +
        • +
        • + for Chrome from here; +
        • +
        • + Safari extension is also available from here, + but it is not yet signed, so it is not currently possible to enable it; a signed + release will be available shortly. +
        • +
      • -
      • for Windows 10 from here. +
      • for Firefox, Chrome and Edge on Windows 10 (64-bit) from here.
    2. The installer will install the browser extension for all supported browsers automatically. The extension must be manually enabled from either the extension installation pop-up that appears in - the browser - or from the browser extensions management page and may need browser restart under certain + the browser or from the browser extensions management page and may need browser restart under + certain circumstances.
    3. @@ -84,6 +98,9 @@

      Usage

      +

      The privacy policy of the test service is available here. +

      +

      Uninstallation

      @@ -117,6 +134,21 @@

      Debugging and logs

      logs in the Console tab, put breakpoints in extension code in the Debugger tab and inspect extension network communication in the Network tab.
    4. +
    5. + To enable logging in the extension companion native app, +
        +
      • in Linux, run the following command in the console:
        + echo 'logging=true' > ~/.config/RIA/web-eid.conf +
      • +
      • in macOS, run the following command in the console:
        + defaults write eu.web-eid.web-eid logging true +
      • +
      • in Windows, add the following registry key:
        + [HKEY_LOCAL_MACHINE\SOFTWARE\RIA\web-eid]
        + "logging"="true" +
      • +
      +
    6. The native app logs are stored in
        From ca6b814d3a23c3d2900abb65f29c59e5864836e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=20S=C3=B5mermaa?= Date: Thu, 6 May 2021 14:47:58 +0300 Subject: [PATCH 026/116] doc: make OS name bold --- example/src/main/resources/static/index.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/example/src/main/resources/static/index.html b/example/src/main/resources/static/index.html index c060f41..f5aee18 100644 --- a/example/src/main/resources/static/index.html +++ b/example/src/main/resources/static/index.html @@ -49,12 +49,12 @@

        Usage

      • Download and run the Web eID native app and browser extension installer: From 6b8c9a711d114f23b11935818e46af478bc3909a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=20S=C3=B5mermaa?= Date: Mon, 10 May 2021 16:54:47 +0300 Subject: [PATCH 027/116] docs(index.html): add command for turning on Safari extension logging --- example/src/main/resources/static/index.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/example/src/main/resources/static/index.html b/example/src/main/resources/static/index.html index f5aee18..81091fa 100644 --- a/example/src/main/resources/static/index.html +++ b/example/src/main/resources/static/index.html @@ -141,7 +141,8 @@

        Debugging and logs

        echo 'logging=true' > ~/.config/RIA/web-eid.conf
      • in macOS, run the following command in the console:
        - defaults write eu.web-eid.web-eid logging true + defaults write eu.web-eid.web-eid logging true
        + defaults write eu.web-eid.web-eid-safari logging true
      • in Windows, add the following registry key:
        [HKEY_LOCAL_MACHINE\SOFTWARE\RIA\web-eid]
        From f7382a45e1d58231c39a2ecb494b60fbbe30751e Mon Sep 17 00:00:00 2001 From: Mart Somermaa Date: Tue, 1 Jun 2021 13:10:45 +0300 Subject: [PATCH 028/116] doc: HKEY_CURRENT_USER, not HKEY_LOCAL_MACHINE --- example/src/main/resources/static/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/src/main/resources/static/index.html b/example/src/main/resources/static/index.html index 81091fa..90352bb 100644 --- a/example/src/main/resources/static/index.html +++ b/example/src/main/resources/static/index.html @@ -145,7 +145,7 @@

        Debugging and logs

        defaults write eu.web-eid.web-eid-safari logging true
      • in Windows, add the following registry key:
        - [HKEY_LOCAL_MACHINE\SOFTWARE\RIA\web-eid]
        + [HKEY_CURRENT_USER\SOFTWARE\RIA\web-eid]
        "logging"="true"
      From 15d3992985179afccf96b6c4c90af456285e4e38 Mon Sep 17 00:00:00 2001 From: Mart Somermaa Date: Tue, 1 Jun 2021 13:51:32 +0300 Subject: [PATCH 029/116] doc: add link to project website --- example/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/example/README.md b/example/README.md index fdf3022..9b98191 100644 --- a/example/README.md +++ b/example/README.md @@ -5,6 +5,8 @@ Example Spring Boot web application that uses Web eID for strong authentication and digital signing with electronic ID smart cards. +More information about the Web eID project is available on the project [website](https://web-eid.eu/). + ## Setup Note that although the browser considers localhost to be a secure context, it does not have a certificate, From cfe7fe1cf23cd96a4df8a5c9441e310d903bbf28 Mon Sep 17 00:00:00 2001 From: Mart Somermaa Date: Fri, 11 Jun 2021 13:51:10 +0300 Subject: [PATCH 030/116] release(html): web-eid-app release 1.0.0-rc2 --- example/src/main/resources/static/index.html | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/example/src/main/resources/static/index.html b/example/src/main/resources/static/index.html index 90352bb..19c2de0 100644 --- a/example/src/main/resources/static/index.html +++ b/example/src/main/resources/static/index.html @@ -43,37 +43,37 @@

      Table of contents


      Usage

      - Instructions for installing and testing version 1.0.0-rc1 in Firefox, Chrome, Edge or Safari: + Instructions for installing and testing version 1.0.0-rc2 in Firefox, Chrome, Edge or Safari:

      1. Download and run the Web eID native app and browser extension installer:
        • on Ubuntu Linux 20.04, for Firefox and Chrome from here, + href="https://github.com/web-eid/web-eid-app/releases/download/1.0.0-rc2/web-eid_1.0.0.511_amd64.deb">here, install it with either the Ubuntu Software Center or from the console with
          - sudo apt install ./web-eid_1.0.0.354_amd64.deb + sudo apt install ./web-eid_1.0.0.511_amd64.deb
        • on macOS 10.15 or later,
          • for Firefox from here, + href="https://github.com/web-eid/web-eid-app/releases/download/1.0.0-rc2/web-eid-firefox_1.0.0.511.pkg">here,
          • for Chrome from here; + href="https://github.com/web-eid/web-eid-app/releases/download/1.0.0-rc2/web-eid-chrome_1.0.0.511.pkg">here;
          • Safari extension is also available from here, + href="https://github.com/web-eid/web-eid-app/releases/download/1.0.0-rc2/web-eid-safari_1.0.0.511.pkg">here, but it is not yet signed, so it is not currently possible to enable it; a signed release will be available shortly.
        • on Windows 10 (64-bit), for Firefox, Chrome and Edge from here. + href="https://github.com/web-eid/web-eid-app/releases/download/1.0.0-rc2/web-eid_1.0.0.511.x64.qt.msi">here.
      2. From 8a6b579db40a5c08fd465d2bba35d9e9d21b8237 Mon Sep 17 00:00:00 2001 From: Mart Somermaa Date: Mon, 12 Jul 2021 14:23:30 +0300 Subject: [PATCH 031/116] conf: forward HTTPS information from reverse proxy to Tomcat so that it can apply security settings --- example/src/main/resources/application.properties | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/example/src/main/resources/application.properties b/example/src/main/resources/application.properties index cbb42d2..d1c337f 100644 --- a/example/src/main/resources/application.properties +++ b/example/src/main/resources/application.properties @@ -1 +1,8 @@ spring.profiles.active=dev +# Make session cookie secure behind a reverse proxy, see +# - https://docs.spring.io/spring-boot/docs/2.2.5.RELEASE/reference/htmlsingle/#howto-use-behind-a-proxy-server +# - https://docs.spring.io/spring-boot/docs/2.2.5.RELEASE/reference/htmlsingle/#howto-enable-https +server.forward-headers-strategy=native +server.tomcat.remote-ip-header=x-forwarded-for +server.tomcat.protocol-header=x-forwarded-proto +# server.servlet.session.cookie.secure=true -- implicit when HTTPS is detected From 940e318827006c9cca5d537484af4a1e13d05779 Mon Sep 17 00:00:00 2001 From: Mart Somermaa Date: Tue, 13 Jul 2021 18:07:20 +0300 Subject: [PATCH 032/116] feat(config): add SameSite cookie configuration --- .../config/SameSiteCookieConfiguration.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 example/src/main/java/org/webeid/example/config/SameSiteCookieConfiguration.java diff --git a/example/src/main/java/org/webeid/example/config/SameSiteCookieConfiguration.java b/example/src/main/java/org/webeid/example/config/SameSiteCookieConfiguration.java new file mode 100644 index 0000000..2183a9f --- /dev/null +++ b/example/src/main/java/org/webeid/example/config/SameSiteCookieConfiguration.java @@ -0,0 +1,20 @@ +package org.webeid.example.config; + +import org.apache.tomcat.util.http.Rfc6265CookieProcessor; +import org.springframework.boot.web.embedded.tomcat.TomcatContextCustomizer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +public class SameSiteCookieConfiguration implements WebMvcConfigurer { + + @Bean + public TomcatContextCustomizer configureSameSiteCookies() { + return context -> { + final Rfc6265CookieProcessor cookieProcessor = new Rfc6265CookieProcessor(); + cookieProcessor.setSameSiteCookies("strict"); + context.setCookieProcessor(cookieProcessor); + }; + } +} From 27c2185b5c2b541a37a75c2ca92dd0d46fc42616 Mon Sep 17 00:00:00 2001 From: Mart Somermaa Date: Tue, 13 Jul 2021 18:19:51 +0300 Subject: [PATCH 033/116] doc: document HTTPS support --- example/README.md | 67 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 60 insertions(+), 7 deletions(-) diff --git a/example/README.md b/example/README.md index 9b98191..d775432 100644 --- a/example/README.md +++ b/example/README.md @@ -7,15 +7,68 @@ and digital signing with electronic ID smart cards. More information about the Web eID project is available on the project [website](https://web-eid.eu/). -## Setup +## HTTPS support -Note that although the browser considers localhost to be a secure context, it does not have a certificate, -therefore you need to use e.g. Ngrok.io for local testing. +There are two ways of adding HTTPS support to a Spring Boot application: -Download ngrok and run locally using two parameters: -```sh -ngrok http 8080 -``` +1. enable HTTPS support directly in the bundled Tomcat server by configuring + the `server.ssl.*` properties, + +2. use a reverse proxy server that handles TLS termination and communicates + with the Spring Boot application over a local HTTP socket. + +The first approach is straightforward and documented in the [official documentation](https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto.webserver.configure-ssl). + +The second approach, running behind a reverse proxy, is common in enterprise +deployments and the configuration is more involved. We assume this setup in the +current project and document it in this section. + +Enabling HTTPS support when running behind a reverse proxy server requires +configuration of both the proxy server and the Spring Boot application. + +The proxy server must pass the `Host:` line from the incoming request to the +proxied application and set the `X-Forwarded-*` headers to inform the +application that it runs behind a reverse proxy. Here is example configuration +for the Apache web server: + + + ProxyPreserveHost On + ProxyPass http://localhost:8380/ + ProxyPassReverse http://localhost:8380/ + RequestHeader set X-Forwarded-Proto https + RequestHeader set X-Forwarded-Port 443 + + +The Spring Boot application turns on proxied HTTPS support in the bundled +Tomcat web server automatically if it detects the presence of the +`X-Forwarded-*` headers and the following settings are configured in +`application.properties`: + + server.forward-headers-strategy=native + server.tomcat.remote-ip-header=x-forwarded-for + server.tomcat.protocol-header=x-forwarded-proto + +These settings are already enabled in the default +[`application.properties`](src/main/resources/application.properties). See +chapter +[9.3.12](https://docs.spring.io/spring-boot/docs/2.2.5.RELEASE/reference/htmlsingle/#howto-use-behind-a-proxy-server) +and +[9.14.3](https://docs.spring.io/spring-boot/docs/2.2.5.RELEASE/reference/htmlsingle/#howto-enable-https) +in the official documentation for further details. + +### How to verify that HTTPS is configured properly + +When HTTPS support is configured properly, all responses will have the HTTP +Strict Transport Security (HSTS) header and the `JSESSIONID` session cookie has +`Secure` attribute set. + +### Using a HTTPS proxy during development + +Use e.g. [_ngrok_](https://ngrok.com/) during development to get a reverse +proxy with a trusted HTTPS certificates. Download _ngrok_ and run it locally by +providing the protocol and Spring Boot application port as follows: + + ngrok http 8080 ## Configuration From d207c18e6e8005bcd37517b3fa00612c6428512b Mon Sep 17 00:00:00 2001 From: Mart Somermaa Date: Thu, 15 Jul 2021 12:37:10 +0300 Subject: [PATCH 034/116] css: load Bootstrap CSS from resources instead of CDN --- example/src/main/resources/static/css/bootstrap.min.css | 7 +++++++ example/src/main/resources/static/index.html | 3 +-- .../templates/welcome-with-file-upload-support.html | 3 +-- example/src/main/resources/templates/welcome.html | 3 +-- 4 files changed, 10 insertions(+), 6 deletions(-) create mode 100644 example/src/main/resources/static/css/bootstrap.min.css diff --git a/example/src/main/resources/static/css/bootstrap.min.css b/example/src/main/resources/static/css/bootstrap.min.css new file mode 100644 index 0000000..7d2a868 --- /dev/null +++ b/example/src/main/resources/static/css/bootstrap.min.css @@ -0,0 +1,7 @@ +/*! + * Bootstrap v4.5.0 (https://getbootstrap.com/) + * Copyright 2011-2020 The Bootstrap Authors + * Copyright 2011-2020 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */:root{--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#dc3545;--orange:#fd7e14;--yellow:#ffc107;--green:#28a745;--teal:#20c997;--cyan:#17a2b8;--white:#fff;--gray:#6c757d;--gray-dark:#343a40;--primary:#007bff;--secondary:#6c757d;--success:#28a745;--info:#17a2b8;--warning:#ffc107;--danger:#dc3545;--light:#f8f9fa;--dark:#343a40;--breakpoint-xs:0;--breakpoint-sm:576px;--breakpoint-md:768px;--breakpoint-lg:992px;--breakpoint-xl:1200px;--font-family-sans-serif:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus:not(:focus-visible){outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]){color:inherit;text-decoration:none}a:not([href]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;font-weight:500;line-height:1.2}.h1,h1{font-size:2.5rem}.h2,h2{font-size:2rem}.h3,h3{font-size:1.75rem}.h4,h4{font-size:1.5rem}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:6rem;font-weight:300;line-height:1.2}.display-2{font-size:5.5rem;font-weight:300;line-height:1.2}.display-3{font-size:4.5rem;font-weight:300;line-height:1.2}.display-4{font-size:3.5rem;font-weight:300;line-height:1.2}hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}.small,small{font-size:80%;font-weight:400}.mark,mark{padding:.2em;background-color:#fcf8e3}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote-footer{display:block;font-size:80%;color:#6c757d}.blockquote-footer::before{content:"\2014\00A0"}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:90%;color:#6c757d}code{font-size:87.5%;color:#e83e8c;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:87.5%;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;font-size:87.5%;color:#212529}pre code{font-size:inherit;color:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container{max-width:540px}}@media (min-width:768px){.container{max-width:720px}}@media (min-width:992px){.container{max-width:960px}}@media (min-width:1200px){.container{max-width:1140px}}.container-fluid,.container-lg,.container-md,.container-sm,.container-xl{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container,.container-sm{max-width:540px}}@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}.row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-auto,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{position:relative;width:100%;padding-right:15px;padding-left:15px}.col{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;min-width:0;max-width:100%}.row-cols-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-first{-ms-flex-order:-1;order:-1}.order-last{-ms-flex-order:13;order:13}.order-0{-ms-flex-order:0;order:0}.order-1{-ms-flex-order:1;order:1}.order-2{-ms-flex-order:2;order:2}.order-3{-ms-flex-order:3;order:3}.order-4{-ms-flex-order:4;order:4}.order-5{-ms-flex-order:5;order:5}.order-6{-ms-flex-order:6;order:6}.order-7{-ms-flex-order:7;order:7}.order-8{-ms-flex-order:8;order:8}.order-9{-ms-flex-order:9;order:9}.order-10{-ms-flex-order:10;order:10}.order-11{-ms-flex-order:11;order:11}.order-12{-ms-flex-order:12;order:12}.offset-1{margin-left:8.333333%}.offset-2{margin-left:16.666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.333333%}.offset-5{margin-left:41.666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.333333%}.offset-8{margin-left:66.666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.333333%}.offset-11{margin-left:91.666667%}@media (min-width:576px){.col-sm{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;min-width:0;max-width:100%}.row-cols-sm-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-sm-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-sm-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-sm-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-sm-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-sm-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-sm-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-sm-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-sm-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-sm-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-sm-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-sm-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-sm-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-sm-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-sm-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-sm-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-sm-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-sm-first{-ms-flex-order:-1;order:-1}.order-sm-last{-ms-flex-order:13;order:13}.order-sm-0{-ms-flex-order:0;order:0}.order-sm-1{-ms-flex-order:1;order:1}.order-sm-2{-ms-flex-order:2;order:2}.order-sm-3{-ms-flex-order:3;order:3}.order-sm-4{-ms-flex-order:4;order:4}.order-sm-5{-ms-flex-order:5;order:5}.order-sm-6{-ms-flex-order:6;order:6}.order-sm-7{-ms-flex-order:7;order:7}.order-sm-8{-ms-flex-order:8;order:8}.order-sm-9{-ms-flex-order:9;order:9}.order-sm-10{-ms-flex-order:10;order:10}.order-sm-11{-ms-flex-order:11;order:11}.order-sm-12{-ms-flex-order:12;order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.333333%}.offset-sm-2{margin-left:16.666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.333333%}.offset-sm-5{margin-left:41.666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.333333%}.offset-sm-8{margin-left:66.666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.333333%}.offset-sm-11{margin-left:91.666667%}}@media (min-width:768px){.col-md{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;min-width:0;max-width:100%}.row-cols-md-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-md-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-md-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-md-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-md-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-md-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-md-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-md-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-md-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-md-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-md-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-md-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-md-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-md-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-md-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-md-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-md-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-md-first{-ms-flex-order:-1;order:-1}.order-md-last{-ms-flex-order:13;order:13}.order-md-0{-ms-flex-order:0;order:0}.order-md-1{-ms-flex-order:1;order:1}.order-md-2{-ms-flex-order:2;order:2}.order-md-3{-ms-flex-order:3;order:3}.order-md-4{-ms-flex-order:4;order:4}.order-md-5{-ms-flex-order:5;order:5}.order-md-6{-ms-flex-order:6;order:6}.order-md-7{-ms-flex-order:7;order:7}.order-md-8{-ms-flex-order:8;order:8}.order-md-9{-ms-flex-order:9;order:9}.order-md-10{-ms-flex-order:10;order:10}.order-md-11{-ms-flex-order:11;order:11}.order-md-12{-ms-flex-order:12;order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.333333%}.offset-md-2{margin-left:16.666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.333333%}.offset-md-5{margin-left:41.666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.333333%}.offset-md-8{margin-left:66.666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.333333%}.offset-md-11{margin-left:91.666667%}}@media (min-width:992px){.col-lg{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;min-width:0;max-width:100%}.row-cols-lg-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-lg-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-lg-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-lg-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-lg-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-lg-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-lg-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-lg-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-lg-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-lg-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-lg-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-lg-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-lg-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-lg-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-lg-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-lg-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-lg-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-lg-first{-ms-flex-order:-1;order:-1}.order-lg-last{-ms-flex-order:13;order:13}.order-lg-0{-ms-flex-order:0;order:0}.order-lg-1{-ms-flex-order:1;order:1}.order-lg-2{-ms-flex-order:2;order:2}.order-lg-3{-ms-flex-order:3;order:3}.order-lg-4{-ms-flex-order:4;order:4}.order-lg-5{-ms-flex-order:5;order:5}.order-lg-6{-ms-flex-order:6;order:6}.order-lg-7{-ms-flex-order:7;order:7}.order-lg-8{-ms-flex-order:8;order:8}.order-lg-9{-ms-flex-order:9;order:9}.order-lg-10{-ms-flex-order:10;order:10}.order-lg-11{-ms-flex-order:11;order:11}.order-lg-12{-ms-flex-order:12;order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.333333%}.offset-lg-2{margin-left:16.666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.333333%}.offset-lg-5{margin-left:41.666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.333333%}.offset-lg-8{margin-left:66.666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.333333%}.offset-lg-11{margin-left:91.666667%}}@media (min-width:1200px){.col-xl{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;min-width:0;max-width:100%}.row-cols-xl-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-xl-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-xl-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-xl-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-xl-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-xl-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-xl-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-xl-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-xl-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-xl-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-xl-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-xl-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-xl-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-xl-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-xl-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-xl-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-xl-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-xl-first{-ms-flex-order:-1;order:-1}.order-xl-last{-ms-flex-order:13;order:13}.order-xl-0{-ms-flex-order:0;order:0}.order-xl-1{-ms-flex-order:1;order:1}.order-xl-2{-ms-flex-order:2;order:2}.order-xl-3{-ms-flex-order:3;order:3}.order-xl-4{-ms-flex-order:4;order:4}.order-xl-5{-ms-flex-order:5;order:5}.order-xl-6{-ms-flex-order:6;order:6}.order-xl-7{-ms-flex-order:7;order:7}.order-xl-8{-ms-flex-order:8;order:8}.order-xl-9{-ms-flex-order:9;order:9}.order-xl-10{-ms-flex-order:10;order:10}.order-xl-11{-ms-flex-order:11;order:11}.order-xl-12{-ms-flex-order:12;order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.333333%}.offset-xl-2{margin-left:16.666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.333333%}.offset-xl-5{margin-left:41.666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.333333%}.offset-xl-8{margin-left:66.666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.333333%}.offset-xl-11{margin-left:91.666667%}}.table{width:100%;margin-bottom:1rem;color:#212529}.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid #dee2e6}.table thead th{vertical-align:bottom;border-bottom:2px solid #dee2e6}.table tbody+tbody{border-top:2px solid #dee2e6}.table-sm td,.table-sm th{padding:.3rem}.table-bordered{border:1px solid #dee2e6}.table-bordered td,.table-bordered th{border:1px solid #dee2e6}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-borderless tbody+tbody,.table-borderless td,.table-borderless th,.table-borderless thead th{border:0}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,.05)}.table-hover tbody tr:hover{color:#212529;background-color:rgba(0,0,0,.075)}.table-primary,.table-primary>td,.table-primary>th{background-color:#b8daff}.table-primary tbody+tbody,.table-primary td,.table-primary th,.table-primary thead th{border-color:#7abaff}.table-hover .table-primary:hover{background-color:#9fcdff}.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#9fcdff}.table-secondary,.table-secondary>td,.table-secondary>th{background-color:#d6d8db}.table-secondary tbody+tbody,.table-secondary td,.table-secondary th,.table-secondary thead th{border-color:#b3b7bb}.table-hover .table-secondary:hover{background-color:#c8cbcf}.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#c8cbcf}.table-success,.table-success>td,.table-success>th{background-color:#c3e6cb}.table-success tbody+tbody,.table-success td,.table-success th,.table-success thead th{border-color:#8fd19e}.table-hover .table-success:hover{background-color:#b1dfbb}.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#b1dfbb}.table-info,.table-info>td,.table-info>th{background-color:#bee5eb}.table-info tbody+tbody,.table-info td,.table-info th,.table-info thead th{border-color:#86cfda}.table-hover .table-info:hover{background-color:#abdde5}.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#abdde5}.table-warning,.table-warning>td,.table-warning>th{background-color:#ffeeba}.table-warning tbody+tbody,.table-warning td,.table-warning th,.table-warning thead th{border-color:#ffdf7e}.table-hover .table-warning:hover{background-color:#ffe8a1}.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#ffe8a1}.table-danger,.table-danger>td,.table-danger>th{background-color:#f5c6cb}.table-danger tbody+tbody,.table-danger td,.table-danger th,.table-danger thead th{border-color:#ed969e}.table-hover .table-danger:hover{background-color:#f1b0b7}.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f1b0b7}.table-light,.table-light>td,.table-light>th{background-color:#fdfdfe}.table-light tbody+tbody,.table-light td,.table-light th,.table-light thead th{border-color:#fbfcfc}.table-hover .table-light:hover{background-color:#ececf6}.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#ececf6}.table-dark,.table-dark>td,.table-dark>th{background-color:#c6c8ca}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#95999c}.table-hover .table-dark:hover{background-color:#b9bbbe}.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#b9bbbe}.table-active,.table-active>td,.table-active>th{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,.075)}.table .thead-dark th{color:#fff;background-color:#343a40;border-color:#454d55}.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:#dee2e6}.table-dark{color:#fff;background-color:#343a40}.table-dark td,.table-dark th,.table-dark thead th{border-color:#454d55}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:rgba(255,255,255,.05)}.table-dark.table-hover tbody tr:hover{color:#fff;background-color:rgba(255,255,255,.075)}@media (max-width:575.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-sm>.table-bordered{border:0}}@media (max-width:767.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-md>.table-bordered{border:0}}@media (max-width:991.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-lg>.table-bordered{border:0}}@media (max-width:1199.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive>.table-bordered{border:0}.form-control{display:block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}.form-control:focus{color:#495057;background-color:#fff;border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.form-control::-webkit-input-placeholder{color:#6c757d;opacity:1}.form-control::-moz-placeholder{color:#6c757d;opacity:1}.form-control:-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}input[type=date].form-control,input[type=datetime-local].form-control,input[type=month].form-control,input[type=time].form-control{-webkit-appearance:none;-moz-appearance:none;appearance:none}select.form-control:focus::-ms-value{color:#495057;background-color:#fff}.form-control-file,.form-control-range{display:block;width:100%}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem;line-height:1.5}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem;line-height:1.5}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;font-size:1rem;line-height:1.5;color:#212529;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.form-control-lg{height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}select.form-control[multiple],select.form-control[size]{height:auto}textarea.form-control{height:auto}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.form-row>.col,.form-row>[class*=col-]{padding-right:5px;padding-left:5px}.form-check{position:relative;display:block;padding-left:1.25rem}.form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{color:#6c757d}.form-check-label{margin-bottom:0}.form-check-inline{display:-ms-inline-flexbox;display:inline-flex;-ms-flex-align:center;align-items:center;padding-left:0;margin-right:.75rem}.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#28a745}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(40,167,69,.9);border-radius:.25rem}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{border-color:#28a745;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-valid,.was-validated .custom-select:valid{border-color:#28a745;padding-right:calc(.75em + 2.3125rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e") #fff no-repeat center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}.custom-select.is-valid:focus,.was-validated .custom-select:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#28a745}.form-check-input.is-valid~.valid-feedback,.form-check-input.is-valid~.valid-tooltip,.was-validated .form-check-input:valid~.valid-feedback,.was-validated .form-check-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid~.custom-control-label,.was-validated .custom-control-input:valid~.custom-control-label{color:#28a745}.custom-control-input.is-valid~.custom-control-label::before,.was-validated .custom-control-input:valid~.custom-control-label::before{border-color:#28a745}.custom-control-input.is-valid:checked~.custom-control-label::before,.was-validated .custom-control-input:valid:checked~.custom-control-label::before{border-color:#34ce57;background-color:#34ce57}.custom-control-input.is-valid:focus~.custom-control-label::before,.was-validated .custom-control-input:valid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.custom-control-input.is-valid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:valid:focus:not(:checked)~.custom-control-label::before{border-color:#28a745}.custom-file-input.is-valid~.custom-file-label,.was-validated .custom-file-input:valid~.custom-file-label{border-color:#28a745}.custom-file-input.is-valid:focus~.custom-file-label,.was-validated .custom-file-input:valid:focus~.custom-file-label{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#dc3545}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(220,53,69,.9);border-radius:.25rem}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:#dc3545;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-invalid,.was-validated .custom-select:invalid{border-color:#dc3545;padding-right:calc(.75em + 2.3125rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e") #fff no-repeat center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}.custom-select.is-invalid:focus,.was-validated .custom-select:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#dc3545}.form-check-input.is-invalid~.invalid-feedback,.form-check-input.is-invalid~.invalid-tooltip,.was-validated .form-check-input:invalid~.invalid-feedback,.was-validated .form-check-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid~.custom-control-label,.was-validated .custom-control-input:invalid~.custom-control-label{color:#dc3545}.custom-control-input.is-invalid~.custom-control-label::before,.was-validated .custom-control-input:invalid~.custom-control-label::before{border-color:#dc3545}.custom-control-input.is-invalid:checked~.custom-control-label::before,.was-validated .custom-control-input:invalid:checked~.custom-control-label::before{border-color:#e4606d;background-color:#e4606d}.custom-control-input.is-invalid:focus~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.custom-control-input.is-invalid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus:not(:checked)~.custom-control-label::before{border-color:#dc3545}.custom-file-input.is-invalid~.custom-file-label,.was-validated .custom-file-input:invalid~.custom-file-label{border-color:#dc3545}.custom-file-input.is-invalid:focus~.custom-file-label,.was-validated .custom-file-input:invalid:focus~.custom-file-label{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-inline{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center}.form-inline .form-check{width:100%}@media (min-width:576px){.form-inline label{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:-ms-flexbox;display:flex;-ms-flex:0 0 auto;flex:0 0 auto;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .custom-select,.form-inline .input-group{width:auto}.form-inline .form-check{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;-ms-flex-negative:0;flex-shrink:0;margin-top:0;margin-right:.25rem;margin-left:0}.form-inline .custom-control{-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.btn{display:inline-block;font-weight:400;color:#212529;text-align:center;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:#212529;text-decoration:none}.btn.focus,.btn:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.btn.disabled,.btn:disabled{opacity:.65}.btn:not(:disabled):not(.disabled){cursor:pointer}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:hover{color:#fff;background-color:#0069d9;border-color:#0062cc}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#0069d9;border-color:#0062cc;box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:not(:disabled):not(.disabled).active,.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#0062cc;border-color:#005cbf}.btn-primary:not(:disabled):not(.disabled).active:focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:hover{color:#fff;background-color:#5a6268;border-color:#545b62}.btn-secondary.focus,.btn-secondary:focus{color:#fff;background-color:#5a6268;border-color:#545b62;box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:not(:disabled):not(.disabled).active,.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b}.btn-secondary:not(:disabled):not(.disabled).active:focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-success{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#218838;border-color:#1e7e34;box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:not(:disabled):not(.disabled).active,.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}.btn-success:not(:disabled):not(.disabled).active:focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#138496;border-color:#117a8b;box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:not(:disabled):not(.disabled).active,.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f}.btn-info:not(:disabled):not(.disabled).active:focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-warning{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:hover{color:#212529;background-color:#e0a800;border-color:#d39e00}.btn-warning.focus,.btn-warning:focus{color:#212529;background-color:#e0a800;border-color:#d39e00;box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{color:#212529;background-color:#d39e00;border-color:#c69500}.btn-warning:not(:disabled):not(.disabled).active:focus,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:hover{color:#fff;background-color:#c82333;border-color:#bd2130}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c82333;border-color:#bd2130;box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:not(:disabled):not(.disabled).active,.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#bd2130;border-color:#b21f2d}.btn-danger:not(:disabled):not(.disabled).active:focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}.btn-light.focus,.btn-light:focus{color:#212529;background-color:#e2e6ea;border-color:#dae0e5;box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-light.disabled,.btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}.btn-light:not(:disabled):not(.disabled).active:focus,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-dark{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124}.btn-dark.focus,.btn-dark:focus{color:#fff;background-color:#23272b;border-color:#1d2124;box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:not(:disabled):not(.disabled).active,.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}.btn-dark:not(:disabled):not(.disabled).active:focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-outline-primary{color:#007bff;border-color:#007bff}.btn-outline-primary:hover{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#007bff;background-color:transparent}.btn-outline-primary:not(:disabled):not(.disabled).active,.btn-outline-primary:not(:disabled):not(.disabled):active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-secondary{color:#6c757d;border-color:#6c757d}.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}.btn-outline-secondary:not(:disabled):not(.disabled).active,.btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-success{color:#28a745;border-color:#28a745}.btn-outline-success:hover{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#28a745;background-color:transparent}.btn-outline-success:not(:disabled):not(.disabled).active,.btn-outline-success:not(:disabled):not(.disabled):active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success:not(:disabled):not(.disabled).active:focus,.btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-info{color:#17a2b8;border-color:#17a2b8}.btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#17a2b8;background-color:transparent}.btn-outline-info:not(:disabled):not(.disabled).active,.btn-outline-info:not(:disabled):not(.disabled):active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info:not(:disabled):not(.disabled).active:focus,.btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-warning{color:#ffc107;border-color:#ffc107}.btn-outline-warning:hover{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.btn-outline-warning:not(:disabled):not(.disabled).active,.btn-outline-warning:not(:disabled):not(.disabled):active,.show>.btn-outline-warning.dropdown-toggle{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-danger{color:#dc3545;border-color:#dc3545}.btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.btn-outline-danger:not(:disabled):not(.disabled).active,.btn-outline-danger:not(:disabled):not(.disabled):active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-light{color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-light:not(:disabled):not(.disabled).active,.btn-outline-light:not(:disabled):not(.disabled):active,.show>.btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:not(:disabled):not(.disabled).active:focus,.btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-dark{color:#343a40;border-color:#343a40}.btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark.focus,.btn-outline-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#343a40;background-color:transparent}.btn-outline-dark:not(:disabled):not(.disabled).active,.btn-outline-dark:not(:disabled):not(.disabled):active,.show>.btn-outline-dark.dropdown-toggle{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-link{font-weight:400;color:#007bff;text-decoration:none}.btn-link:hover{color:#0056b3;text-decoration:underline}.btn-link.focus,.btn-link:focus{text-decoration:underline}.btn-link.disabled,.btn-link:disabled{color:#6c757d;pointer-events:none}.btn-group-lg>.btn,.btn-lg{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.dropdown,.dropleft,.dropright,.dropup{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.dropdown-menu-left{right:auto;left:0}.dropdown-menu-right{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-left{right:auto;left:0}.dropdown-menu-sm-right{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-left{right:auto;left:0}.dropdown-menu-md-right{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-left{right:auto;left:0}.dropdown-menu-lg-right{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-left{right:auto;left:0}.dropdown-menu-xl-right{right:0;left:auto}}.dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropright .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropright .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-toggle::after{vertical-align:0}.dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropleft .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropleft .dropdown-toggle::after{display:none}.dropleft .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropleft .dropdown-toggle:empty::after{margin-left:0}.dropleft .dropdown-toggle::before{vertical-align:0}.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=top]{right:auto;bottom:auto}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#16181b;text-decoration:none;background-color:#f8f9fa}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#007bff}.dropdown-item.disabled,.dropdown-item:disabled{color:#6c757d;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1.5rem;color:#212529}.btn-group,.btn-group-vertical{position:relative;display:-ms-inline-flexbox;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;-ms-flex:1 1 auto;flex:1 1 auto}.btn-group-vertical>.btn:hover,.btn-group>.btn:hover{z-index:1}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus{z-index:1}.btn-toolbar{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-pack:start;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn-group:not(:first-child),.btn-group>.btn:not(:first-child){margin-left:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropright .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropleft .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{-ms-flex-direction:column;flex-direction:column;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:center;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn{margin-bottom:0}.btn-group-toggle>.btn input[type=checkbox],.btn-group-toggle>.btn input[type=radio],.btn-group-toggle>.btn-group>.btn input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:stretch;align-items:stretch;width:100%}.input-group>.custom-file,.input-group>.custom-select,.input-group>.form-control,.input-group>.form-control-plaintext{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;width:1%;min-width:0;margin-bottom:0}.input-group>.custom-file+.custom-file,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.form-control,.input-group>.custom-select+.custom-file,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.form-control,.input-group>.form-control+.custom-file,.input-group>.form-control+.custom-select,.input-group>.form-control+.form-control,.input-group>.form-control-plaintext+.custom-file,.input-group>.form-control-plaintext+.custom-select,.input-group>.form-control-plaintext+.form-control{margin-left:-1px}.input-group>.custom-file .custom-file-input:focus~.custom-file-label,.input-group>.custom-select:focus,.input-group>.form-control:focus{z-index:3}.input-group>.custom-file .custom-file-input:focus{z-index:4}.input-group>.custom-select:not(:last-child),.input-group>.form-control:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-select:not(:first-child),.input-group>.form-control:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.custom-file{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}.input-group>.custom-file:not(:last-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label::after{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-file:not(:first-child) .custom-file-label{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-append,.input-group-prepend{display:-ms-flexbox;display:flex}.input-group-append .btn,.input-group-prepend .btn{position:relative;z-index:2}.input-group-append .btn:focus,.input-group-prepend .btn:focus{z-index:3}.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.btn,.input-group-append .input-group-text+.input-group-text,.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-prepend .input-group-text+.input-group-text{margin-left:-1px}.input-group-prepend{margin-right:-1px}.input-group-append{margin-left:-1px}.input-group-text{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.input-group-text input[type=checkbox],.input-group-text input[type=radio]{margin-top:0}.input-group-lg>.custom-select,.input-group-lg>.form-control:not(textarea){height:calc(1.5em + 1rem + 2px)}.input-group-lg>.custom-select,.input-group-lg>.form-control,.input-group-lg>.input-group-append>.btn,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-prepend>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.input-group-sm>.custom-select,.input-group-sm>.form-control:not(textarea){height:calc(1.5em + .5rem + 2px)}.input-group-sm>.custom-select,.input-group-sm>.form-control,.input-group-sm>.input-group-append>.btn,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-prepend>.input-group-text{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.input-group-lg>.custom-select,.input-group-sm>.custom-select{padding-right:1.75rem}.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),.input-group>.input-group-append:not(:last-child)>.btn,.input-group>.input-group-append:not(:last-child)>.input-group-text,.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-top-left-radius:0;border-bottom-left-radius:0}.custom-control{position:relative;display:block;min-height:1.5rem;padding-left:1.5rem}.custom-control-inline{display:-ms-inline-flexbox;display:inline-flex;margin-right:1rem}.custom-control-input{position:absolute;left:0;z-index:-1;width:1rem;height:1.25rem;opacity:0}.custom-control-input:checked~.custom-control-label::before{color:#fff;border-color:#007bff;background-color:#007bff}.custom-control-input:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-control-input:focus:not(:checked)~.custom-control-label::before{border-color:#80bdff}.custom-control-input:not(:disabled):active~.custom-control-label::before{color:#fff;background-color:#b3d7ff;border-color:#b3d7ff}.custom-control-input:disabled~.custom-control-label,.custom-control-input[disabled]~.custom-control-label{color:#6c757d}.custom-control-input:disabled~.custom-control-label::before,.custom-control-input[disabled]~.custom-control-label::before{background-color:#e9ecef}.custom-control-label{position:relative;margin-bottom:0;vertical-align:top}.custom-control-label::before{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;pointer-events:none;content:"";background-color:#fff;border:#adb5bd solid 1px}.custom-control-label::after{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;content:"";background:no-repeat 50%/50% 50%}.custom-checkbox .custom-control-label::before{border-radius:.25rem}.custom-checkbox .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before{border-color:#007bff;background-color:#007bff}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-radio .custom-control-label::before{border-radius:50%}.custom-radio .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.custom-radio .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-switch{padding-left:2.25rem}.custom-switch .custom-control-label::before{left:-2.25rem;width:1.75rem;pointer-events:all;border-radius:.5rem}.custom-switch .custom-control-label::after{top:calc(.25rem + 2px);left:calc(-2.25rem + 2px);width:calc(1rem - 4px);height:calc(1rem - 4px);background-color:#adb5bd;border-radius:.5rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-transform .15s ease-in-out;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-transform .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-switch .custom-control-label::after{transition:none}}.custom-switch .custom-control-input:checked~.custom-control-label::after{background-color:#fff;-webkit-transform:translateX(.75rem);transform:translateX(.75rem)}.custom-switch .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-select{display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem 1.75rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;vertical-align:middle;background:#fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px;border:1px solid #ced4da;border-radius:.25rem;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-select:focus{border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-select:focus::-ms-value{color:#495057;background-color:#fff}.custom-select[multiple],.custom-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none}.custom-select:disabled{color:#6c757d;background-color:#e9ecef}.custom-select::-ms-expand{display:none}.custom-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}.custom-select-sm{height:calc(1.5em + .5rem + 2px);padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem}.custom-select-lg{height:calc(1.5em + 1rem + 2px);padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem}.custom-file{position:relative;display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);margin-bottom:0}.custom-file-input{position:relative;z-index:2;width:100%;height:calc(1.5em + .75rem + 2px);margin:0;opacity:0}.custom-file-input:focus~.custom-file-label{border-color:#80bdff;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-file-input:disabled~.custom-file-label,.custom-file-input[disabled]~.custom-file-label{background-color:#e9ecef}.custom-file-input:lang(en)~.custom-file-label::after{content:"Browse"}.custom-file-input~.custom-file-label[data-browse]::after{content:attr(data-browse)}.custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem}.custom-file-label::after{position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:calc(1.5em + .75rem);padding:.375rem .75rem;line-height:1.5;color:#495057;content:"Browse";background-color:#e9ecef;border-left:inherit;border-radius:0 .25rem .25rem 0}.custom-range{width:100%;height:1.4rem;padding:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-range:focus{outline:0}.custom-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range::-moz-focus-outer{border:0}.custom-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#007bff;border:0;border-radius:1rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.custom-range::-webkit-slider-thumb:active{background-color:#b3d7ff}.custom-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#007bff;border:0;border-radius:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-moz-range-thumb{-moz-transition:none;transition:none}}.custom-range::-moz-range-thumb:active{background-color:#b3d7ff}.custom-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-ms-thumb{width:1rem;height:1rem;margin-top:0;margin-right:.2rem;margin-left:.2rem;background-color:#007bff;border:0;border-radius:1rem;-ms-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-ms-thumb{-ms-transition:none;transition:none}}.custom-range::-ms-thumb:active{background-color:#b3d7ff}.custom-range::-ms-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:transparent;border-color:transparent;border-width:.5rem}.custom-range::-ms-fill-lower{background-color:#dee2e6;border-radius:1rem}.custom-range::-ms-fill-upper{margin-right:15px;background-color:#dee2e6;border-radius:1rem}.custom-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.custom-range:disabled::-webkit-slider-runnable-track{cursor:default}.custom-range:disabled::-moz-range-thumb{background-color:#adb5bd}.custom-range:disabled::-moz-range-track{cursor:default}.custom-range:disabled::-ms-thumb{background-color:#adb5bd}.custom-control-label::before,.custom-file-label,.custom-select{transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-control-label::before,.custom-file-label,.custom-select{transition:none}}.nav{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#6c757d;pointer-events:none;cursor:default}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-item{margin-bottom:-1px}.nav-tabs .nav-link{border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#007bff}.nav-fill .nav-item{-ms-flex:1 1 auto;flex:1 1 auto;text-align:center}.nav-justified .nav-item{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;padding:.5rem 1rem}.navbar .container,.navbar .container-fluid,.navbar .container-lg,.navbar .container-md,.navbar .container-sm,.navbar .container-xl{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between}.navbar-brand{display:inline-block;padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;line-height:inherit;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-nav{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static;float:none}.navbar-text{display:inline-block;padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{-ms-flex-preferred-size:100%;flex-basis:100%;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem}.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:"";background:no-repeat center center;background-size:100% 100%}@media (max-width:575.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{padding-right:0;padding-left:0}}@media (min-width:576px){.navbar-expand-sm{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-sm .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-sm .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media (max-width:767.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{padding-right:0;padding-left:0}}@media (min-width:768px){.navbar-expand-md{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-md .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-md .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}}@media (max-width:991.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{padding-right:0;padding-left:0}}@media (min-width:992px){.navbar-expand-lg{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-lg .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-lg .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}}@media (max-width:1199.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{padding-right:0;padding-left:0}}@media (min-width:1200px){.navbar-expand-xl{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-xl .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-xl .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}}.navbar-expand{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{padding-right:0;padding-left:0}.navbar-expand .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand{color:rgba(0,0,0,.9)}.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.5)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .show>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.5);border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-light .navbar-text{color:rgba(0,0,0,.5)}.navbar-light .navbar-text a{color:rgba(0,0,0,.9)}.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand{color:#fff}.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,.5)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:rgba(255,255,255,.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,.25)}.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:rgba(255,255,255,.5);border-color:rgba(255,255,255,.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-dark .navbar-text{color:rgba(255,255,255,.5)}.navbar-dark .navbar-text a{color:#fff}.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-body{-ms-flex:1 1 auto;flex:1 1 auto;min-height:1px;padding:1.25rem}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.75rem 1.25rem;margin-bottom:0;background-color:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-header+.list-group .list-group-item:first-child{border-top:0}.card-footer{padding:.75rem 1.25rem;background-color:rgba(0,0,0,.03);border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-right:-.625rem;margin-bottom:-.75rem;margin-left:-.625rem;border-bottom:0}.card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem}.card-img,.card-img-bottom,.card-img-top{-ms-flex-negative:0;flex-shrink:0;width:100%}.card-img,.card-img-top{border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img,.card-img-bottom{border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-deck .card{margin-bottom:15px}@media (min-width:576px){.card-deck{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;margin-right:-15px;margin-left:-15px}.card-deck .card{-ms-flex:1 0 0%;flex:1 0 0%;margin-right:15px;margin-bottom:0;margin-left:15px}}.card-group>.card{margin-bottom:15px}@media (min-width:576px){.card-group{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap}.card-group>.card{-ms-flex:1 0 0%;flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.card-columns .card{margin-bottom:.75rem}@media (min-width:576px){.card-columns{-webkit-column-count:3;-moz-column-count:3;column-count:3;-webkit-column-gap:1.25rem;-moz-column-gap:1.25rem;column-gap:1.25rem;orphans:1;widows:1}.card-columns .card{display:inline-block;width:100%}}.accordion>.card{overflow:hidden}.accordion>.card:not(:last-of-type){border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion>.card:not(:first-of-type){border-top-left-radius:0;border-top-right-radius:0}.accordion>.card>.card-header{border-radius:0;margin-bottom:-1px}.breadcrumb{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:.25rem}.breadcrumb-item{display:-ms-flexbox;display:flex}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{display:inline-block;padding-right:.5rem;color:#6c757d;content:"/"}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:underline}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:none}.breadcrumb-item.active{color:#6c757d}.pagination{display:-ms-flexbox;display:flex;padding-left:0;list-style:none;border-radius:.25rem}.page-link{position:relative;display:block;padding:.5rem .75rem;margin-left:-1px;line-height:1.25;color:#007bff;background-color:#fff;border:1px solid #dee2e6}.page-link:hover{z-index:2;color:#0056b3;text-decoration:none;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:3;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.page-item:first-child .page-link{margin-left:0;border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-item.active .page-link{z-index:3;color:#fff;background-color:#007bff;border-color:#007bff}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;cursor:auto;background-color:#fff;border-color:#dee2e6}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem;line-height:1.5}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.875rem;line-height:1.5}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.badge{transition:none}}a.badge:focus,a.badge:hover{text-decoration:none}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-primary{color:#fff;background-color:#007bff}a.badge-primary:focus,a.badge-primary:hover{color:#fff;background-color:#0062cc}a.badge-primary.focus,a.badge-primary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.badge-secondary{color:#fff;background-color:#6c757d}a.badge-secondary:focus,a.badge-secondary:hover{color:#fff;background-color:#545b62}a.badge-secondary.focus,a.badge-secondary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.badge-success{color:#fff;background-color:#28a745}a.badge-success:focus,a.badge-success:hover{color:#fff;background-color:#1e7e34}a.badge-success.focus,a.badge-success:focus{outline:0;box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.badge-info{color:#fff;background-color:#17a2b8}a.badge-info:focus,a.badge-info:hover{color:#fff;background-color:#117a8b}a.badge-info.focus,a.badge-info:focus{outline:0;box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.badge-warning{color:#212529;background-color:#ffc107}a.badge-warning:focus,a.badge-warning:hover{color:#212529;background-color:#d39e00}a.badge-warning.focus,a.badge-warning:focus{outline:0;box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.badge-danger{color:#fff;background-color:#dc3545}a.badge-danger:focus,a.badge-danger:hover{color:#fff;background-color:#bd2130}a.badge-danger.focus,a.badge-danger:focus{outline:0;box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.badge-light{color:#212529;background-color:#f8f9fa}a.badge-light:focus,a.badge-light:hover{color:#212529;background-color:#dae0e5}a.badge-light.focus,a.badge-light:focus{outline:0;box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.badge-dark{color:#fff;background-color:#343a40}a.badge-dark:focus,a.badge-dark:hover{color:#fff;background-color:#1d2124}a.badge-dark.focus,a.badge-dark:focus{outline:0;box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#e9ecef;border-radius:.3rem}@media (min-width:576px){.jumbotron{padding:4rem 2rem}}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:4rem}.alert-dismissible .close{position:absolute;top:0;right:0;padding:.75rem 1.25rem;color:inherit}.alert-primary{color:#004085;background-color:#cce5ff;border-color:#b8daff}.alert-primary hr{border-top-color:#9fcdff}.alert-primary .alert-link{color:#002752}.alert-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db}.alert-secondary hr{border-top-color:#c8cbcf}.alert-secondary .alert-link{color:#202326}.alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}.alert-success hr{border-top-color:#b1dfbb}.alert-success .alert-link{color:#0b2e13}.alert-info{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb}.alert-info hr{border-top-color:#abdde5}.alert-info .alert-link{color:#062c33}.alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba}.alert-warning hr{border-top-color:#ffe8a1}.alert-warning .alert-link{color:#533f03}.alert-danger{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}.alert-danger hr{border-top-color:#f1b0b7}.alert-danger .alert-link{color:#491217}.alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.alert-light hr{border-top-color:#ececf6}.alert-light .alert-link{color:#686868}.alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}.alert-dark hr{border-top-color:#b9bbbe}.alert-dark .alert-link{color:#040505}@-webkit-keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}.progress{display:-ms-flexbox;display:flex;height:1rem;overflow:hidden;line-height:0;font-size:.75rem;background-color:#e9ecef;border-radius:.25rem}.progress-bar{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;overflow:hidden;color:#fff;text-align:center;white-space:nowrap;background-color:#007bff;transition:width .6s ease}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:1rem 1rem}.progress-bar-animated{-webkit-animation:progress-bar-stripes 1s linear infinite;animation:progress-bar-stripes 1s linear infinite}@media (prefers-reduced-motion:reduce){.progress-bar-animated{-webkit-animation:none;animation:none}}.media{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start}.media-body{-ms-flex:1;flex:1}.list-group{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:.25rem}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{z-index:1;color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#212529;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;pointer-events:none;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#007bff;border-color:#007bff}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:-1px;border-top-width:1px}.list-group-horizontal{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}@media (min-width:576px){.list-group-horizontal-sm{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:768px){.list-group-horizontal-md{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:992px){.list-group-horizontal-lg{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:1200px){.list-group-horizontal-xl{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 1px}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{color:#004085;background-color:#b8daff}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#004085;background-color:#9fcdff}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004085;border-color:#004085}.list-group-item-secondary{color:#383d41;background-color:#d6d8db}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#383d41;background-color:#c8cbcf}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#383d41;border-color:#383d41}.list-group-item-success{color:#155724;background-color:#c3e6cb}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#155724;background-color:#b1dfbb}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#155724;border-color:#155724}.list-group-item-info{color:#0c5460;background-color:#bee5eb}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#0c5460;background-color:#abdde5}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#0c5460;border-color:#0c5460}.list-group-item-warning{color:#856404;background-color:#ffeeba}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#856404;background-color:#ffe8a1}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#856404;border-color:#856404}.list-group-item-danger{color:#721c24;background-color:#f5c6cb}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#721c24;background-color:#f1b0b7}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#721c24;border-color:#721c24}.list-group-item-light{color:#818182;background-color:#fdfdfe}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#818182;background-color:#ececf6}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#818182;border-color:#818182}.list-group-item-dark{color:#1b1e21;background-color:#c6c8ca}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#1b1e21;background-color:#b9bbbe}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1b1e21;border-color:#1b1e21}.close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.close:hover{color:#000;text-decoration:none}.close:not(:disabled):not(.disabled):focus,.close:not(:disabled):not(.disabled):hover{opacity:.75}button.close{padding:0;background-color:transparent;border:0}a.close.disabled{pointer-events:none}.toast{max-width:350px;overflow:hidden;font-size:.875rem;background-color:rgba(255,255,255,.85);background-clip:padding-box;border:1px solid rgba(0,0,0,.1);box-shadow:0 .25rem .75rem rgba(0,0,0,.1);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);opacity:0;border-radius:.25rem}.toast:not(:last-child){margin-bottom:.75rem}.toast.showing{opacity:1}.toast.show{display:block;opacity:1}.toast.hide{display:none}.toast-header{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.25rem .75rem;color:#6c757d;background-color:rgba(255,255,255,.85);background-clip:padding-box;border-bottom:1px solid rgba(0,0,0,.05)}.toast-body{padding:.75rem}.modal-open{overflow:hidden}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal{position:fixed;top:0;left:0;z-index:1050;display:none;width:100%;height:100%;overflow:hidden;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out;transition:transform .3s ease-out,-webkit-transform .3s ease-out;-webkit-transform:translate(0,-50px);transform:translate(0,-50px)}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{-webkit-transform:none;transform:none}.modal.modal-static .modal-dialog{-webkit-transform:scale(1.02);transform:scale(1.02)}.modal-dialog-scrollable{display:-ms-flexbox;display:flex;max-height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 1rem);overflow:hidden}.modal-dialog-scrollable .modal-footer,.modal-dialog-scrollable .modal-header{-ms-flex-negative:0;flex-shrink:0}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;min-height:calc(100% - 1rem)}.modal-dialog-centered::before{display:block;height:calc(100vh - 1rem);height:-webkit-min-content;height:-moz-min-content;height:min-content;content:""}.modal-dialog-centered.modal-dialog-scrollable{-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;height:100%}.modal-dialog-centered.modal-dialog-scrollable .modal-content{max-height:none}.modal-dialog-centered.modal-dialog-scrollable::before{content:none}.modal-content{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:justify;justify-content:space-between;padding:1rem 1rem;border-bottom:1px solid #dee2e6;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.modal-header .close{padding:1rem 1rem;margin:-1rem -1rem -1rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem}.modal-footer{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:end;justify-content:flex-end;padding:.75rem;border-top:1px solid #dee2e6;border-bottom-right-radius:calc(.3rem - 1px);border-bottom-left-radius:calc(.3rem - 1px)}.modal-footer>*{margin:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{max-height:calc(100% - 3.5rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-dialog-centered::before{height:calc(100vh - 3.5rem);height:-webkit-min-content;height:-moz-min-content;height:min-content}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width:1200px){.modal-xl{max-width:1140px}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[x-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[x-placement^=top] .arrow,.bs-tooltip-top .arrow{bottom:0}.bs-tooltip-auto[x-placement^=top] .arrow::before,.bs-tooltip-top .arrow::before{top:0;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-auto[x-placement^=right],.bs-tooltip-right{padding:0 .4rem}.bs-tooltip-auto[x-placement^=right] .arrow,.bs-tooltip-right .arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=right] .arrow::before,.bs-tooltip-right .arrow::before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-auto[x-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[x-placement^=bottom] .arrow,.bs-tooltip-bottom .arrow{top:0}.bs-tooltip-auto[x-placement^=bottom] .arrow::before,.bs-tooltip-bottom .arrow::before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-auto[x-placement^=left],.bs-tooltip-left{padding:0 .4rem}.bs-tooltip-auto[x-placement^=left] .arrow,.bs-tooltip-left .arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=left] .arrow::before,.bs-tooltip-left .arrow::before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover .arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 .3rem}.popover .arrow::after,.popover .arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-auto[x-placement^=top],.bs-popover-top{margin-bottom:.5rem}.bs-popover-auto[x-placement^=top]>.arrow,.bs-popover-top>.arrow{bottom:calc(-.5rem - 1px)}.bs-popover-auto[x-placement^=top]>.arrow::before,.bs-popover-top>.arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=top]>.arrow::after,.bs-popover-top>.arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:#fff}.bs-popover-auto[x-placement^=right],.bs-popover-right{margin-left:.5rem}.bs-popover-auto[x-placement^=right]>.arrow,.bs-popover-right>.arrow{left:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=right]>.arrow::before,.bs-popover-right>.arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=right]>.arrow::after,.bs-popover-right>.arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:#fff}.bs-popover-auto[x-placement^=bottom],.bs-popover-bottom{margin-top:.5rem}.bs-popover-auto[x-placement^=bottom]>.arrow,.bs-popover-bottom>.arrow{top:calc(-.5rem - 1px)}.bs-popover-auto[x-placement^=bottom]>.arrow::before,.bs-popover-bottom>.arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=bottom]>.arrow::after,.bs-popover-bottom>.arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:#fff}.bs-popover-auto[x-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f7f7f7}.bs-popover-auto[x-placement^=left],.bs-popover-left{margin-right:.5rem}.bs-popover-auto[x-placement^=left]>.arrow,.bs-popover-left>.arrow{right:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=left]>.arrow::before,.bs-popover-left>.arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=left]>.arrow::after,.bs-popover-left>.arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:#fff}.popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:.5rem .75rem;color:#212529}.carousel{position:relative}.carousel.pointer-event{-ms-touch-action:pan-y;touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:-webkit-transform .6s ease-in-out;transition:transform .6s ease-in-out;transition:transform .6s ease-in-out,-webkit-transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-right,.carousel-item-next:not(.carousel-item-left){-webkit-transform:translateX(100%);transform:translateX(100%)}.active.carousel-item-left,.carousel-item-prev:not(.carousel-item-right){-webkit-transform:translateX(-100%);transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;-webkit-transform:none;transform:none}.carousel-fade .carousel-item-next.carousel-item-left,.carousel-fade .carousel-item-prev.carousel-item-right,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{z-index:0;opacity:0;transition:opacity 0s .6s}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:15%;color:#fff;text-align:center;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:20px;height:20px;background:no-repeat 50%/100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5L3.75 4l-2.5 2.5L2.75 8l4-4-4-4z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:15;display:-ms-flexbox;display:flex;-ms-flex-pack:center;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none}.carousel-indicators li{box-sizing:content-box;-ms-flex:0 1 auto;flex:0 1 auto;width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators li{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}@-webkit-keyframes spinner-border{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes spinner-border{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;border:.25em solid currentColor;border-right-color:transparent;border-radius:50%;-webkit-animation:spinner-border .75s linear infinite;animation:spinner-border .75s linear infinite}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@-webkit-keyframes spinner-grow{0%{-webkit-transform:scale(0);transform:scale(0)}50%{opacity:1;-webkit-transform:none;transform:none}}@keyframes spinner-grow{0%{-webkit-transform:scale(0);transform:scale(0)}50%{opacity:1;-webkit-transform:none;transform:none}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;background-color:currentColor;border-radius:50%;opacity:0;-webkit-animation:spinner-grow .75s linear infinite;animation:spinner-grow .75s linear infinite}.spinner-grow-sm{width:1rem;height:1rem}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-primary{background-color:#007bff!important}a.bg-primary:focus,a.bg-primary:hover,button.bg-primary:focus,button.bg-primary:hover{background-color:#0062cc!important}.bg-secondary{background-color:#6c757d!important}a.bg-secondary:focus,a.bg-secondary:hover,button.bg-secondary:focus,button.bg-secondary:hover{background-color:#545b62!important}.bg-success{background-color:#28a745!important}a.bg-success:focus,a.bg-success:hover,button.bg-success:focus,button.bg-success:hover{background-color:#1e7e34!important}.bg-info{background-color:#17a2b8!important}a.bg-info:focus,a.bg-info:hover,button.bg-info:focus,button.bg-info:hover{background-color:#117a8b!important}.bg-warning{background-color:#ffc107!important}a.bg-warning:focus,a.bg-warning:hover,button.bg-warning:focus,button.bg-warning:hover{background-color:#d39e00!important}.bg-danger{background-color:#dc3545!important}a.bg-danger:focus,a.bg-danger:hover,button.bg-danger:focus,button.bg-danger:hover{background-color:#bd2130!important}.bg-light{background-color:#f8f9fa!important}a.bg-light:focus,a.bg-light:hover,button.bg-light:focus,button.bg-light:hover{background-color:#dae0e5!important}.bg-dark{background-color:#343a40!important}a.bg-dark:focus,a.bg-dark:hover,button.bg-dark:focus,button.bg-dark:hover{background-color:#1d2124!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.border{border:1px solid #dee2e6!important}.border-top{border-top:1px solid #dee2e6!important}.border-right{border-right:1px solid #dee2e6!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.border-left{border-left:1px solid #dee2e6!important}.border-0{border:0!important}.border-top-0{border-top:0!important}.border-right-0{border-right:0!important}.border-bottom-0{border-bottom:0!important}.border-left-0{border-left:0!important}.border-primary{border-color:#007bff!important}.border-secondary{border-color:#6c757d!important}.border-success{border-color:#28a745!important}.border-info{border-color:#17a2b8!important}.border-warning{border-color:#ffc107!important}.border-danger{border-color:#dc3545!important}.border-light{border-color:#f8f9fa!important}.border-dark{border-color:#343a40!important}.border-white{border-color:#fff!important}.rounded-sm{border-radius:.2rem!important}.rounded{border-radius:.25rem!important}.rounded-top{border-top-left-radius:.25rem!important;border-top-right-radius:.25rem!important}.rounded-right{border-top-right-radius:.25rem!important;border-bottom-right-radius:.25rem!important}.rounded-bottom{border-bottom-right-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-left{border-top-left-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-lg{border-radius:.3rem!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:50rem!important}.rounded-0{border-radius:0!important}.clearfix::after{display:block;clear:both;content:""}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:-ms-flexbox!important;display:flex!important}.d-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}@media (min-width:576px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:-ms-flexbox!important;display:flex!important}.d-sm-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:-ms-flexbox!important;display:flex!important}.d-md-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:992px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:-ms-flexbox!important;display:flex!important}.d-lg-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:-ms-flexbox!important;display:flex!important}.d-xl-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:-ms-flexbox!important;display:flex!important}.d-print-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive::before{display:block;content:""}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9::before{padding-top:42.857143%}.embed-responsive-16by9::before{padding-top:56.25%}.embed-responsive-4by3::before{padding-top:75%}.embed-responsive-1by1::before{padding-top:100%}.flex-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-center{-ms-flex-align:center!important;align-items:center!important}.align-items-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}@media (min-width:576px){.flex-sm-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-sm-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-sm-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-sm-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-sm-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-sm-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-sm-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-sm-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-sm-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-sm-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-sm-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-sm-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-sm-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-sm-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-sm-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-sm-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-sm-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-sm-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-sm-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-sm-center{-ms-flex-align:center!important;align-items:center!important}.align-items-sm-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-sm-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-sm-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-sm-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-sm-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-sm-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-sm-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-sm-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-sm-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-sm-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-sm-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-sm-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-sm-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-sm-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:768px){.flex-md-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-md-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-md-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-md-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-md-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-md-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-md-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-md-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-md-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-md-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-md-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-md-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-md-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-md-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-md-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-md-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-md-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-md-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-md-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-md-center{-ms-flex-align:center!important;align-items:center!important}.align-items-md-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-md-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-md-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-md-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-md-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-md-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-md-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-md-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-md-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-md-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-md-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-md-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-md-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-md-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:992px){.flex-lg-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-lg-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-lg-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-lg-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-lg-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-lg-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-lg-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-lg-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-lg-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-lg-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-lg-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-lg-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-lg-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-lg-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-lg-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-lg-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-lg-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-lg-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-lg-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-lg-center{-ms-flex-align:center!important;align-items:center!important}.align-items-lg-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-lg-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-lg-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-lg-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-lg-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-lg-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-lg-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-lg-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-lg-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-lg-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-lg-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-lg-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-lg-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-lg-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:1200px){.flex-xl-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-xl-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-xl-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-xl-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-xl-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-xl-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-xl-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-xl-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-xl-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-xl-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-xl-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-xl-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-xl-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-xl-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-xl-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-xl-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-xl-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-xl-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-xl-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-xl-center{-ms-flex-align:center!important;align-items:center!important}.align-items-xl-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-xl-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-xl-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-xl-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-xl-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-xl-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-xl-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-xl-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-xl-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-xl-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-xl-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-xl-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-xl-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-xl-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}@media (min-width:576px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}}@media (min-width:768px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}}@media (min-width:992px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}}@media (min-width:1200px){.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}}.user-select-all{-webkit-user-select:all!important;-moz-user-select:all!important;-ms-user-select:all!important;user-select:all!important}.user-select-auto{-webkit-user-select:auto!important;-moz-user-select:auto!important;-ms-user-select:auto!important;user-select:auto!important}.user-select-none{-webkit-user-select:none!important;-moz-user-select:none!important;-ms-user-select:none!important;user-select:none!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}@supports ((position:-webkit-sticky) or (position:sticky)){.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.min-vw-100{min-width:100vw!important}.min-vh-100{min-height:100vh!important}.vw-100{width:100vw!important}.vh-100{height:100vh!important}.m-0{margin:0!important}.mt-0,.my-0{margin-top:0!important}.mr-0,.mx-0{margin-right:0!important}.mb-0,.my-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.m-1{margin:.25rem!important}.mt-1,.my-1{margin-top:.25rem!important}.mr-1,.mx-1{margin-right:.25rem!important}.mb-1,.my-1{margin-bottom:.25rem!important}.ml-1,.mx-1{margin-left:.25rem!important}.m-2{margin:.5rem!important}.mt-2,.my-2{margin-top:.5rem!important}.mr-2,.mx-2{margin-right:.5rem!important}.mb-2,.my-2{margin-bottom:.5rem!important}.ml-2,.mx-2{margin-left:.5rem!important}.m-3{margin:1rem!important}.mt-3,.my-3{margin-top:1rem!important}.mr-3,.mx-3{margin-right:1rem!important}.mb-3,.my-3{margin-bottom:1rem!important}.ml-3,.mx-3{margin-left:1rem!important}.m-4{margin:1.5rem!important}.mt-4,.my-4{margin-top:1.5rem!important}.mr-4,.mx-4{margin-right:1.5rem!important}.mb-4,.my-4{margin-bottom:1.5rem!important}.ml-4,.mx-4{margin-left:1.5rem!important}.m-5{margin:3rem!important}.mt-5,.my-5{margin-top:3rem!important}.mr-5,.mx-5{margin-right:3rem!important}.mb-5,.my-5{margin-bottom:3rem!important}.ml-5,.mx-5{margin-left:3rem!important}.p-0{padding:0!important}.pt-0,.py-0{padding-top:0!important}.pr-0,.px-0{padding-right:0!important}.pb-0,.py-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.p-1{padding:.25rem!important}.pt-1,.py-1{padding-top:.25rem!important}.pr-1,.px-1{padding-right:.25rem!important}.pb-1,.py-1{padding-bottom:.25rem!important}.pl-1,.px-1{padding-left:.25rem!important}.p-2{padding:.5rem!important}.pt-2,.py-2{padding-top:.5rem!important}.pr-2,.px-2{padding-right:.5rem!important}.pb-2,.py-2{padding-bottom:.5rem!important}.pl-2,.px-2{padding-left:.5rem!important}.p-3{padding:1rem!important}.pt-3,.py-3{padding-top:1rem!important}.pr-3,.px-3{padding-right:1rem!important}.pb-3,.py-3{padding-bottom:1rem!important}.pl-3,.px-3{padding-left:1rem!important}.p-4{padding:1.5rem!important}.pt-4,.py-4{padding-top:1.5rem!important}.pr-4,.px-4{padding-right:1.5rem!important}.pb-4,.py-4{padding-bottom:1.5rem!important}.pl-4,.px-4{padding-left:1.5rem!important}.p-5{padding:3rem!important}.pt-5,.py-5{padding-top:3rem!important}.pr-5,.px-5{padding-right:3rem!important}.pb-5,.py-5{padding-bottom:3rem!important}.pl-5,.px-5{padding-left:3rem!important}.m-n1{margin:-.25rem!important}.mt-n1,.my-n1{margin-top:-.25rem!important}.mr-n1,.mx-n1{margin-right:-.25rem!important}.mb-n1,.my-n1{margin-bottom:-.25rem!important}.ml-n1,.mx-n1{margin-left:-.25rem!important}.m-n2{margin:-.5rem!important}.mt-n2,.my-n2{margin-top:-.5rem!important}.mr-n2,.mx-n2{margin-right:-.5rem!important}.mb-n2,.my-n2{margin-bottom:-.5rem!important}.ml-n2,.mx-n2{margin-left:-.5rem!important}.m-n3{margin:-1rem!important}.mt-n3,.my-n3{margin-top:-1rem!important}.mr-n3,.mx-n3{margin-right:-1rem!important}.mb-n3,.my-n3{margin-bottom:-1rem!important}.ml-n3,.mx-n3{margin-left:-1rem!important}.m-n4{margin:-1.5rem!important}.mt-n4,.my-n4{margin-top:-1.5rem!important}.mr-n4,.mx-n4{margin-right:-1.5rem!important}.mb-n4,.my-n4{margin-bottom:-1.5rem!important}.ml-n4,.mx-n4{margin-left:-1.5rem!important}.m-n5{margin:-3rem!important}.mt-n5,.my-n5{margin-top:-3rem!important}.mr-n5,.mx-n5{margin-right:-3rem!important}.mb-n5,.my-n5{margin-bottom:-3rem!important}.ml-n5,.mx-n5{margin-left:-3rem!important}.m-auto{margin:auto!important}.mt-auto,.my-auto{margin-top:auto!important}.mr-auto,.mx-auto{margin-right:auto!important}.mb-auto,.my-auto{margin-bottom:auto!important}.ml-auto,.mx-auto{margin-left:auto!important}@media (min-width:576px){.m-sm-0{margin:0!important}.mt-sm-0,.my-sm-0{margin-top:0!important}.mr-sm-0,.mx-sm-0{margin-right:0!important}.mb-sm-0,.my-sm-0{margin-bottom:0!important}.ml-sm-0,.mx-sm-0{margin-left:0!important}.m-sm-1{margin:.25rem!important}.mt-sm-1,.my-sm-1{margin-top:.25rem!important}.mr-sm-1,.mx-sm-1{margin-right:.25rem!important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem!important}.ml-sm-1,.mx-sm-1{margin-left:.25rem!important}.m-sm-2{margin:.5rem!important}.mt-sm-2,.my-sm-2{margin-top:.5rem!important}.mr-sm-2,.mx-sm-2{margin-right:.5rem!important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem!important}.ml-sm-2,.mx-sm-2{margin-left:.5rem!important}.m-sm-3{margin:1rem!important}.mt-sm-3,.my-sm-3{margin-top:1rem!important}.mr-sm-3,.mx-sm-3{margin-right:1rem!important}.mb-sm-3,.my-sm-3{margin-bottom:1rem!important}.ml-sm-3,.mx-sm-3{margin-left:1rem!important}.m-sm-4{margin:1.5rem!important}.mt-sm-4,.my-sm-4{margin-top:1.5rem!important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem!important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem!important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem!important}.m-sm-5{margin:3rem!important}.mt-sm-5,.my-sm-5{margin-top:3rem!important}.mr-sm-5,.mx-sm-5{margin-right:3rem!important}.mb-sm-5,.my-sm-5{margin-bottom:3rem!important}.ml-sm-5,.mx-sm-5{margin-left:3rem!important}.p-sm-0{padding:0!important}.pt-sm-0,.py-sm-0{padding-top:0!important}.pr-sm-0,.px-sm-0{padding-right:0!important}.pb-sm-0,.py-sm-0{padding-bottom:0!important}.pl-sm-0,.px-sm-0{padding-left:0!important}.p-sm-1{padding:.25rem!important}.pt-sm-1,.py-sm-1{padding-top:.25rem!important}.pr-sm-1,.px-sm-1{padding-right:.25rem!important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem!important}.pl-sm-1,.px-sm-1{padding-left:.25rem!important}.p-sm-2{padding:.5rem!important}.pt-sm-2,.py-sm-2{padding-top:.5rem!important}.pr-sm-2,.px-sm-2{padding-right:.5rem!important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem!important}.pl-sm-2,.px-sm-2{padding-left:.5rem!important}.p-sm-3{padding:1rem!important}.pt-sm-3,.py-sm-3{padding-top:1rem!important}.pr-sm-3,.px-sm-3{padding-right:1rem!important}.pb-sm-3,.py-sm-3{padding-bottom:1rem!important}.pl-sm-3,.px-sm-3{padding-left:1rem!important}.p-sm-4{padding:1.5rem!important}.pt-sm-4,.py-sm-4{padding-top:1.5rem!important}.pr-sm-4,.px-sm-4{padding-right:1.5rem!important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem!important}.pl-sm-4,.px-sm-4{padding-left:1.5rem!important}.p-sm-5{padding:3rem!important}.pt-sm-5,.py-sm-5{padding-top:3rem!important}.pr-sm-5,.px-sm-5{padding-right:3rem!important}.pb-sm-5,.py-sm-5{padding-bottom:3rem!important}.pl-sm-5,.px-sm-5{padding-left:3rem!important}.m-sm-n1{margin:-.25rem!important}.mt-sm-n1,.my-sm-n1{margin-top:-.25rem!important}.mr-sm-n1,.mx-sm-n1{margin-right:-.25rem!important}.mb-sm-n1,.my-sm-n1{margin-bottom:-.25rem!important}.ml-sm-n1,.mx-sm-n1{margin-left:-.25rem!important}.m-sm-n2{margin:-.5rem!important}.mt-sm-n2,.my-sm-n2{margin-top:-.5rem!important}.mr-sm-n2,.mx-sm-n2{margin-right:-.5rem!important}.mb-sm-n2,.my-sm-n2{margin-bottom:-.5rem!important}.ml-sm-n2,.mx-sm-n2{margin-left:-.5rem!important}.m-sm-n3{margin:-1rem!important}.mt-sm-n3,.my-sm-n3{margin-top:-1rem!important}.mr-sm-n3,.mx-sm-n3{margin-right:-1rem!important}.mb-sm-n3,.my-sm-n3{margin-bottom:-1rem!important}.ml-sm-n3,.mx-sm-n3{margin-left:-1rem!important}.m-sm-n4{margin:-1.5rem!important}.mt-sm-n4,.my-sm-n4{margin-top:-1.5rem!important}.mr-sm-n4,.mx-sm-n4{margin-right:-1.5rem!important}.mb-sm-n4,.my-sm-n4{margin-bottom:-1.5rem!important}.ml-sm-n4,.mx-sm-n4{margin-left:-1.5rem!important}.m-sm-n5{margin:-3rem!important}.mt-sm-n5,.my-sm-n5{margin-top:-3rem!important}.mr-sm-n5,.mx-sm-n5{margin-right:-3rem!important}.mb-sm-n5,.my-sm-n5{margin-bottom:-3rem!important}.ml-sm-n5,.mx-sm-n5{margin-left:-3rem!important}.m-sm-auto{margin:auto!important}.mt-sm-auto,.my-sm-auto{margin-top:auto!important}.mr-sm-auto,.mx-sm-auto{margin-right:auto!important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto!important}.ml-sm-auto,.mx-sm-auto{margin-left:auto!important}}@media (min-width:768px){.m-md-0{margin:0!important}.mt-md-0,.my-md-0{margin-top:0!important}.mr-md-0,.mx-md-0{margin-right:0!important}.mb-md-0,.my-md-0{margin-bottom:0!important}.ml-md-0,.mx-md-0{margin-left:0!important}.m-md-1{margin:.25rem!important}.mt-md-1,.my-md-1{margin-top:.25rem!important}.mr-md-1,.mx-md-1{margin-right:.25rem!important}.mb-md-1,.my-md-1{margin-bottom:.25rem!important}.ml-md-1,.mx-md-1{margin-left:.25rem!important}.m-md-2{margin:.5rem!important}.mt-md-2,.my-md-2{margin-top:.5rem!important}.mr-md-2,.mx-md-2{margin-right:.5rem!important}.mb-md-2,.my-md-2{margin-bottom:.5rem!important}.ml-md-2,.mx-md-2{margin-left:.5rem!important}.m-md-3{margin:1rem!important}.mt-md-3,.my-md-3{margin-top:1rem!important}.mr-md-3,.mx-md-3{margin-right:1rem!important}.mb-md-3,.my-md-3{margin-bottom:1rem!important}.ml-md-3,.mx-md-3{margin-left:1rem!important}.m-md-4{margin:1.5rem!important}.mt-md-4,.my-md-4{margin-top:1.5rem!important}.mr-md-4,.mx-md-4{margin-right:1.5rem!important}.mb-md-4,.my-md-4{margin-bottom:1.5rem!important}.ml-md-4,.mx-md-4{margin-left:1.5rem!important}.m-md-5{margin:3rem!important}.mt-md-5,.my-md-5{margin-top:3rem!important}.mr-md-5,.mx-md-5{margin-right:3rem!important}.mb-md-5,.my-md-5{margin-bottom:3rem!important}.ml-md-5,.mx-md-5{margin-left:3rem!important}.p-md-0{padding:0!important}.pt-md-0,.py-md-0{padding-top:0!important}.pr-md-0,.px-md-0{padding-right:0!important}.pb-md-0,.py-md-0{padding-bottom:0!important}.pl-md-0,.px-md-0{padding-left:0!important}.p-md-1{padding:.25rem!important}.pt-md-1,.py-md-1{padding-top:.25rem!important}.pr-md-1,.px-md-1{padding-right:.25rem!important}.pb-md-1,.py-md-1{padding-bottom:.25rem!important}.pl-md-1,.px-md-1{padding-left:.25rem!important}.p-md-2{padding:.5rem!important}.pt-md-2,.py-md-2{padding-top:.5rem!important}.pr-md-2,.px-md-2{padding-right:.5rem!important}.pb-md-2,.py-md-2{padding-bottom:.5rem!important}.pl-md-2,.px-md-2{padding-left:.5rem!important}.p-md-3{padding:1rem!important}.pt-md-3,.py-md-3{padding-top:1rem!important}.pr-md-3,.px-md-3{padding-right:1rem!important}.pb-md-3,.py-md-3{padding-bottom:1rem!important}.pl-md-3,.px-md-3{padding-left:1rem!important}.p-md-4{padding:1.5rem!important}.pt-md-4,.py-md-4{padding-top:1.5rem!important}.pr-md-4,.px-md-4{padding-right:1.5rem!important}.pb-md-4,.py-md-4{padding-bottom:1.5rem!important}.pl-md-4,.px-md-4{padding-left:1.5rem!important}.p-md-5{padding:3rem!important}.pt-md-5,.py-md-5{padding-top:3rem!important}.pr-md-5,.px-md-5{padding-right:3rem!important}.pb-md-5,.py-md-5{padding-bottom:3rem!important}.pl-md-5,.px-md-5{padding-left:3rem!important}.m-md-n1{margin:-.25rem!important}.mt-md-n1,.my-md-n1{margin-top:-.25rem!important}.mr-md-n1,.mx-md-n1{margin-right:-.25rem!important}.mb-md-n1,.my-md-n1{margin-bottom:-.25rem!important}.ml-md-n1,.mx-md-n1{margin-left:-.25rem!important}.m-md-n2{margin:-.5rem!important}.mt-md-n2,.my-md-n2{margin-top:-.5rem!important}.mr-md-n2,.mx-md-n2{margin-right:-.5rem!important}.mb-md-n2,.my-md-n2{margin-bottom:-.5rem!important}.ml-md-n2,.mx-md-n2{margin-left:-.5rem!important}.m-md-n3{margin:-1rem!important}.mt-md-n3,.my-md-n3{margin-top:-1rem!important}.mr-md-n3,.mx-md-n3{margin-right:-1rem!important}.mb-md-n3,.my-md-n3{margin-bottom:-1rem!important}.ml-md-n3,.mx-md-n3{margin-left:-1rem!important}.m-md-n4{margin:-1.5rem!important}.mt-md-n4,.my-md-n4{margin-top:-1.5rem!important}.mr-md-n4,.mx-md-n4{margin-right:-1.5rem!important}.mb-md-n4,.my-md-n4{margin-bottom:-1.5rem!important}.ml-md-n4,.mx-md-n4{margin-left:-1.5rem!important}.m-md-n5{margin:-3rem!important}.mt-md-n5,.my-md-n5{margin-top:-3rem!important}.mr-md-n5,.mx-md-n5{margin-right:-3rem!important}.mb-md-n5,.my-md-n5{margin-bottom:-3rem!important}.ml-md-n5,.mx-md-n5{margin-left:-3rem!important}.m-md-auto{margin:auto!important}.mt-md-auto,.my-md-auto{margin-top:auto!important}.mr-md-auto,.mx-md-auto{margin-right:auto!important}.mb-md-auto,.my-md-auto{margin-bottom:auto!important}.ml-md-auto,.mx-md-auto{margin-left:auto!important}}@media (min-width:992px){.m-lg-0{margin:0!important}.mt-lg-0,.my-lg-0{margin-top:0!important}.mr-lg-0,.mx-lg-0{margin-right:0!important}.mb-lg-0,.my-lg-0{margin-bottom:0!important}.ml-lg-0,.mx-lg-0{margin-left:0!important}.m-lg-1{margin:.25rem!important}.mt-lg-1,.my-lg-1{margin-top:.25rem!important}.mr-lg-1,.mx-lg-1{margin-right:.25rem!important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem!important}.ml-lg-1,.mx-lg-1{margin-left:.25rem!important}.m-lg-2{margin:.5rem!important}.mt-lg-2,.my-lg-2{margin-top:.5rem!important}.mr-lg-2,.mx-lg-2{margin-right:.5rem!important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem!important}.ml-lg-2,.mx-lg-2{margin-left:.5rem!important}.m-lg-3{margin:1rem!important}.mt-lg-3,.my-lg-3{margin-top:1rem!important}.mr-lg-3,.mx-lg-3{margin-right:1rem!important}.mb-lg-3,.my-lg-3{margin-bottom:1rem!important}.ml-lg-3,.mx-lg-3{margin-left:1rem!important}.m-lg-4{margin:1.5rem!important}.mt-lg-4,.my-lg-4{margin-top:1.5rem!important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem!important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem!important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem!important}.m-lg-5{margin:3rem!important}.mt-lg-5,.my-lg-5{margin-top:3rem!important}.mr-lg-5,.mx-lg-5{margin-right:3rem!important}.mb-lg-5,.my-lg-5{margin-bottom:3rem!important}.ml-lg-5,.mx-lg-5{margin-left:3rem!important}.p-lg-0{padding:0!important}.pt-lg-0,.py-lg-0{padding-top:0!important}.pr-lg-0,.px-lg-0{padding-right:0!important}.pb-lg-0,.py-lg-0{padding-bottom:0!important}.pl-lg-0,.px-lg-0{padding-left:0!important}.p-lg-1{padding:.25rem!important}.pt-lg-1,.py-lg-1{padding-top:.25rem!important}.pr-lg-1,.px-lg-1{padding-right:.25rem!important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem!important}.pl-lg-1,.px-lg-1{padding-left:.25rem!important}.p-lg-2{padding:.5rem!important}.pt-lg-2,.py-lg-2{padding-top:.5rem!important}.pr-lg-2,.px-lg-2{padding-right:.5rem!important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem!important}.pl-lg-2,.px-lg-2{padding-left:.5rem!important}.p-lg-3{padding:1rem!important}.pt-lg-3,.py-lg-3{padding-top:1rem!important}.pr-lg-3,.px-lg-3{padding-right:1rem!important}.pb-lg-3,.py-lg-3{padding-bottom:1rem!important}.pl-lg-3,.px-lg-3{padding-left:1rem!important}.p-lg-4{padding:1.5rem!important}.pt-lg-4,.py-lg-4{padding-top:1.5rem!important}.pr-lg-4,.px-lg-4{padding-right:1.5rem!important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem!important}.pl-lg-4,.px-lg-4{padding-left:1.5rem!important}.p-lg-5{padding:3rem!important}.pt-lg-5,.py-lg-5{padding-top:3rem!important}.pr-lg-5,.px-lg-5{padding-right:3rem!important}.pb-lg-5,.py-lg-5{padding-bottom:3rem!important}.pl-lg-5,.px-lg-5{padding-left:3rem!important}.m-lg-n1{margin:-.25rem!important}.mt-lg-n1,.my-lg-n1{margin-top:-.25rem!important}.mr-lg-n1,.mx-lg-n1{margin-right:-.25rem!important}.mb-lg-n1,.my-lg-n1{margin-bottom:-.25rem!important}.ml-lg-n1,.mx-lg-n1{margin-left:-.25rem!important}.m-lg-n2{margin:-.5rem!important}.mt-lg-n2,.my-lg-n2{margin-top:-.5rem!important}.mr-lg-n2,.mx-lg-n2{margin-right:-.5rem!important}.mb-lg-n2,.my-lg-n2{margin-bottom:-.5rem!important}.ml-lg-n2,.mx-lg-n2{margin-left:-.5rem!important}.m-lg-n3{margin:-1rem!important}.mt-lg-n3,.my-lg-n3{margin-top:-1rem!important}.mr-lg-n3,.mx-lg-n3{margin-right:-1rem!important}.mb-lg-n3,.my-lg-n3{margin-bottom:-1rem!important}.ml-lg-n3,.mx-lg-n3{margin-left:-1rem!important}.m-lg-n4{margin:-1.5rem!important}.mt-lg-n4,.my-lg-n4{margin-top:-1.5rem!important}.mr-lg-n4,.mx-lg-n4{margin-right:-1.5rem!important}.mb-lg-n4,.my-lg-n4{margin-bottom:-1.5rem!important}.ml-lg-n4,.mx-lg-n4{margin-left:-1.5rem!important}.m-lg-n5{margin:-3rem!important}.mt-lg-n5,.my-lg-n5{margin-top:-3rem!important}.mr-lg-n5,.mx-lg-n5{margin-right:-3rem!important}.mb-lg-n5,.my-lg-n5{margin-bottom:-3rem!important}.ml-lg-n5,.mx-lg-n5{margin-left:-3rem!important}.m-lg-auto{margin:auto!important}.mt-lg-auto,.my-lg-auto{margin-top:auto!important}.mr-lg-auto,.mx-lg-auto{margin-right:auto!important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto!important}.ml-lg-auto,.mx-lg-auto{margin-left:auto!important}}@media (min-width:1200px){.m-xl-0{margin:0!important}.mt-xl-0,.my-xl-0{margin-top:0!important}.mr-xl-0,.mx-xl-0{margin-right:0!important}.mb-xl-0,.my-xl-0{margin-bottom:0!important}.ml-xl-0,.mx-xl-0{margin-left:0!important}.m-xl-1{margin:.25rem!important}.mt-xl-1,.my-xl-1{margin-top:.25rem!important}.mr-xl-1,.mx-xl-1{margin-right:.25rem!important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem!important}.ml-xl-1,.mx-xl-1{margin-left:.25rem!important}.m-xl-2{margin:.5rem!important}.mt-xl-2,.my-xl-2{margin-top:.5rem!important}.mr-xl-2,.mx-xl-2{margin-right:.5rem!important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem!important}.ml-xl-2,.mx-xl-2{margin-left:.5rem!important}.m-xl-3{margin:1rem!important}.mt-xl-3,.my-xl-3{margin-top:1rem!important}.mr-xl-3,.mx-xl-3{margin-right:1rem!important}.mb-xl-3,.my-xl-3{margin-bottom:1rem!important}.ml-xl-3,.mx-xl-3{margin-left:1rem!important}.m-xl-4{margin:1.5rem!important}.mt-xl-4,.my-xl-4{margin-top:1.5rem!important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem!important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem!important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem!important}.m-xl-5{margin:3rem!important}.mt-xl-5,.my-xl-5{margin-top:3rem!important}.mr-xl-5,.mx-xl-5{margin-right:3rem!important}.mb-xl-5,.my-xl-5{margin-bottom:3rem!important}.ml-xl-5,.mx-xl-5{margin-left:3rem!important}.p-xl-0{padding:0!important}.pt-xl-0,.py-xl-0{padding-top:0!important}.pr-xl-0,.px-xl-0{padding-right:0!important}.pb-xl-0,.py-xl-0{padding-bottom:0!important}.pl-xl-0,.px-xl-0{padding-left:0!important}.p-xl-1{padding:.25rem!important}.pt-xl-1,.py-xl-1{padding-top:.25rem!important}.pr-xl-1,.px-xl-1{padding-right:.25rem!important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem!important}.pl-xl-1,.px-xl-1{padding-left:.25rem!important}.p-xl-2{padding:.5rem!important}.pt-xl-2,.py-xl-2{padding-top:.5rem!important}.pr-xl-2,.px-xl-2{padding-right:.5rem!important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem!important}.pl-xl-2,.px-xl-2{padding-left:.5rem!important}.p-xl-3{padding:1rem!important}.pt-xl-3,.py-xl-3{padding-top:1rem!important}.pr-xl-3,.px-xl-3{padding-right:1rem!important}.pb-xl-3,.py-xl-3{padding-bottom:1rem!important}.pl-xl-3,.px-xl-3{padding-left:1rem!important}.p-xl-4{padding:1.5rem!important}.pt-xl-4,.py-xl-4{padding-top:1.5rem!important}.pr-xl-4,.px-xl-4{padding-right:1.5rem!important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem!important}.pl-xl-4,.px-xl-4{padding-left:1.5rem!important}.p-xl-5{padding:3rem!important}.pt-xl-5,.py-xl-5{padding-top:3rem!important}.pr-xl-5,.px-xl-5{padding-right:3rem!important}.pb-xl-5,.py-xl-5{padding-bottom:3rem!important}.pl-xl-5,.px-xl-5{padding-left:3rem!important}.m-xl-n1{margin:-.25rem!important}.mt-xl-n1,.my-xl-n1{margin-top:-.25rem!important}.mr-xl-n1,.mx-xl-n1{margin-right:-.25rem!important}.mb-xl-n1,.my-xl-n1{margin-bottom:-.25rem!important}.ml-xl-n1,.mx-xl-n1{margin-left:-.25rem!important}.m-xl-n2{margin:-.5rem!important}.mt-xl-n2,.my-xl-n2{margin-top:-.5rem!important}.mr-xl-n2,.mx-xl-n2{margin-right:-.5rem!important}.mb-xl-n2,.my-xl-n2{margin-bottom:-.5rem!important}.ml-xl-n2,.mx-xl-n2{margin-left:-.5rem!important}.m-xl-n3{margin:-1rem!important}.mt-xl-n3,.my-xl-n3{margin-top:-1rem!important}.mr-xl-n3,.mx-xl-n3{margin-right:-1rem!important}.mb-xl-n3,.my-xl-n3{margin-bottom:-1rem!important}.ml-xl-n3,.mx-xl-n3{margin-left:-1rem!important}.m-xl-n4{margin:-1.5rem!important}.mt-xl-n4,.my-xl-n4{margin-top:-1.5rem!important}.mr-xl-n4,.mx-xl-n4{margin-right:-1.5rem!important}.mb-xl-n4,.my-xl-n4{margin-bottom:-1.5rem!important}.ml-xl-n4,.mx-xl-n4{margin-left:-1.5rem!important}.m-xl-n5{margin:-3rem!important}.mt-xl-n5,.my-xl-n5{margin-top:-3rem!important}.mr-xl-n5,.mx-xl-n5{margin-right:-3rem!important}.mb-xl-n5,.my-xl-n5{margin-bottom:-3rem!important}.ml-xl-n5,.mx-xl-n5{margin-left:-3rem!important}.m-xl-auto{margin:auto!important}.mt-xl-auto,.my-xl-auto{margin-top:auto!important}.mr-xl-auto,.mx-xl-auto{margin-right:auto!important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto!important}.ml-xl-auto,.mx-xl-auto{margin-left:auto!important}}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;pointer-events:auto;content:"";background-color:rgba(0,0,0,0)}.text-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace!important}.text-justify{text-align:justify!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}@media (min-width:576px){.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-light{font-weight:300!important}.font-weight-lighter{font-weight:lighter!important}.font-weight-normal{font-weight:400!important}.font-weight-bold{font-weight:700!important}.font-weight-bolder{font-weight:bolder!important}.font-italic{font-style:italic!important}.text-white{color:#fff!important}.text-primary{color:#007bff!important}a.text-primary:focus,a.text-primary:hover{color:#0056b3!important}.text-secondary{color:#6c757d!important}a.text-secondary:focus,a.text-secondary:hover{color:#494f54!important}.text-success{color:#28a745!important}a.text-success:focus,a.text-success:hover{color:#19692c!important}.text-info{color:#17a2b8!important}a.text-info:focus,a.text-info:hover{color:#0f6674!important}.text-warning{color:#ffc107!important}a.text-warning:focus,a.text-warning:hover{color:#ba8b00!important}.text-danger{color:#dc3545!important}a.text-danger:focus,a.text-danger:hover{color:#a71d2a!important}.text-light{color:#f8f9fa!important}a.text-light:focus,a.text-light:hover{color:#cbd3da!important}.text-dark{color:#343a40!important}a.text-dark:focus,a.text-dark:hover{color:#121416!important}.text-body{color:#212529!important}.text-muted{color:#6c757d!important}.text-black-50{color:rgba(0,0,0,.5)!important}.text-white-50{color:rgba(255,255,255,.5)!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.text-decoration-none{text-decoration:none!important}.text-break{word-wrap:break-word!important}.text-reset{color:inherit!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media print{*,::after,::before{text-shadow:none!important;box-shadow:none!important}a:not(.btn){text-decoration:underline}abbr[title]::after{content:" (" attr(title) ")"}pre{white-space:pre-wrap!important}blockquote,pre{border:1px solid #adb5bd;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}@page{size:a3}body{min-width:992px!important}.container{min-width:992px!important}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #dee2e6!important}.table-dark{color:inherit}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#dee2e6}.table .thead-dark th{color:inherit;border-color:#dee2e6}} +/*# sourceMappingURL=bootstrap.min.css.map */ \ No newline at end of file diff --git a/example/src/main/resources/static/index.html b/example/src/main/resources/static/index.html index 19c2de0..db07454 100644 --- a/example/src/main/resources/static/index.html +++ b/example/src/main/resources/static/index.html @@ -5,9 +5,8 @@ Web eID: electronic ID smart cards on the Web Welcome! Welcome! Date: Thu, 15 Jul 2021 13:38:23 +0300 Subject: [PATCH 035/116] security: turn on CSRF protection Signed-off-by: Mart Somermaa --- .../example/config/ApplicationConfiguration.java | 7 ++----- .../main/resources/{static => templates}/index.html | 12 +++++++++++- example/src/main/resources/templates/welcome.html | 12 +++++++++++- .../java/org/webeid/example/testutil/HttpHelper.java | 4 ++++ 4 files changed, 28 insertions(+), 7 deletions(-) rename example/src/main/resources/{static => templates}/index.html (96%) diff --git a/example/src/main/java/org/webeid/example/config/ApplicationConfiguration.java b/example/src/main/java/org/webeid/example/config/ApplicationConfiguration.java index 0d52175..e77b4c8 100644 --- a/example/src/main/java/org/webeid/example/config/ApplicationConfiguration.java +++ b/example/src/main/java/org/webeid/example/config/ApplicationConfiguration.java @@ -69,15 +69,12 @@ protected void configure(HttpSecurity http) throws Exception { .logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler()) .and() .headers() - .frameOptions() - .sameOrigin() - .and() - .csrf() - .disable(); + .frameOptions().sameOrigin(); // @formatter:on } public void addViewControllers(ViewControllerRegistry registry) { + registry.addViewController("/").setViewName("index"); registry.addViewController("/welcome").setViewName("welcome"); } diff --git a/example/src/main/resources/static/index.html b/example/src/main/resources/templates/index.html similarity index 96% rename from example/src/main/resources/static/index.html rename to example/src/main/resources/templates/index.html index db07454..9be1e83 100644 --- a/example/src/main/resources/static/index.html +++ b/example/src/main/resources/templates/index.html @@ -3,6 +3,10 @@ + + + + Web eID: electronic ID smart cards on the Web For developers const authButton = document.querySelector("#webeid-auth-button"); + const csrfToken = document.querySelector('#csrftoken').content; + const csrfHeaderName = document.querySelector('#csrfheadername').content; + authButton.addEventListener("click", async () => { const options = { getAuthChallengeUrl: window.location.origin + "/auth/challenge", - postAuthTokenUrl: window.location.origin + "/auth/login" + postAuthTokenUrl: window.location.origin + "/auth/login", + headers: { + [csrfHeaderName]: csrfToken + } }; hideErrorMessage(); diff --git a/example/src/main/resources/templates/welcome.html b/example/src/main/resources/templates/welcome.html index b41ba95..e2d8221 100644 --- a/example/src/main/resources/templates/welcome.html +++ b/example/src/main/resources/templates/welcome.html @@ -3,6 +3,10 @@ + + + + Welcome! Digital signing window.location.href = "/sign/download"; }); + const csrfToken = document.querySelector('#csrftoken').content; + const csrfHeaderName = document.querySelector('#csrfheadername').content; + signButton.addEventListener("click", async () => { const options = { postPrepareSigningUrl: window.location.origin + "/sign/prepare", - postFinalizeSigningUrl: window.location.origin + "/sign/sign" + postFinalizeSigningUrl: window.location.origin + "/sign/sign", + headers: { + [csrfHeaderName]: csrfToken + } }; hideErrorMessage(); diff --git a/example/src/test/java/org/webeid/example/testutil/HttpHelper.java b/example/src/test/java/org/webeid/example/testutil/HttpHelper.java index 9ec2f99..4becbd7 100644 --- a/example/src/test/java/org/webeid/example/testutil/HttpHelper.java +++ b/example/src/test/java/org/webeid/example/testutil/HttpHelper.java @@ -32,6 +32,7 @@ import org.webeid.example.service.dto.CertificateDTO; import org.webeid.example.service.dto.SignatureDTO; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; @@ -43,6 +44,7 @@ public static MockHttpServletResponse login(DefaultMockMvcBuilder mvcBuilder, Mo .build() .perform(post("/auth/login") .session(session) + .with(csrf()) .contentType(MediaType.APPLICATION_JSON) .content(ObjectMother.toJson(authTokenDTO))) .andReturn() @@ -68,6 +70,7 @@ public static MockHttpServletResponse prepare(DefaultMockMvcBuilder mvcBuilder, .build() .perform(post("/sign/prepare") .session(session) + .with(csrf()) .contentType(MediaType.APPLICATION_JSON) .content(ObjectMother.toJson(certificateDTO))) .andReturn() @@ -81,6 +84,7 @@ public static MockHttpServletResponse sign(DefaultMockMvcBuilder mvcBuilder, Moc .build() .perform(post("/sign/sign") .session(session) + .with(csrf()) .contentType(MediaType.APPLICATION_JSON) .content(ObjectMother.toJson(signatureDTO))) .andReturn() From 7174d870b204377203fdb0c7e3c12f1fefddf26d Mon Sep 17 00:00:00 2001 From: Mart Somermaa Date: Thu, 15 Jul 2021 14:31:01 +0300 Subject: [PATCH 036/116] refactor: move settings from application.properties to application.yaml Signed-off-by: Mart Somermaa --- example/src/main/resources/application.properties | 7 ------- example/src/main/resources/application.yaml | 10 ++++++++++ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/example/src/main/resources/application.properties b/example/src/main/resources/application.properties index d1c337f..cbb42d2 100644 --- a/example/src/main/resources/application.properties +++ b/example/src/main/resources/application.properties @@ -1,8 +1 @@ spring.profiles.active=dev -# Make session cookie secure behind a reverse proxy, see -# - https://docs.spring.io/spring-boot/docs/2.2.5.RELEASE/reference/htmlsingle/#howto-use-behind-a-proxy-server -# - https://docs.spring.io/spring-boot/docs/2.2.5.RELEASE/reference/htmlsingle/#howto-enable-https -server.forward-headers-strategy=native -server.tomcat.remote-ip-header=x-forwarded-for -server.tomcat.protocol-header=x-forwarded-proto -# server.servlet.session.cookie.secure=true -- implicit when HTTPS is detected diff --git a/example/src/main/resources/application.yaml b/example/src/main/resources/application.yaml index 2c53a60..4c82178 100644 --- a/example/src/main/resources/application.yaml +++ b/example/src/main/resources/application.yaml @@ -5,6 +5,16 @@ spring: max-file-size: 5000KB max-request-size: 5000KB +# Make session cookie secure behind a reverse proxy, see +# - https://docs.spring.io/spring-boot/docs/2.2.5.RELEASE/reference/htmlsingle/#howto-use-behind-a-proxy-server +# - https://docs.spring.io/spring-boot/docs/2.2.5.RELEASE/reference/htmlsingle/#howto-enable-https +# Note that `server.servlet.session.cookie.secure` is implicitly true when HTTPS is detected. +server: + forward-headers-strategy: native + tomcat: + remote-ip-header: x-forwarded-for + protocol-header: x-forwarded-proto + logging: level: org.webeid.security: DEBUG From c8746bf9fbf0a9a8f091a40e771529dd00a5be78 Mon Sep 17 00:00:00 2001 From: Mart Somermaa Date: Mon, 19 Jul 2021 22:24:22 +0300 Subject: [PATCH 037/116] feat(security): assure that authenticated subject matches with signing certificate subject Signed-off-by: Mart Somermaa --- .../config/ValidationConfiguration.java | 2 - .../AuthTokenDTOAuthenticationProvider.java | 10 +---- .../security/WebEidAuthentication.java | 37 ++++++++++++++++++ .../example/service/SigningService.java | 34 ++++++++-------- .../example/web/rest/SigningController.java | 5 ++- .../webeid/example/WebApplicationTest.java | 2 +- example/src/test/resources/signout.p12 | Bin 3061 -> 2890 bytes 7 files changed, 61 insertions(+), 29 deletions(-) create mode 100644 example/src/main/java/org/webeid/example/security/WebEidAuthentication.java diff --git a/example/src/main/java/org/webeid/example/config/ValidationConfiguration.java b/example/src/main/java/org/webeid/example/config/ValidationConfiguration.java index 2df70d9..c52854a 100644 --- a/example/src/main/java/org/webeid/example/config/ValidationConfiguration.java +++ b/example/src/main/java/org/webeid/example/config/ValidationConfiguration.java @@ -135,8 +135,6 @@ public AuthTokenValidator validator() { try { return new AuthTokenValidatorBuilder() .withSiteOrigin(URI.create(yamlConfig().getLocalOrigin())) - // TODO: it is still open what the validation library should do when cert fingerprint validation is enabled but fingerprint is null (as in Chrome). - // .withSiteCertificateSha256Fingerprint(yamlConfig().getFingerprint()) .withNonceCache(nonceCache()) .withTrustedCertificateAuthorities(loadTrustedCACertificatesFromResources()) .withTrustedCertificateAuthorities(loadTrustedCACertificatesFromKeyStore()) diff --git a/example/src/main/java/org/webeid/example/security/AuthTokenDTOAuthenticationProvider.java b/example/src/main/java/org/webeid/example/security/AuthTokenDTOAuthenticationProvider.java index de22a3c..1f27338 100644 --- a/example/src/main/java/org/webeid/example/security/AuthTokenDTOAuthenticationProvider.java +++ b/example/src/main/java/org/webeid/example/security/AuthTokenDTOAuthenticationProvider.java @@ -68,8 +68,8 @@ public Authentication authenticate(Authentication auth) throws AuthenticationExc authorities.add(USER_ROLE); try { - X509Certificate userCertificate = tokenValidator.validate(token); - return new PreAuthenticatedAuthenticationToken(getPrincipalFromCertificate(userCertificate), null, authorities); + final X509Certificate userCertificate = tokenValidator.validate(token); + return WebEidAuthentication.fromCertificate(userCertificate, authorities); } catch (TokenValidationException e) { LOG.warn("Token validation has failed", e); throw new AuthenticationServiceException("Token validation failed: " + e.getMessage()); @@ -85,10 +85,4 @@ public boolean supports(Class authentication) { return PreAuthenticatedAuthenticationToken.class.equals(authentication); } - // FIXME: create a proper principal object - private String getPrincipalFromCertificate(X509Certificate userCertificate) throws CertificateEncodingException { - return CertUtil.getSubjectGivenName(userCertificate) + ' ' + - CertUtil.getSubjectSurname(userCertificate) + ", " + - CertUtil.getSubjectIdCode(userCertificate); - } } diff --git a/example/src/main/java/org/webeid/example/security/WebEidAuthentication.java b/example/src/main/java/org/webeid/example/security/WebEidAuthentication.java new file mode 100644 index 0000000..f935aab --- /dev/null +++ b/example/src/main/java/org/webeid/example/security/WebEidAuthentication.java @@ -0,0 +1,37 @@ +package org.webeid.example.security; + +import org.springframework.security.core.Authentication; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken; +import org.webeid.security.util.CertUtil; + +import java.security.cert.CertificateEncodingException; +import java.security.cert.X509Certificate; +import java.util.List; +import java.util.Objects; + +public class WebEidAuthentication extends PreAuthenticatedAuthenticationToken implements Authentication { + + private final String idCode; + + public static Authentication fromCertificate(X509Certificate userCertificate, List authorities) throws CertificateEncodingException { + final String principalName = getPrincipalNameFromCertificate(userCertificate); + final String idCode = Objects.requireNonNull(CertUtil.getSubjectIdCode(userCertificate)); + return new WebEidAuthentication(principalName, idCode, authorities); + } + + public String getIdCode() { + return idCode; + } + + private WebEidAuthentication(String principalName, String idCode, List authorities) { + super(principalName, idCode, authorities); + this.idCode = idCode; + } + + private static String getPrincipalNameFromCertificate(X509Certificate userCertificate) throws CertificateEncodingException { + return Objects.requireNonNull(CertUtil.getSubjectGivenName(userCertificate)) + ' ' + + Objects.requireNonNull(CertUtil.getSubjectSurname(userCertificate)); + } + +} diff --git a/example/src/main/java/org/webeid/example/service/SigningService.java b/example/src/main/java/org/webeid/example/service/SigningService.java index f350dc2..43eddde 100644 --- a/example/src/main/java/org/webeid/example/service/SigningService.java +++ b/example/src/main/java/org/webeid/example/service/SigningService.java @@ -32,11 +32,13 @@ import org.springframework.core.io.ByteArrayResource; import org.springframework.stereotype.Service; import org.webeid.example.config.YAMLConfig; +import org.webeid.example.security.WebEidAuthentication; import org.webeid.example.service.dto.CertificateDTO; import org.webeid.example.service.dto.DigestDTO; import org.webeid.example.service.dto.FileDTO; import org.webeid.example.service.dto.SignatureDTO; import org.webeid.example.web.rest.SigningController; +import org.webeid.security.util.CertUtil; import javax.servlet.http.HttpSession; import javax.xml.bind.DatatypeConverter; @@ -74,13 +76,19 @@ private HttpSession currentSession() { * Prepares given container {@link Container} for the signature process. * * @param certificateDTO user's X.509 certificate + * @param authentication authenticated principal * @return data to be signed */ - public DigestDTO prepareContainer(CertificateDTO certificateDTO) throws CertificateException, NoSuchAlgorithmException, IOException { + public DigestDTO prepareContainer(CertificateDTO certificateDTO, WebEidAuthentication authentication) throws CertificateException, NoSuchAlgorithmException, IOException { + X509Certificate certificate = certificateDTO.toX509Certificate(); + if (!authentication.getIdCode().equals(CertUtil.getSubjectIdCode(certificate))) { + throw new IllegalArgumentException("Authenticated subject ID code differs from " + + "signing certificate subject ID code"); + } + FileDTO fileDTO = FileDTO.getExampleForSigningFromResources(); Container containerToSign = getContainerToSign(fileDTO); String containerName = generateContainerName(fileDTO.getName()); - X509Certificate certificate = certificateDTO.toX509Certificate(); currentSession().setAttribute(SESSION_ATTR_CONTAINER, containerToSign); currentSession().setAttribute(SESSION_ATTR_FILE, fileDTO); @@ -118,22 +126,16 @@ public DigestDTO prepareContainer(CertificateDTO certificateDTO) throws Certific * @return fileDTO */ public FileDTO signContainer(SignatureDTO signatureDTO) { - try { - FileDTO fileDTO = (FileDTO) Objects.requireNonNull(currentSession().getAttribute(SESSION_ATTR_FILE)); - Container containerToSign = (Container) Objects.requireNonNull(currentSession().getAttribute(SESSION_ATTR_CONTAINER)); - DataToSign dataToSign = (DataToSign) Objects.requireNonNull(currentSession().getAttribute(SESSION_ATTR_DATA)); - - byte[] signatureBytes = DatatypeConverter.parseBase64Binary(signatureDTO.getBase64Signature()); - Signature signature = dataToSign.finalize(signatureBytes); - containerToSign.addSignature(signature); - currentSession().setAttribute(SESSION_ATTR_CONTAINER, containerToSign); + FileDTO fileDTO = (FileDTO) Objects.requireNonNull(currentSession().getAttribute(SESSION_ATTR_FILE)); + Container containerToSign = (Container) Objects.requireNonNull(currentSession().getAttribute(SESSION_ATTR_CONTAINER)); + DataToSign dataToSign = (DataToSign) Objects.requireNonNull(currentSession().getAttribute(SESSION_ATTR_DATA)); - return new FileDTO(generateContainerName(fileDTO.getName())); + byte[] signatureBytes = DatatypeConverter.parseBase64Binary(signatureDTO.getBase64Signature()); + Signature signature = dataToSign.finalize(signatureBytes); + containerToSign.addSignature(signature); + currentSession().setAttribute(SESSION_ATTR_CONTAINER, containerToSign); - } catch (Exception ex) { - LOG.error("Signing of container caused an error", ex); - throw new RuntimeException("Signing of container caused an error"); - } + return new FileDTO(generateContainerName(fileDTO.getName())); } public String getContainerName() { diff --git a/example/src/main/java/org/webeid/example/web/rest/SigningController.java b/example/src/main/java/org/webeid/example/web/rest/SigningController.java index 5cb934f..652105c 100644 --- a/example/src/main/java/org/webeid/example/web/rest/SigningController.java +++ b/example/src/main/java/org/webeid/example/web/rest/SigningController.java @@ -27,6 +27,7 @@ import org.springframework.http.HttpHeaders; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; +import org.webeid.example.security.WebEidAuthentication; import org.webeid.example.service.SigningService; import org.webeid.example.service.dto.CertificateDTO; import org.webeid.example.service.dto.DigestDTO; @@ -48,8 +49,8 @@ public SigningController(SigningService signingService) { } @PostMapping("prepare") - public DigestDTO prepare(@RequestBody CertificateDTO data) throws CertificateException, NoSuchAlgorithmException, IOException { - return signingService.prepareContainer(data); + public DigestDTO prepare(@RequestBody CertificateDTO data, WebEidAuthentication authentication) throws CertificateException, NoSuchAlgorithmException, IOException { + return signingService.prepareContainer(data, authentication); } @PostMapping("sign") diff --git a/example/src/test/java/org/webeid/example/WebApplicationTest.java b/example/src/test/java/org/webeid/example/WebApplicationTest.java index 55838d8..499558c 100644 --- a/example/src/test/java/org/webeid/example/WebApplicationTest.java +++ b/example/src/test/java/org/webeid/example/WebApplicationTest.java @@ -112,7 +112,7 @@ public void validateOcspResponse(XadesSignature xadesSignature) { mvcBuilder.build().perform(get("/auth/challenge")); MockHttpServletResponse response = HttpHelper.login(mvcBuilder, session, ObjectMother.mockAuthToken()); - assertEquals("{\"sub\":\"JAAK-KRISTJAN JÕEORG, PNOEE-38001085718\",\"auth\":[\"ROLE_USER\"]}", response.getContentAsString()); + assertEquals("{\"sub\":\"JAAK-KRISTJAN JÕEORG\",\"auth\":[\"ROLE_USER\"]}", response.getContentAsString()); /* Example how to test file upload. response = HttpHelper.upload(mvcBuilder, session, ObjectMother.mockMultipartFile()); diff --git a/example/src/test/resources/signout.p12 b/example/src/test/resources/signout.p12 index c3454bc6ad75577b1eb2a898a12314f4278739fd..3fd499be5f210e1b691bfd189db564e0049eacc8 100644 GIT binary patch literal 2890 zcmY+EXE+-Q7snG4F=~_;wH0kp1QnyDN*g5htd$nEM~s?vix{P9&ng;QV^%0ywbiPc zFIsyxW@u5lDc;`adEa}V`{6w2d4B(M&WH2i2gflXX@InF920tAO z4?sA^T{w<$6OIF8{uO}@K{zn_H`e}LT69eR+q%FAq`~7rf5LH~V>pbC@&EYuab6HK z>d`xDd$n}pC6fLkpE%d2X~wpTG&CRp2nXudH3+7!2+Uqdk+roqY&Eo(5(C2p52r#W zUGA(WE>Ons=k6Jf26Fm`ZS8`?#a~dxVni=N5VsB!`jj>(;qa(IXd$|##s}M_3L~8F zpeUA_L9>>et4D2j2b2_=Xxcwc2TbH8^|dARe+hqXhzK~am3k|pqSPzP3GazH3}mWh zT8QD!b`lr)ib-s_0KfRfpR_OF`)T-Mu6i2JsK&EOiHXA+oK|b~l6f=0LMk=O$&c&% zTE}9MK!UCA;yuLu9!%RGiu7PrNzj@WyM!6FXivKxZAp&#%mj2D{WU8n`WPa{ICZLC z@i1+i3{2>rgzyKJ`$X6Yym2?fuM7xiXVk@^`giZ&`Z)EUwB|2t6^_md+ z_5kENtTc)LX|m&u!v5Z+Y%7t|5?d4D7!wgQCEb;eibKh-i4s#ke?K=2&6fO$G8B+` z9&7pV1<(mh@g~f_5^M^l5x`EdAHP1eAX?E2p zhwQKavX}6;hV|0BxkwPB*hdeaQxnZoWjO!LfekV{Rt834mW*rXk}q+HmAzjY>vMdv zr+RXxDQ>y@6xGyAn4aU5&);gJkGyxUB;1c@&N~f?x(XG?Um>8S)))j^1tKvD3gPyA zHN5JDcjVLaZdE-}!?QWm=sOi%?ile6zL(qkf+UJ zdb6&wWrAACVTcwp$wNi7|JEE4HMQsVY^ygM8;E&f_>Vug@o}Q_PYSo0?8~+6&&L7J za$f|zH{)cEeS7p~uv9a0uRV(uE0u#FT0Nn%qx4*Uea|*)1&`4iSFePN$esWtePkqy zBP=rAB&)Z)P2Rzn$uO!hkI?ysil37=TsUGIJ}wP-=1TA=(PBx!hf3M5Jg#Bh64^LY zSQ|1%(|9mYC&gU2p72R`#yH*Y6IYA*B|v%F>^HpcG`H}5GMHRF;l6t#=;l?)f=FxI z<3dcp_-KyV34&Y4C6wiss?h>lXA2r~y#%mhTmRsrIZzJAv}#k`A*~z#4#vK0brs<2 z#Xk4!d9H%sTTr*AvmU4TDwc;TQc&q zaVK&J_{G0X$pDoD3DN-M;3EGZPB|!u-OSC)Nmvdck5H0RQB+Yb#y8R~mg)W^OuYQYjgU$_Rw}h0c zCW~LtCbso<0Ofe(L9FQB4U*=IC0AFm*-Rhi_-u!*wzw~08M4Ls6t#X9gNy#n0=gRL zd-9Fai`PGdjpqAq5B4@soWr<;@ARcsx|qD&$ZiVO3$5sv@upJEMy#Jl((j)m_OiJ{ zl2gh|sVSF&lb-0Ox(LxJ#R|^_l`1!P_Z8`>CFWWKH9wz3p)p6A1ScCZW}0YiSNfxK z4U2?`QoR;inhF9AYxsgm*A}27UYMPgAC0dOMOaEiAR#qn{ASu5Pg8@3{Wttl_8J6R z-cVHJ&fBorK23Kl1c@Fok-I`Cdk4lS?89)H)a-LJ_hFfw^2T=ksQtKzLoW>=0Od#Y9wxkqJ_R$p@_jhlPBpb`}+Ns7XNb=mLR9S&KngQ;mr>nA* zW1$E2L0wx-MOoi&KTDSP5aaGQcp_B=bF|ViPS{pg$tP)?&1v`b#YePc9a5)J`5@CX=vWIxY+BtMyc@L5XM`k zyK0`P4Sx&^{(KfmmpVNPRzQkVD7UuceuiIS>EnAvA6RylUQMO`iEY$`L%E zpm_4U&r@nXFI1+v|v>d43I{%+mdn55{ir07_cb_KK zN!31GkGp(@OCpEg6x3M?6&@j=FvsR@9OAEq5reB$m13sevO5P>ilk2$(yVzQy1Ka7 zWki>5)x`%xQUsosMD`sit?&3y*T2cT2 literal 3061 zcmVU0s;sCfPw}PqM(J;*JmD>Je0p4NKD!Mb=w4{LB);vco=SMbbA}jABSd+*$VgI z`D~KJn{2nvDQW$|f&opF<;JUh<;rI?n}bCRv`x*sjGroQfk8~481tt$ZXm?5twx&I z??;27RhNi*&+8P$$2ONfRyJTAJaxA`8TZ6=0*o)t6GU~@XtGJJ!5gTxFyo_exg){4 zgiw1fhaukah`G{ir@48cCGxU{Ss06xpWSgq=dy;C>ekKpgbH=@HkL}y`7e4loA{XeL`!)z>gic+6{Uw7iO74Z&C z^WG&nDA7Fmoma*$I+(|wUQy zCxWzkjQti|0~kGoHrf|%h>F2El564%>t`|_3wt5>$sJu|AcWmP*}&;GR#PuB*`j7V zIzja*n2b%VY?0Yt#T+%s4;J)%A}vNM4yHv+kY-gQ$(>DhT(M`xEG{n?+M61{bt*Sn zri*$+Tv{a2goT6d6i$2S18?ktQ7f2s;t|8`e*Z0D14!RoA-*hhCN6WktdxMvv`EsF zAO*)q^@5`q226y@na6D9_z)t<$oimKP(3pbo2NnB@5fuxgmLA(J_CY#0F+m&EZTO% z*2~S>fy$IJkysayz3wJWv>USJ zlRR0H4zfnl<4TnBV?8^5j$Z`HkDz;d*J-=>aVP4`C=ipwJqG~;-wzmXu*y7;qB62V z7wIqPeO((b-WM;Os_r)W;*%JR6sUPm#pgOT-j~{JJH`tLFrWY(r_FFvxk=7hLeYjeLVt2TtpsaR&YG28=g^0uCy984dxpHwK!A| zDW#ff(-$Gi=T&2kH8xKAL7U|#lIq*YFI+Y%j59D2+kL)F-aNyHybgHM2{oo&qtv3V zqBa`xv|%A+*U~B~)Dx9*Ul<8?;Xpwal-yv@Ga!rRPaIU78Nuvq)&d2&Trd95q6zF0 zeNHs3r;+UuWaWb|onc~R`Lk|vRgj#x;-wh^fhDZjfE$542@IBHUfs#?7_z=r`hl~7 zIPGOO7dyGqZd;Z&fou-jdN90*N{U#^Pd(XkQvj-T{Fzl8sZGz+G* z&L$q|38}9P#e7z!!BM=My=HvQ(4CUAah*`$q!+VICZVcvG*vsTlBM{s9Rk>vs(%|- zPN*BaD339D25ZI~#gF$F!%{_gboa40s)_MMC*+VnsJG==X|zT4=2`#~o#s?qs_9~9 zgRrtgN|5-Ni@5AteGyvl4Ct9xtAny_m-gTk)H%+fs8k16-g`poS5$Pwf9WIrC_*U| zepHA}-iVhP$A!Qo>+F0x>8nLSUB}6Jh>quTeM76`l~#7_>{x>PU22-8?VBL8mI8=p z`a?fb9a5KsIhrB~`E4;VlVJs=T|$=H1hjK2m&N&;}Oa>jvusym@Qn8{)-N5bpoRcphl|@0fdX&LNQU%yP)?7>=6)%#4 z9b7AushQyH)vQ}-!M@UzgJ&acco_X)*h;c0?(*Mxui#x;_t59Kz%sZAt}!0mGmxQ_y$#v!_A{V> zUJhm%)nubHA4eH_LzoCD>`RVurFx|7V0E08q5WPULI0WEBlE-k@wtCbHYNmFLwSIo zHi>xKm7Q<0P@;onh21dM4e|Q!QJ+IREUVR*xPBiZlNS4-Mj2bimERtAVNY=tRtD7K z=pW*}d94^3<0JB}JoD>=Us~c|^n0jSOv(2m{}NpkC;G-@RvYd+)k-17AB)pUx%A)o z9!XE5Hr6>7{e=y@B6;OACMA%q1ybcFY=A?{iQ1eJMi`Y3Y<8ahtc&$XTuX))3bPkE z0`x7P_X-2ty0Rt|!9`KK7Tj-~`~}_)h!)yXuhj;fk>W-u7$@}Reujz0Z`(*>9-S9g zK{j%8kNs~8{HtT{U9y@jZi9?aO;$z3f)wkuibAWU42P!+=Hx1M)iudKig-o#Q)*lZ z!Tx0gUs!68SD8^EqYNFjK?d8zAhxpdl5K0dBySU~Sl7YyNkG56L7GTJe zwiKe<9K2|T7zFHm|Dsh46z9?vB56F1y*Xj~X3-T!I2-u_1fP!GtfSbKsJ*yk9naPD zdeEEsR6^2F7Tf$qC~c84GOFFeL(c%Jry*H9jf9V=T9RSMBT;d>KQ{56-y}<oc(5EGaFA`U4Wt34ePhGz>It(aT2XwAAq9k;)uW~?foZa7@! z(2BDq<6p%t;UycYSYj)=VbB_x%JF8&7zZ=qvm;KHI>1|>23Qqbj+}MZ&{IftkLR6B zgYf$?Ik%LY^a{BcSbG=me0ad6fQ_O(+Ht-FlM~0dwf4zW2A2B8+(_tA7_Fm>gL^pc z(1E2~<+}>Iiwh=S^$qF+2(5PkYw5<}Q+|sIH%-_BxbV+?C*l!_!kaT1%lbKtOsY>vxPdnR0{<|h>TV}X%>maczTXduHwB=4XI9ON$<(Sfw;tt7FX0ulBf$O#RM z0}??r1sQyeoY;+b4k2EJ+o>!s)^#Ke$DkzjJj}zUICqyE7&zFv0)(l`zJb~O;f=`?q7q_XG zy;Ezm6H~X+JS8-EE`PyA9$EG37?MoE$c0s;sC DF8QKu From 1659862b1029aa73b522b58f8b30530f1ec4969a Mon Sep 17 00:00:00 2001 From: Mart Somermaa Date: Fri, 23 Jul 2021 22:29:20 +0300 Subject: [PATCH 038/116] deps(web-eid-authtoken-validation-java): update to v1.1.0, use ZonedDateTime Refs WE2-458 Signed-off-by: Mart Somermaa --- example/pom.xml | 2 +- .../config/SameSiteCookieConfiguration.java | 22 +++++++++++++++++++ .../config/ValidationConfiguration.java | 14 ++++++------ .../AuthTokenDTOAuthenticationProvider.java | 3 +-- .../security/WebEidAuthentication.java | 22 +++++++++++++++++++ .../example/service/SigningService.java | 2 +- .../example/web/rest/ChallengeController.java | 2 -- .../example/web/rest/SigningController.java | 2 +- .../webeid/example/WebApplicationTest.java | 9 ++++---- 9 files changed, 60 insertions(+), 18 deletions(-) diff --git a/example/pom.xml b/example/pom.xml index 1684073..4a44fee 100644 --- a/example/pom.xml +++ b/example/pom.xml @@ -20,7 +20,7 @@ 1.8 2.22.1 2.8.5 - 1.0.2 + 1.1.0 1.44 diff --git a/example/src/main/java/org/webeid/example/config/SameSiteCookieConfiguration.java b/example/src/main/java/org/webeid/example/config/SameSiteCookieConfiguration.java index 2183a9f..f735424 100644 --- a/example/src/main/java/org/webeid/example/config/SameSiteCookieConfiguration.java +++ b/example/src/main/java/org/webeid/example/config/SameSiteCookieConfiguration.java @@ -1,3 +1,25 @@ +/* + * Copyright (c) 2021 The Web eID Project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + package org.webeid.example.config; import org.apache.tomcat.util.http.Rfc6265CookieProcessor; diff --git a/example/src/main/java/org/webeid/example/config/ValidationConfiguration.java b/example/src/main/java/org/webeid/example/config/ValidationConfiguration.java index c52854a..eb79607 100644 --- a/example/src/main/java/org/webeid/example/config/ValidationConfiguration.java +++ b/example/src/main/java/org/webeid/example/config/ValidationConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 The Web eID Project + * Copyright (c) 2020, 2021 The Web eID Project * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -49,7 +49,7 @@ import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; -import java.time.LocalDateTime; +import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; @@ -69,9 +69,9 @@ public CacheManager cacheManager() { } @Bean - public Cache nonceCache() { + public Cache nonceCache() { final CacheManager cacheManager = cacheManager(); - Cache cache = cacheManager.getCache(CACHE_NAME); + Cache cache = cacheManager.getCache(CACHE_NAME); if (cache == null) { cache = createNonceCache(cacheManager); @@ -149,9 +149,9 @@ public YAMLConfig yamlConfig() { return new YAMLConfig(); } - private Cache createNonceCache(CacheManager cacheManager) { - CompleteConfiguration cacheConfig = new MutableConfiguration() - .setTypes(String.class, LocalDateTime.class) + private Cache createNonceCache(CacheManager cacheManager) { + CompleteConfiguration cacheConfig = new MutableConfiguration() + .setTypes(String.class, ZonedDateTime.class) .setExpiryPolicyFactory(factoryOf(new CreatedExpiryPolicy( new Duration(TimeUnit.MINUTES, NONCE_TTL_MINUTES + 1)))); return cacheManager.createCache(CACHE_NAME, cacheConfig); diff --git a/example/src/main/java/org/webeid/example/security/AuthTokenDTOAuthenticationProvider.java b/example/src/main/java/org/webeid/example/security/AuthTokenDTOAuthenticationProvider.java index 1f27338..db63854 100644 --- a/example/src/main/java/org/webeid/example/security/AuthTokenDTOAuthenticationProvider.java +++ b/example/src/main/java/org/webeid/example/security/AuthTokenDTOAuthenticationProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 The Web eID Project + * Copyright (c) 2020, 2021 The Web eID Project * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -35,7 +35,6 @@ import org.springframework.stereotype.Component; import org.webeid.example.security.dto.AuthTokenDTO; import org.webeid.security.exceptions.TokenValidationException; -import org.webeid.security.util.CertUtil; import org.webeid.security.validator.AuthTokenValidator; import java.security.cert.CertificateEncodingException; diff --git a/example/src/main/java/org/webeid/example/security/WebEidAuthentication.java b/example/src/main/java/org/webeid/example/security/WebEidAuthentication.java index f935aab..6c5ec3c 100644 --- a/example/src/main/java/org/webeid/example/security/WebEidAuthentication.java +++ b/example/src/main/java/org/webeid/example/security/WebEidAuthentication.java @@ -1,3 +1,25 @@ +/* + * Copyright (c) 2021 The Web eID Project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + package org.webeid.example.security; import org.springframework.security.core.Authentication; diff --git a/example/src/main/java/org/webeid/example/service/SigningService.java b/example/src/main/java/org/webeid/example/service/SigningService.java index 43eddde..ed90ad1 100644 --- a/example/src/main/java/org/webeid/example/service/SigningService.java +++ b/example/src/main/java/org/webeid/example/service/SigningService.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 The Web eID Project + * Copyright (c) 2020, 2021 The Web eID Project * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/example/src/main/java/org/webeid/example/web/rest/ChallengeController.java b/example/src/main/java/org/webeid/example/web/rest/ChallengeController.java index 602a11d..677539b 100644 --- a/example/src/main/java/org/webeid/example/web/rest/ChallengeController.java +++ b/example/src/main/java/org/webeid/example/web/rest/ChallengeController.java @@ -22,8 +22,6 @@ package org.webeid.example.web.rest; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; diff --git a/example/src/main/java/org/webeid/example/web/rest/SigningController.java b/example/src/main/java/org/webeid/example/web/rest/SigningController.java index 652105c..65030b7 100644 --- a/example/src/main/java/org/webeid/example/web/rest/SigningController.java +++ b/example/src/main/java/org/webeid/example/web/rest/SigningController.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 The Web eID Project + * Copyright (c) 2020, 2021 The Web eID Project * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/example/src/test/java/org/webeid/example/WebApplicationTest.java b/example/src/test/java/org/webeid/example/WebApplicationTest.java index 499558c..da36307 100644 --- a/example/src/test/java/org/webeid/example/WebApplicationTest.java +++ b/example/src/test/java/org/webeid/example/WebApplicationTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 The Web eID Project + * Copyright (c) 2020, 2021 The Web eID Project * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -41,11 +41,12 @@ import org.webeid.example.testutil.Dates; import org.webeid.example.testutil.HttpHelper; import org.webeid.example.testutil.ObjectMother; +import org.webeid.security.util.UtcDateTime; import org.webeid.security.validator.AuthTokenValidatorData; import org.webeid.security.validator.validators.SubjectCertificateNotRevokedValidator; import javax.cache.Cache; -import java.time.LocalDateTime; +import java.time.ZonedDateTime; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; @@ -55,7 +56,7 @@ public class WebApplicationTest { @Autowired - Cache cache; + Cache cache; @Autowired private WebApplicationContext context; @@ -102,7 +103,7 @@ public void validateOcspResponse(XadesSignature xadesSignature) { } }; - cache.put(TEST_NONCE, LocalDateTime.now().plusMinutes(5)); + cache.put(TEST_NONCE, UtcDateTime.now().plusMinutes(5)); final MockHttpSession session = new MockHttpSession(); From 85f66f8ee198eb07c7ea497785dc3d75a34551ab Mon Sep 17 00:00:00 2001 From: Mart Somermaa Date: Tue, 27 Jul 2021 13:46:59 +0300 Subject: [PATCH 039/116] release(html): web-eid release v1.0.0 Signed-off-by: Mart Somermaa --- .../js/{web-eid-0.9.0.js => web-eid-1.0.0.js} | 15 +++++++-- .../src/main/resources/templates/index.html | 32 +++++-------------- .../welcome-with-file-upload-support.html | 2 +- .../src/main/resources/templates/welcome.html | 2 +- 4 files changed, 22 insertions(+), 29 deletions(-) rename example/src/main/resources/static/js/{web-eid-0.9.0.js => web-eid-1.0.0.js} (97%) diff --git a/example/src/main/resources/static/js/web-eid-0.9.0.js b/example/src/main/resources/static/js/web-eid-1.0.0.js similarity index 97% rename from example/src/main/resources/static/js/web-eid-0.9.0.js rename to example/src/main/resources/static/js/web-eid-1.0.0.js index b5b7419..3a017bb 100644 --- a/example/src/main/resources/static/js/web-eid-0.9.0.js +++ b/example/src/main/resources/static/js/web-eid-1.0.0.js @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 The Web eID Project + * Copyright (c) Estonian Information System Authority * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -19,9 +19,8 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ - var config = Object.freeze({ - VERSION: "0.9.0", + VERSION: "1.0.0", EXTENSION_HANDSHAKE_TIMEOUT: 1000, NATIVE_APP_HANDSHAKE_TIMEOUT: 5 * 1000, DEFAULT_USER_INTERACTION_TIMEOUT: 2 * 60 * 1000, @@ -51,6 +50,7 @@ var ErrorCode; // Third party errors ErrorCode["ERR_WEBEID_SERVER_REJECTED"] = "ERR_WEBEID_SERVER_REJECTED"; ErrorCode["ERR_WEBEID_USER_CANCELLED"] = "ERR_WEBEID_USER_CANCELLED"; + ErrorCode["ERR_WEBEID_NATIVE_INVALID_ARGUMENT"] = "ERR_WEBEID_NATIVE_INVALID_ARGUMENT"; ErrorCode["ERR_WEBEID_NATIVE_FATAL"] = "ERR_WEBEID_NATIVE_FATAL"; // Developer mistakes ErrorCode["ERR_WEBEID_ACTION_PENDING"] = "ERR_WEBEID_ACTION_PENDING"; @@ -116,6 +116,14 @@ class ActionPendingError extends Error { } } +class NativeInvalidArgumentError extends Error { + constructor(message = "native application received an invalid argument") { + super(message); + this.name = this.constructor.name; + this.code = ErrorCode$1.ERR_WEBEID_NATIVE_INVALID_ARGUMENT; + } +} + class NativeFatalError extends Error { constructor(message = "native application terminated with a fatal error") { super(message); @@ -257,6 +265,7 @@ const errorCodeToErrorClass = { [ErrorCode$1.ERR_WEBEID_ORIGIN_MISMATCH]: OriginMismatchError, [ErrorCode$1.ERR_WEBEID_CONTEXT_INSECURE]: ContextInsecureError, [ErrorCode$1.ERR_WEBEID_EXTENSION_UNAVAILABLE]: ExtensionUnavailableError, + [ErrorCode$1.ERR_WEBEID_NATIVE_INVALID_ARGUMENT]: NativeInvalidArgumentError, [ErrorCode$1.ERR_WEBEID_NATIVE_FATAL]: NativeFatalError, [ErrorCode$1.ERR_WEBEID_NATIVE_UNAVAILABLE]: NativeUnavailableError, [ErrorCode$1.ERR_WEBEID_PROTOCOL_INSECURE]: ProtocolInsecureError, diff --git a/example/src/main/resources/templates/index.html b/example/src/main/resources/templates/index.html index 9be1e83..b471103 100644 --- a/example/src/main/resources/templates/index.html +++ b/example/src/main/resources/templates/index.html @@ -46,37 +46,22 @@

        Table of contents


        Usage

        - Instructions for installing and testing version 1.0.0-rc2 in Firefox, Chrome, Edge or Safari: + Instructions for installing and testing version 1.0.0 in Firefox, Chrome, Edge or Safari:

        1. Download and run the Web eID native app and browser extension installer:
          • on Ubuntu Linux 20.04, for Firefox and Chrome from here, + href="https://installer.id.ee/media/web-eid/web-eid_1.0.0.521-2004_amd64.deb">here, install it with either the Ubuntu Software Center or from the console with
            - sudo apt install ./web-eid_1.0.0.511_amd64.deb + sudo apt install ./web-eid_[version].deb
          • -
          • on macOS 10.15 or later, -
              -
            • - for Firefox from here, -
            • -
            • - for Chrome from here; -
            • -
            • - Safari extension is also available from here, - but it is not yet signed, so it is not currently possible to enable it; a signed - release will be available shortly. -
            • -
            +
          • on macOS 10.15 or later, for Firefox, Chrome and Safari from here,
          • on Windows 10 (64-bit), for Firefox, Chrome and Edge from here. + href="https://installer.id.ee/media/web-eid/web-eid_1.0.0.527.exe">here.
        2. @@ -84,8 +69,7 @@

          Usage

          The installer will install the browser extension for all supported browsers automatically. The extension must be manually enabled from either the extension installation pop-up that appears in the browser or from the browser extensions management page and may need browser restart under - certain - circumstances. + certain circumstances.
        3. Attach a smart card reader to the computer and insert the eID card into the reader. @@ -215,7 +199,7 @@

          For developers

          diff --git a/example/src/main/resources/templates/welcome-with-file-upload-support.html b/example/src/main/resources/templates/welcome-with-file-upload-support.html index ed815e6..f13ab58 100644 --- a/example/src/main/resources/templates/welcome-with-file-upload-support.html +++ b/example/src/main/resources/templates/welcome-with-file-upload-support.html @@ -37,8 +37,8 @@

          Sign a document