Skip to content

Move web-eid-spring-boot-example into web-eid-authtoken-validation-java/example #76

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 117 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
117 commits
Select commit Hold shift + click to select a range
d65ca1b
Add license
mrts Dec 21, 2020
f02ef49
Initial commit
mrts Dec 21, 2020
3222b3c
Add macOS installer
mrts Dec 28, 2020
4170767
Add Ubuntu and Windows installer
mrts Dec 28, 2020
05ac09e
build(deps): use GitHub Packages for authtoken-validation, update Gua…
mrts Feb 19, 2021
0aeafc0
feat: add configurable support for DigiDoc4j prod mode, enable OCSP c…
mrts Feb 19, 2021
f8b878f
fix: mock OCSP checks with JMock to make testHappyFlow_LoginUploadPre…
mrts Feb 19, 2021
7e7b93a
ci: use GitLab Package Repository instead of GitHub as GitHub Package…
mrts Feb 22, 2021
836e1fd
deployment: add Fabric deployment script, fix okhttp version
mrts Feb 22, 2021
3d298ea
refactor: use Caffeine instead of Hazelcast
mrts Feb 22, 2021
99ede25
docs,installer: update installer packages to 0.9.4.76, update instruc…
mrts Feb 23, 2021
91baa01
feat: use AIA OCSP and LT profile during signing, bump authtoken-vali…
mrts Feb 23, 2021
f98f208
feat: add a static example text document for testing signing, disable…
mrts Feb 23, 2021
4cdce5a
deps: update code to web-eid-authtoken v1.0.1 API
mrts Mar 1, 2021
b841861
conf: bump org.webeid log level to DEBUG
mrts Mar 4, 2021
7666d50
Update README.md
Counter178 Mar 15, 2021
c5ac11c
Update authtoken-validation to 1.0.2, web-eid package to 9.4.0-rc1, a…
mrts Mar 15, 2021
5ca0033
Add documentation and developers sections to index.html
mrts Mar 15, 2021
c77f6b7
doc: add contact info to index.html
mrts Mar 16, 2021
b7710ba
doc: mention Croatian eID support, Ubuntu Software Center
mrts Mar 18, 2021
d1fcac2
doc: mention Ubuntu Software Center during unistall
mrts Mar 18, 2021
cad6168
fix(html): make welcome page error box similar to auth page
mrts Mar 19, 2021
4a08590
fix(signing): update DigiDoc4j to mitigate LOTL change issue
mrts Mar 30, 2021
8df70f1
release(html): web-eid-app release downloads 0.9.4-rc1 -> 0.9.4
mrts Apr 6, 2021
3d02a22
relase(html): web-eid-app release 0.9.4 -> 1.0.0-rc1 with tentative S…
mrts Apr 30, 2021
ca6b814
doc: make OS name bold
mrts May 6, 2021
6b8c9a7
docs(index.html): add command for turning on Safari extension logging
mrts May 10, 2021
f7382a4
doc: HKEY_CURRENT_USER, not HKEY_LOCAL_MACHINE
mrts Jun 1, 2021
15d3992
doc: add link to project website
mrts Jun 1, 2021
cfe7fe1
release(html): web-eid-app release 1.0.0-rc2
mrts Jun 11, 2021
8a6b579
conf: forward HTTPS information from reverse proxy to Tomcat so that …
mrts Jul 12, 2021
940e318
feat(config): add SameSite cookie configuration
mrts Jul 13, 2021
27c2185
doc: document HTTPS support
mrts Jul 13, 2021
d207c18
css: load Bootstrap CSS from resources instead of CDN
mrts Jul 15, 2021
0f77c9a
security: turn on CSRF protection
mrts Jul 15, 2021
7174d87
refactor: move settings from application.properties to application.yaml
mrts Jul 15, 2021
c8746bf
feat(security): assure that authenticated subject matches with signin…
mrts Jul 19, 2021
1659862
deps(web-eid-authtoken-validation-java): update to v1.1.0, use ZonedD…
mrts Jul 23, 2021
85f66f8
release(html): web-eid release v1.0.0
mrts Jul 27, 2021
7583afd
doc(html): Safari support is upcoming
mrts Jul 29, 2021
e944825
doc(html): update macOS uninstallation instructions, log locations an…
mrts Aug 3, 2021
ddcd169
doc(README): rework documentation and trim configuration
mrts Aug 5, 2021
1b593f8
fix(doc): fix anchor in README
mrts Aug 31, 2021
2538f44
Mentioning all the people involved in making the example application.
pahaloom Sep 7, 2021
004b858
release(html,deps): Safari first public release v1.0.2, update web-ei…
mrts Oct 26, 2021
bcabac7
feat: migrate to authtoken-validation v2, add session-backed challeng…
mrts Nov 16, 2021
b6d0eba
docs: update README with v2 information
mrts Jan 21, 2022
5af811b
feat: add Ubuntu installation script
mrts Feb 4, 2022
ee4af45
add -y to install packages without user prompt
heikkikitt Feb 15, 2022
d2b067c
docs,tests: update security analysis link, remove unused parameters f…
mrts Mar 11, 2022
41f635d
deps: upgrade Spring Boot and other dependencies
mrts Apr 1, 2022
06d72c2
Update LICENSE
kristelmerilain Jun 2, 2022
2e929fa
release: Web eID release v2.1.0
mrts Jul 26, 2022
e2898ba
deps: roll back DigiDoc4j to version 4.3.0
mrts Jul 26, 2022
3ac4dc2
docs(index.html): use Web eID in a Java or .NET web application
mrts Aug 1, 2022
de06fab
docs(index.html),script: emphazise latest official Open EID packages,…
mrts Aug 31, 2022
de4ba2f
docs(index.html): add section how to verify if debugging works as req…
mrts Aug 31, 2022
e514fb2
deps(web-eid-authtoken-validation): bump authtoken-validation version…
mrts Oct 14, 2022
4a80707
refactor,fix: fix logging package name in application.yaml, enable su…
mrts Nov 7, 2022
a3285a6
feat: add support for organization certificates
mrts Nov 9, 2022
e65499e
Add bullseye, Linux Mint 21 and kinetic and remove impish support
kristelmerilain Nov 16, 2022
c4f9eb4
Update Ubuntu package version
kristelmerilain Nov 29, 2022
3a6cf18
docs(README): explain how to run the application with prod profile
mrts Nov 30, 2022
7420e22
docs(README): add CertificateNotTrustedException to FAQ
mrts Nov 30, 2022
533f421
release: Web eID release v2.2.0, PHP validation library published
mrts Dec 27, 2022
1693dbd
docs(index.html): Belgian cards are supported now
mrts Jan 20, 2023
282dec2
chore: update copyright year
mrts Jan 20, 2023
c435c0f
Remove bionic support (#22)
kristelmerilain Mar 1, 2023
abf97d0
Update Ubuntu package version and add bookworm support
kristelmerilain Apr 19, 2023
acf1abb
Update copyright year (#24)
kristelmerilain Apr 27, 2023
6a5760d
build(deps): bump guava from 31.1-jre to 32.0.0-jre
dependabot[bot] Jun 14, 2023
511e254
release: Web eID release v2.3.0/1
mrts Jul 11, 2023
934145e
Update download-install-web-eid.sh
metsma Jul 28, 2023
1eb3ba2
Update Ubuntu package version (#28)
kristelmerilain Aug 4, 2023
62933e1
deps: update to Java 11 and web-eid-authtoken-validation v3, get rid …
mrts Aug 7, 2023
6ce5720
deps: update DigiDoc4j to v5.1.0
mrts Aug 24, 2023
627d448
refactor: use ZonedDateTime in tests instead of Date
mrts Aug 24, 2023
048d3ba
refactor: better signature digest algorithm handling and name validation
mrts Aug 24, 2023
8a8ed7a
refactor,fix(tests): mock BLevelParameters.getSigningDate() instead o…
mrts Aug 25, 2023
950f63e
deps: upgrade DigiDoc4j to v5.2.0 and Spring Boot to 2.7.15
mrts Sep 5, 2023
880933f
fix: use correct JSON property names in SignatureAlgorithmDTO, add d…
mrts Sep 5, 2023
5d6bcfb
feat: validate signature algorithm values
mrts Sep 7, 2023
2d3bcf9
Remove kinetic support (#33)
kristelmerilain Oct 2, 2023
92fa4ac
Update download-install-web-eid.sh (#34)
kristelmerilain Oct 9, 2023
6656005
Add mantic support (#35)
kristelmerilain Nov 3, 2023
26de20d
Update tests
metsma Nov 7, 2023
55f2057
Update Ubuntu package version (#37)
kristelmerilain Nov 29, 2023
69fc172
Logout accpets POST requests
metsma Jan 5, 2024
559e5cd
Use session fixation protection strategy
metsma Jan 5, 2024
07663e7
All ID-Card certificates are expired in EstEID 2015
metsma Jan 5, 2024
1c0e551
Set __Host- prefix to session cookie
metsma Jan 5, 2024
ada443e
Update copyright year
metsma Mar 19, 2024
311dece
Remove lunar support (#46)
kristelmerilain Apr 11, 2024
4a7eeaf
Add v2.5.0 release
mrts Apr 26, 2024
bfc2673
Upgrade to Spring Boot 3/Spring Security 6
Apr 3, 2024
05e6269
Clean up pom.xml
mrts Apr 5, 2024
bfe9739
Make FileDTO Serializable, enable Thymeleaf cache in production, use …
mrts Apr 5, 2024
e46a462
Secure endpoints and services that require authentication
mrts Apr 5, 2024
33faef1
Override equals() and hashCode() in WebEidAuthentication
mrts Apr 5, 2024
8b4bf6d
Use method injection to provide AuthTokenDTOAuthenticationProvider an…
mrts Apr 5, 2024
3db96fd
Use Java 17 base image in Jib
mrts Apr 30, 2024
1b55e1b
Use Optional in CertificateData
mrts May 7, 2024
e6200b8
Add new TEST ORG certificate issuers
metsma May 1, 2024
0313507
Update Web eID group ID to eu.webeid.security, amend REAME (#51)
mrts May 31, 2024
aa651e8
Add Belgian test CA certs, bump Docker image to 3.1.0 and update path…
mrts Jun 3, 2024
750beb6
Add noble support
kristelmerilain Jun 14, 2024
5083fe4
Remove mantic support (#54)
kristelmerilain Aug 1, 2024
1d06df3
Update and rename download-install-web-eid.sh to install-web-eid.sh (…
kristelmerilain Oct 3, 2024
fe496e2
Add v2.6.0 release (#56)
mrts Oct 22, 2024
2d695af
Add oracular support (#57)
kristelmerilain Nov 19, 2024
88072f3
Remove focal support
kristelmerilain Jan 27, 2025
e7dccc8
Add Thales test ID card intermediate CA to trusted certificates in de…
mrts Mar 20, 2025
07e0ca1
Update copyright year to 2025
mrts Mar 21, 2025
f54db1b
Bump version to 3.1.1, update dependencies
mrts Mar 21, 2025
6f5c643
Merge web-eid-spring-boot-example into web-eid-authtoken-validation-j…
svenzik May 6, 2025
a945f5b
Update README.md
svenzik May 6, 2025
a13c5ca
Move example project workflow to parent, add build scripts and sonar
svenzik May 6, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions .github/workflows/maven-build-example.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Maven build example

on:
push:
paths:
- 'example/**'
- '.github/workflows/*example*'
pull_request:
paths:
- 'example/**'
- '.github/workflows/*example*'

defaults:
run:
working-directory: ./example

jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- uses: actions/setup-java@v4
with:
distribution: zulu
java-version: 17

- name: Cache Maven packages
uses: actions/cache@v4
with:
path: ~/.m2
key: ${{ runner.os }}-m2-v17-${{ secrets.CACHE_VERSION }}-${{ hashFiles('**/pom.xml') }}
restore-keys: ${{ runner.os }}-m2-v17-${{ secrets.CACHE_VERSION }}

- name: Build
run: mvn --batch-mode compile

- name: Test and package
run: mvn --batch-mode package

10 changes: 9 additions & 1 deletion .github/workflows/maven-build.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
name: Maven build

on: [ push, pull_request ]
on:
push:
paths-ignore:
- 'example/**'
- '.github/workflows/*example*'
pull_request:
paths-ignore:
- 'example/**'
- '.github/workflows/*example*'

jobs:
build:
Expand Down
10 changes: 9 additions & 1 deletion .github/workflows/sonarcloud-analysis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
name: SonarCloud code analysis

on: [push, pull_request]
on:
push:
paths-ignore:
- 'example/**'
- '.github/workflows/*example*'
pull_request:
paths-ignore:
- 'example/**'
- '.github/workflows/*example*'

jobs:
analyze:
Expand Down
11 changes: 6 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ A Java web application that uses Maven or Gradle to manage packages is needed fo

In the following example we are using the [Spring Framework](https://spring.io/), but the examples can be easily ported to other Java web application frameworks.

See the full example [here](https://github.com/web-eid/web-eid-spring-boot-example).
## Full example project using the validation library in spring-boot
[example/README.md](example/README.md)

## 1. Add the library to your project

Expand Down Expand Up @@ -98,7 +99,7 @@ import eu.webeid.security.challenge.ChallengeNonceStore;

## 4. Add trusted certificate authority certificates

You must explicitly specify which **intermediate** certificate authorities (CAs) are trusted to issue the eID authentication and OCSP responder certificates. CA certificates can be loaded from either the truststore file, resources or any stream source. We use the [`CertificateLoader`](https://github.com/web-eid/web-eid-authtoken-validation-java/blob/main/src/main/java/eu/webeid/security/certificate/CertificateLoader.java) helper class to load CA certificates from resources here, but consider using [the truststore file](https://github.com/web-eid/web-eid-spring-boot-example/blob/main/src/main/java/eu/webeid/example/config/ValidationConfiguration.java#L104-L123) instead.
You must explicitly specify which **intermediate** certificate authorities (CAs) are trusted to issue the eID authentication and OCSP responder certificates. CA certificates can be loaded from either the truststore file, resources or any stream source. We use the [`CertificateLoader`](https://github.com/web-eid/web-eid-authtoken-validation-java/blob/main/src/main/java/eu/webeid/security/certificate/CertificateLoader.java) helper class to load CA certificates from resources here, but consider using [the truststore file](./blob/example/main/src/main/java/eu/webeid/example/config/ValidationConfiguration.java#L104-L123) instead.

First, copy the trusted certificates, for example `ESTEID2018.cer`, to `resources/cacerts/`, then load the certificates as follows:

Expand Down Expand Up @@ -171,11 +172,11 @@ Authentication consists of calling the `validate()` method of the authentication

When using [Spring Security](https://spring.io/guides/topicals/spring-security-architecture) with standard cookie-based authentication,

- implement a custom authentication provider that uses the authentication token validator for authentication as shown [here](https://github.com/web-eid/web-eid-spring-boot-example/blob/main/src/main/java/eu/webeid/example/security/AuthTokenDTOAuthenticationProvider.java),
- implement an AJAX authentication processing filter that extracts the authentication token and passes it to the authentication manager as shown [here](https://github.com/web-eid/web-eid-spring-boot-example/blob/main/src/main/java/eu/webeid/example/security/WebEidAjaxLoginProcessingFilter.java),
- implement a custom authentication provider that uses the authentication token validator for authentication as shown [here](example/blob/main/src/main/java/eu/webeid/example/security/AuthTokenDTOAuthenticationProvider.java),
- implement an AJAX authentication processing filter that extracts the authentication token and passes it to the authentication manager as shown [here](example/blob/main/src/main/java/eu/webeid/example/security/WebEidAjaxLoginProcessingFilter.java),
- configure the authentication provider and authentication processing filter in the application configuration as shown [here](https://github.com/web-eid/web-eid-spring-boot-example/blob/main/src/main/java/eu/webeid/example/config/ApplicationConfiguration.java).

The gist of the validation is [in the `authenticate()` method](https://github.com/web-eid/web-eid-spring-boot-example/blob/main/src/main/java/eu/webeid/example/security/AuthTokenDTOAuthenticationProvider.java#L74-L76) of the authentication provider:
The gist of the validation is [in the `authenticate()` method](example/blob/main/src/main/java/eu/webeid/example/security/AuthTokenDTOAuthenticationProvider.java#L74-L76) of the authentication provider:

```java
try {
Expand Down
19 changes: 19 additions & 0 deletions example/.gitattributes
Original file line number Diff line number Diff line change
@@ -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
34 changes: 34 additions & 0 deletions example/.gitignore
Original file line number Diff line number Diff line change
@@ -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
121 changes: 121 additions & 0 deletions example/.mvn/wrapper/MavenWrapperDownloader.java
Original file line number Diff line number Diff line change
@@ -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();
}
}
Binary file added example/.mvn/wrapper/maven-wrapper.jar
Binary file not shown.
2 changes: 2 additions & 0 deletions example/.mvn/wrapper/maven-wrapper.properties
Original file line number Diff line number Diff line change
@@ -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
7 changes: 7 additions & 0 deletions example/.prettierrc.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
trailingComma: "none"
useTabs: false
tabWidth: 4
semi: true
singleQuote: false
printWidth: 120

7 changes: 7 additions & 0 deletions example/AUTHORS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Contributors

Here is the list of people involved in creating the example application.

Juri Letberg
Mart Sõmermaa
Martin Ott
21 changes: 21 additions & 0 deletions example/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2020-2023 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
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.
Loading
Loading