35 Commits

Author SHA1 Message Date
bbceee35f2 test against Vault 1.8.0
All checks were successful
continuous-integration/drone/push Build is passing
2021-07-28 19:38:06 +02:00
3a920fe960 prepare release 0.9.5
All checks were successful
continuous-integration/drone/push Build is passing
2021-07-28 19:34:48 +02:00
eed61c4569 minor dependency updates
All checks were successful
continuous-integration/drone/push Build is passing
2021-07-27 21:25:20 +02:00
53d954ea12 deprecate all convenience methods to interact with "secret/" mount
All checks were successful
continuous-integration/drone/push Build is passing
Follow-up deprecation for the not yet deprecated wrapper methods.
2021-06-12 10:46:10 +02:00
e578591a49 deprecate convenience methods to interact with "secret/" mount (#52)
All checks were successful
continuous-integration/drone/push Build is passing
2021-06-11 21:33:59 +02:00
de17f48be2 move builder into main package, introduce new invocation method (#51)
Some checks failed
continuous-integration/drone/push Build is failing
The builder is target of major refactoring in the 1.0 development branch
so we introduce some delegate classes and methods to prepare migration.
2021-06-11 21:15:49 +02:00
5f9950e048 prepare release 0.9.4
All checks were successful
continuous-integration/drone/push Build is passing
2021-06-06 12:22:13 +02:00
e2c439379e switch to "main" as default branch name
All checks were successful
continuous-integration/drone/push Build is passing
2021-06-06 12:09:28 +02:00
ce33d37396 minor dependency updates; test against Vault 1.7.2
All checks were successful
continuous-integration/drone/push Build is passing
2021-06-06 12:07:02 +02:00
bdf4fc4b83 fix typo in method AppRole.Builder#wit0hTokenPeriod (#49) 2021-06-06 12:02:01 +02:00
50d485fab8 clean up unused imports
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-02 11:27:24 +02:00
5b508374d9 prepare release 0.9.3
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-02 11:16:04 +02:00
fbc61e065f fix argline for JDK 1.8 unit tests
All checks were successful
continuous-integration/drone/push Build is passing
2021-03-29 21:13:34 +02:00
56a52cb22a fix argline for JDK 16 unit tests
All checks were successful
continuous-integration/drone/push Build is passing
2021-03-29 20:50:16 +02:00
c43ec190ca use SystemLambda instead of custom environment mocks 2021-03-29 20:49:44 +02:00
639d0e3c5b Jackson 2.12.2, test against Vault 1.7.0
All checks were successful
continuous-integration/drone/push Build is passing
2021-03-29 18:56:24 +02:00
8e97f3c1dd build with JDK 16, test against Vault 1.6.3
All checks were successful
continuous-integration/drone/push Build is passing
2021-03-20 12:13:19 +01:00
c04d940a80 test: close static mocks
All checks were successful
continuous-integration/drone/push Build is passing
2021-02-28 13:03:25 +01:00
76a5ea4fe9 test: use assertThrows instead of try-catch blocks
All checks were successful
continuous-integration/drone/push Build is passing
2021-02-28 12:59:06 +01:00
2b0f458da3 use pre-sized maps for fixed-size payloads
All checks were successful
continuous-integration/drone/push Build is passing
2021-02-28 10:52:36 +01:00
63278c09c8 constructors of abstract VaultConnectorException protected
All checks were successful
continuous-integration/drone/push Build is passing
2021-01-24 14:57:14 +01:00
600f3d0d0f test classes package-private; use mockStatic()
All checks were successful
continuous-integration/drone/push Build is passing
2021-01-24 14:52:48 +01:00
1a19eaa87d release 0.9.2
All checks were successful
continuous-integration/drone/push Build is passing
2021-01-24 12:26:29 +01:00
a2dde38348 Jackson 2.12.1
All checks were successful
continuous-integration/drone/push Build is passing
2021-01-24 12:24:09 +01:00
dfb6d0a37c only initialize trust managers if CA certificate is provided (#43)
All checks were successful
continuous-integration/drone/push Build is passing
2021-01-24 12:20:45 +01:00
b46b59e4a0 update copyright notice to 2021
All checks were successful
continuous-integration/drone/push Build is passing
2021-01-03 11:56:33 +01:00
79ec536876 prepare release of v0.9.1
All checks were successful
continuous-integration/drone/push Build is passing
2021-01-03 11:48:51 +01:00
00d4e9acef test against Vault 1.6.1
All checks were successful
continuous-integration/drone/push Build is passing
2021-01-03 11:46:40 +01:00
48eccedad0 introduce maven profile for dependency analysis 2021-01-03 11:44:34 +01:00
ec4c4ac868 rework Travis CI configuration
Separate stages do not work as intended.
Add LTS and latest JDK (8, 11, 15) to build roster and run analysis with JDK 11 only.
2020-12-12 11:52:43 +01:00
90835aea92 dependency updates
All checks were successful
continuous-integration/drone/push Build is passing
Jackson 2.12, HTTPClient 4.5.13 and some test dependencies
2020-12-12 11:18:17 +01:00
32eed75de8 use batch mode in CI builds
All checks were successful
continuous-integration/drone/push Build is passing
Do not bloat the log with progress output.
2020-12-02 10:14:16 +01:00
c8ca5c4091 test against Vault 1.6.0
All checks were successful
continuous-integration/drone/push Build is passing
2020-11-12 19:48:08 +01:00
4ba81492d5 docs: update Travis CI badge
All checks were successful
continuous-integration/drone/push Build is passing
2020-09-08 21:28:16 +02:00
84b9877ca9 test against Vault 1.5.0 2020-07-26 14:12:13 +02:00
82 changed files with 1818 additions and 2086 deletions

View File

@ -5,10 +5,10 @@ steps:
- name: compile - name: compile
image: maven:3-jdk-11 image: maven:3-jdk-11
commands: commands:
- mvn clean compile - mvn -B clean compile
when: when:
branch: branch:
- master - main
- develop - develop
- feature/* - feature/*
- fix/* - fix/*
@ -16,7 +16,7 @@ steps:
- name: unit-tests - name: unit-tests
image: maven:3-jdk-11 image: maven:3-jdk-11
commands: commands:
- mvn test -P offline-tests - mvn -B resources:testResources compiler:testCompile surefire:test -P offline-tests
when: when:
branch: branch:
- develop - develop
@ -25,15 +25,15 @@ steps:
- name: unit-integration-tests - name: unit-integration-tests
image: maven:3-jdk-11 image: maven:3-jdk-11
environment: environment:
VAULT_VERSION: 1.4.0 VAULT_VERSION: 1.8.0
commands: commands:
- curl -s -o vault_1.4.0_linux_amd64.zip https://releases.hashicorp.com/vault/1.4.0/vault_1.4.0_linux_amd64.zip - curl -s -o vault_1.8.0_linux_amd64.zip https://releases.hashicorp.com/vault/1.8.0/vault_1.8.0_linux_amd64.zip
- curl -s https://releases.hashicorp.com/vault/1.4.0/vault_1.4.0_SHA256SUMS | grep linux_amd64 | sha256sum -c - curl -s https://releases.hashicorp.com/vault/1.8.0/vault_1.8.0_SHA256SUMS | grep linux_amd64 | sha256sum -c
- unzip vault_1.4.0_linux_amd64.zip - unzip vault_1.8.0_linux_amd64.zip
- rm vault_1.4.0_linux_amd64.zip - rm vault_1.8.0_linux_amd64.zip
- mv vault /bin/ - mv vault /bin/
- mvn test - mvn -B resources:testResources compiler:testCompile surefire:test
when: when:
branch: branch:
- master - main
- release/* - release/*

View File

@ -1,47 +1,46 @@
language: java language: java
jdk:
- openjdk11
install: true install: true
addons: addons:
sonarcloud: sonarcloud:
organization: "stklcode-github" organization: "stklcode-github"
token: token:
secure: "sM9OfX5jW764pn9cb2LSXArnXucKMws+eGeg5NnZxHRcGYt4hpBKLSregBSsBNzUoWVj0zNzPCpnh+UQvgxQzUerOqwEdjTBpy3SNPaxSn7UpoSg+Wz3aUmL9ugmx01b51/wMG4UCHEwTZt2tpgTPVtw8K6uSO78e0dSICCBHDnRcdQwOjMEQHIJJ/qHVRwuy/MzLCAP3W1JPZlsphZg9QsFyhB4hW97dE90joZezfocQIv2xI/r6k+BLz0pY6MxYCul0RiDumaiaej0CPvEJI/uSu//BAQjUdHw+mQgnKUYIbrn2ONOviwNfwdr94JyoZEN2B6zASUmNLjPf4AbIojDeyS+CrpQpm17EVm/Qk/Ds+Xra4PPPIcsZhiWzV0KoDUz9xLfXuRJ526VT5tDPiaeI7oETf0+8l+JIS1b399FyqHi7smzjpvC6GuKflQrbuHK4MuKzDh7WTHiqokGG4SS0wOQIaaHB3dfdwwQzPh6IM24e8CETxh3DjMeqUTU4DWmv5po55jZ934TtxVQvVN78bTG9O0zS9u+JmRY04OZ+OaXuFam6MfMUFQi0EPZzdGul/oWSibGUu3bNfVEBp60CnJwYNM/dKG6U7pJthLHvSwiQFOdKzHZ+l1jZJ4gPaXaIGqpwqVGr28ntqA/El1rytPixr2driE6bYMt5jw=" secure: "sM9OfX5jW764pn9cb2LSXArnXucKMws+eGeg5NnZxHRcGYt4hpBKLSregBSsBNzUoWVj0zNzPCpnh+UQvgxQzUerOqwEdjTBpy3SNPaxSn7UpoSg+Wz3aUmL9ugmx01b51/wMG4UCHEwTZt2tpgTPVtw8K6uSO78e0dSICCBHDnRcdQwOjMEQHIJJ/qHVRwuy/MzLCAP3W1JPZlsphZg9QsFyhB4hW97dE90joZezfocQIv2xI/r6k+BLz0pY6MxYCul0RiDumaiaej0CPvEJI/uSu//BAQjUdHw+mQgnKUYIbrn2ONOviwNfwdr94JyoZEN2B6zASUmNLjPf4AbIojDeyS+CrpQpm17EVm/Qk/Ds+Xra4PPPIcsZhiWzV0KoDUz9xLfXuRJ526VT5tDPiaeI7oETf0+8l+JIS1b399FyqHi7smzjpvC6GuKflQrbuHK4MuKzDh7WTHiqokGG4SS0wOQIaaHB3dfdwwQzPh6IM24e8CETxh3DjMeqUTU4DWmv5po55jZ934TtxVQvVN78bTG9O0zS9u+JmRY04OZ+OaXuFam6MfMUFQi0EPZzdGul/oWSibGUu3bNfVEBp60CnJwYNM/dKG6U7pJthLHvSwiQFOdKzHZ+l1jZJ4gPaXaIGqpwqVGr28ntqA/El1rytPixr2driE6bYMt5jw="
stages:
- Compile
- Test
- Analysis
env: env:
- PATH=$PATH:. VAULT_VERSION=1.4.0 - PATH=$PATH:. VAULT_VERSION=1.8.0 ANALYSIS=false
cache:
directories:
- '$HOME/.m2/repository'
- '$HOME/.sonar/cache'
jobs:
include:
- jdk: openjdk8
- jdk: openjdk11
env: PATH=$PATH:. VAULT_VERSION=1.8.0 ANALYSIS=true
- jdk: openjdk16
before_script: before_script:
- | - |
if [[ "$TRAVIS_BRANCH" =~ ^master|(release\/.+)$ ]]; then if [[ "$TRAVIS_BRANCH" =~ ^main|(release\/.+)$ ]]; then
wget -q https://releases.hashicorp.com/vault/${VAULT_VERSION}/vault_${VAULT_VERSION}_linux_amd64.zip wget -q https://releases.hashicorp.com/vault/${VAULT_VERSION}/vault_${VAULT_VERSION}_linux_amd64.zip
wget -q -O - https://releases.hashicorp.com/vault/${VAULT_VERSION}/vault_${VAULT_VERSION}_SHA256SUMS | grep linux_amd64 | sha256sum -c wget -q -O - https://releases.hashicorp.com/vault/${VAULT_VERSION}/vault_${VAULT_VERSION}_SHA256SUMS | grep linux_amd64 | sha256sum -c
unzip vault_${VAULT_VERSION}_linux_amd64.zip unzip vault_${VAULT_VERSION}_linux_amd64.zip
rm vault_${VAULT_VERSION}_linux_amd64.zip rm vault_${VAULT_VERSION}_linux_amd64.zip
fi fi
cache:
directories: script:
- '$HOME/.m2/repository' - mvn -B clean compile
- '$HOME/.sonar/cache' - |
jobs: if [[ "$TRAVIS_BRANCH" =~ ^main|(release\/.+)$ ]]; then
include: mvn -B resources:testResources compiler:testCompile surefire:test -P coverage
- stage: Compile else
name: Compile mvn -B resources:testResources compiler:testCompile surefire:test -P coverage -P offline-tests
script: fi
- mvn clean compile
- stage: Test after_success:
name: Unit Tests - if [ "$ANALYSIS" == "true" ]; then mvn sonar:sonar; fi
if: NOT branch =~ ^master|(release/.+)$
script:
- mvn test -P offline-tests
- name: Unit and Integration Tests
if: branch =~ ^master|(release/.+)$
script:
- mvn -P coverage clean package
after_success:
- if [ "$TRAVIS_BRANCH" = "master" ]; then mvn sonar:sonar; fi
notifications: notifications:
slack: slack:

View File

@ -1,3 +1,55 @@
## 0.9.5 (2021-07-28)
### Deprecations
* Deprecate ` {read,write,delete}Secret()` convenience methods. Use `{read,write,delete}("secret/...")` instead (#52)
* Deprecated builder invocation `VaultConnectorBuilder.http()` in favor of `HTTPVaultConnector.builder()` (#51)
* Deprecated `de.stklcode.jvault.connector.builder.HTTPVaultConnectorBuilder` in favor of `de.stklcode.jvault.connector.HTTPVaultConnectorBuilder` (only package changed) (#51)
Old builders will be removed in 1.0
### Improvements
* Minor dependency updates
### Test
* Tested against Vault 1.8.0
## 0.9.4 (2021-06-06)
### Deprecations
* `AppRole.Builder#wit0hTokenPeriod()` is deprecated in favor of `#withTokenPeriod()` (#49)
### Improvements
* Minor dependency updates
### Test
* Tested against Vault 1.7.2
## 0.9.3 (2021-04-02)
### Improvements
* Use pre-sized map objects for fixed-size payloads
* Minor dependency updates
* Unit test adjustments for JDK 16 build environments
### Test
* Tested against Vault 1.7.0
## 0.9.2 (2021-01-24)
### Fixes
* Only initialize custom trust managers, if CA certificate is actually provided (#43)
### Improvements
* Minor dependency updates
## 0.9.1 (2021-01-03)
### Improvements
* Dependency updates
### Test
* Tested against Vault 1.6.1
## 0.9.0 (2020-04-29) ## 0.9.0 (2020-04-29)
### Fixes ### Fixes

View File

@ -1,11 +1,11 @@
# Java Vault Connector # Java Vault Connector
[![Build Status](https://travis-ci.org/stklcode/jvaultconnector.svg?branch=master)](https://travis-ci.org/stklcode/jvaultconnector) [![Build Status](https://travis-ci.com/stklcode/jvaultconnector.svg?branch=main)](https://travis-ci.com/stklcode/jvaultconnector)
[![Quality Gate](https://sonarcloud.io/api/project_badges/measure?project=de.stklcode.jvault%3Ajvault-connector&metric=alert_status)](https://sonarcloud.io/dashboard?id=de.stklcode.jvault%3Ajvault-connector) [![Quality Gate](https://sonarcloud.io/api/project_badges/measure?project=de.stklcode.jvault%3Ajvault-connector&metric=alert_status)](https://sonarcloud.io/dashboard?id=de.stklcode.jvault%3Ajvault-connector)
[![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](https://github.com/stklcode/jvaultconnector/blob/master/LICENSE.txt) [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](https://github.com/stklcode/jvaultconnector/blob/main/LICENSE.txt)
[![Maven Central](https://img.shields.io/maven-central/v/de.stklcode.jvault/jvault-connector.svg)](https://search.maven.org/#search%7Cga%7C1%7Cg%3A%22de.stklcode.jvault%22%20AND%20a%3A%22jvault-connector%22) [![Maven Central](https://img.shields.io/maven-central/v/de.stklcode.jvault/jvault-connector.svg)](https://search.maven.org/#search%7Cga%7C1%7Cg%3A%22de.stklcode.jvault%22%20AND%20a%3A%22jvault-connector%22)
![Logo](https://raw.githubusercontent.com/stklcode/jvaultconnector/master/assets/logo.png) ![Logo](https://raw.githubusercontent.com/stklcode/jvaultconnector/main/assets/logo.png)
Java Vault Connector is a connector library for [Vault](https://www.vaultproject.io) by [Hashicorp](https://www.hashicorp.com) written in Java. The connector allows simple usage of Vault's secret store in own applications. Java Vault Connector is a connector library for [Vault](https://www.vaultproject.io) by [Hashicorp](https://www.hashicorp.com) written in Java. The connector allows simple usage of Vault's secret store in own applications.
@ -32,7 +32,7 @@ Java Vault Connector is a connector library for [Vault](https://www.vaultproject
* SQL secret handling * SQL secret handling
* KV v1 and v2 support * KV v1 and v2 support
* Connector Factory with builder pattern * Connector Factory with builder pattern
* Tested against Vault 1.4.0 * Tested against Vault 1.8.0
## Maven Artifact ## Maven Artifact
@ -40,7 +40,7 @@ Java Vault Connector is a connector library for [Vault](https://www.vaultproject
<dependency> <dependency>
<groupId>de.stklcode.jvault</groupId> <groupId>de.stklcode.jvault</groupId>
<artifactId>jvault-connector</artifactId> <artifactId>jvault-connector</artifactId>
<version>0.9.0</version> <version>0.9.5</version>
</dependency> </dependency>
``` ```
@ -50,21 +50,21 @@ Java Vault Connector is a connector library for [Vault](https://www.vaultproject
```java ```java
// Instantiate using builder pattern style factory (TLS enabled by default) // Instantiate using builder pattern style factory (TLS enabled by default)
VaultConnector vault = VaultConnectorBuilder.http() VaultConnector vault = HTTPVaultConnector.builder()
.withHost("127.0.0.1") .withHost("127.0.0.1")
.withPort(8200) .withPort(8200)
.withTLS() .withTLS()
.build(); .build();
// Instantiate with custom SSL context // Instantiate with custom SSL context
VaultConnector vault = VaultConnectorBuilder.http() VaultConnector vault = HTTPVaultConnector.builder()
.withHost("example.com") .withHost("example.com")
.withPort(8200) .withPort(8200)
.withTrustedCA(Paths.get("/path/to/CA.pem")) .withTrustedCA(Paths.get("/path/to/CA.pem"))
.build(); .build();
// Initialization from environment variables // Initialization from environment variables
VaultConnector vault = VaultConnectorBuilder.http() VaultConnector vault = HTTPVaultConnector.builder()
.fromEnv() .fromEnv()
.build(); .build();
``` ```
@ -86,20 +86,20 @@ vault.authAppRole("01234567-89ab-cdef-0123-456789abcdef", "fedcba98-7654-3210-fe
```java ```java
// Retrieve secret (prefix "secret/" assumed, use read() to read arbitrary paths) // Retrieve secret (prefix "secret/" assumed, use read() to read arbitrary paths)
String secret = vault.readSecret("some/secret/key").get("value", String.class); String secret = vault.read("secret/some/key").get("value", String.class);
// Complex secret. // Complex secret.
Map<String, Object> secretData = vault.readSecret("another/secret/key").getData(); Map<String, Object> secretData = vault.read("secret/another/key").getData();
// Write simple secret. // Write simple secret.
vault.writeSecret("new/secret/key", "secret value"); vault.write("secret/new/key", "secret value");
// Write complex data to arbitraty path. // Write complex data.
Map<String, Object> map = ...; Map<String, Object> map = ...;
vault.write("any/path/to/write", map); vault.write("path/to/write", map);
// Delete secret. // Delete secret.
vault.delete("any/path/to/write"); vault.delete("path/to/delete");
``` ```
### Token and role creation ### Token and role creation

107
pom.xml
View File

@ -4,7 +4,7 @@
<groupId>de.stklcode.jvault</groupId> <groupId>de.stklcode.jvault</groupId>
<artifactId>jvault-connector</artifactId> <artifactId>jvault-connector</artifactId>
<version>0.9.0</version> <version>0.9.5</version>
<packaging>jar</packaging> <packaging>jar</packaging>
@ -23,6 +23,7 @@
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<argLine></argLine>
</properties> </properties>
<developers> <developers>
@ -66,7 +67,7 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId> <artifactId>maven-resources-plugin</artifactId>
<version>3.1.0</version> <version>3.2.0</version>
</plugin> </plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
@ -85,12 +86,18 @@
<artifactId>maven-install-plugin</artifactId> <artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version> <version>2.5.2</version>
</plugin> </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId> <artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version> <version>2.22.2</version>
<configuration> <configuration>
<reuseForks>false</reuseForks> <reuseForks>false</reuseForks>
<argLine>@{argLine} --illegal-access=permit</argLine>
</configuration> </configuration>
</plugin> </plugin>
</plugins> </plugins>
@ -101,18 +108,18 @@
<dependency> <dependency>
<groupId>org.apache.httpcomponents</groupId> <groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId> <artifactId>httpclient</artifactId>
<version>4.5.12</version> <version>4.5.13</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.fasterxml.jackson.core</groupId> <groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId> <artifactId>jackson-databind</artifactId>
<version>2.10.3</version> <version>2.12.4</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.junit.jupiter</groupId> <groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId> <artifactId>junit-jupiter</artifactId>
<version>5.6.2</version> <version>5.7.2</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
@ -121,45 +128,22 @@
<version>2.2</version> <version>2.2</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>3.3.3</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy</artifactId>
</exclusion>
<exclusion>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy-agent</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency> <dependency>
<groupId>org.mockito</groupId> <groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId> <artifactId>mockito-inline</artifactId>
<version>3.3.3</version> <version>3.11.2</version>
<scope>test</scope>
</dependency>
<!-- Updated transient dependency from mockito-core for JDK 13 compatibility -->
<dependency>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy</artifactId>
<version>1.10.9</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>net.bytebuddy</groupId> <groupId>com.github.stefanbirkner</groupId>
<artifactId>byte-buddy-agent</artifactId> <artifactId>system-lambda</artifactId>
<version>1.10.9</version> <version>1.2.0</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>commons-io</groupId> <groupId>commons-io</groupId>
<artifactId>commons-io</artifactId> <artifactId>commons-io</artifactId>
<version>2.6</version> <version>2.11.0</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
</dependencies> </dependencies>
@ -169,7 +153,7 @@
<dependency> <dependency>
<groupId>org.sonarsource.scanner.maven</groupId> <groupId>org.sonarsource.scanner.maven</groupId>
<artifactId>sonar-maven-plugin</artifactId> <artifactId>sonar-maven-plugin</artifactId>
<version>3.7.0.1746</version> <version>3.9.0.2155</version>
</dependency> </dependency>
</dependencies> </dependencies>
</dependencyManagement> </dependencyManagement>
@ -210,7 +194,7 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId> <artifactId>maven-javadoc-plugin</artifactId>
<version>3.2.0</version> <version>3.3.0</version>
<configuration> <configuration>
<source>1.8</source> <source>1.8</source>
</configuration> </configuration>
@ -234,7 +218,7 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId> <artifactId>maven-gpg-plugin</artifactId>
<version>1.6</version> <version>3.0.1</version>
<executions> <executions>
<execution> <execution>
<id>sign-artifacts</id> <id>sign-artifacts</id>
@ -259,17 +243,16 @@
<plugin> <plugin>
<groupId>org.jacoco</groupId> <groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId> <artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.5</version> <version>0.8.7</version>
<executions> <executions>
<execution> <execution>
<id>prepare-agent</id> <id>default-prepare-agent</id>
<goals> <goals>
<goal>prepare-agent</goal> <goal>prepare-agent</goal>
</goals> </goals>
</execution> </execution>
<execution> <execution>
<id>report</id> <id>default-report</id>
<phase>prepare-package</phase>
<goals> <goals>
<goal>report</goal> <goal>report</goal>
</goals> </goals>
@ -297,6 +280,46 @@
</build> </build>
</profile> </profile>
<profile>
<id>dependency-check</id>
<build>
<plugins>
<plugin>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-maven</artifactId>
<version>6.2.2</version>
<executions>
<execution>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>jdk1.8</id>
<activation>
<jdk>1.8</jdk>
</activation>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>@{argLine}</argLine>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</profile>
<profile> <profile>
<id>sonatype</id> <id>sonatype</id>
<distributionManagement> <distributionManagement>
@ -315,11 +338,11 @@
<id>local</id> <id>local</id>
<distributionManagement> <distributionManagement>
<repository> <repository>
<id>local</id> <id>stklcode</id>
<url>${dist.repo.local}</url> <url>${dist.repo.local}</url>
</repository> </repository>
<snapshotRepository> <snapshotRepository>
<id>local</id> <id>stklcode</id>
<url>${dist.repo.local.snapshot}</url> <url>${dist.repo.local.snapshot}</url>
</snapshotRepository> </snapshotRepository>
</distributionManagement> </distributionManagement>

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -30,6 +30,9 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static java.util.Collections.emptyMap;
import static java.util.Collections.singletonMap;
/** /**
* Vault Connector implementation using Vault's HTTP API. * Vault Connector implementation using Vault's HTTP API.
* *
@ -68,6 +71,16 @@ public class HTTPVaultConnector implements VaultConnector {
private String token; // Current token. private String token; // Current token.
private long tokenTTL = 0; // Expiration time for current token. private long tokenTTL = 0; // Expiration time for current token.
/**
* Get a new builder for a connector.
*
* @return Builder instance.
* @since 0.9.5
*/
public static HTTPVaultConnectorBuilder builder() {
return new HTTPVaultConnectorBuilder();
}
/** /**
* Create connector using hostname and schema. * Create connector using hostname and schema.
* *
@ -222,17 +235,17 @@ public class HTTPVaultConnector implements VaultConnector {
@Override @Override
public final SealResponse sealStatus() throws VaultConnectorException { public final SealResponse sealStatus() throws VaultConnectorException {
return request.get(PATH_SEAL_STATUS, new HashMap<>(), token, SealResponse.class); return request.get(PATH_SEAL_STATUS, emptyMap(), token, SealResponse.class);
} }
@Override @Override
public final void seal() throws VaultConnectorException { public final void seal() throws VaultConnectorException {
request.put(PATH_SEAL, new HashMap<>(), token); request.put(PATH_SEAL, emptyMap(), token);
} }
@Override @Override
public final SealResponse unseal(final String key, final Boolean reset) throws VaultConnectorException { public final SealResponse unseal(final String key, final Boolean reset) throws VaultConnectorException {
Map<String, String> param = new HashMap<>(); Map<String, String> param = new HashMap<>(2, 1);
param.put("key", key); param.put("key", key);
if (reset != null) { if (reset != null) {
param.put("reset", reset.toString()); param.put("reset", reset.toString());
@ -244,7 +257,7 @@ public class HTTPVaultConnector implements VaultConnector {
@Override @Override
public HealthResponse getHealth() throws VaultConnectorException { public HealthResponse getHealth() throws VaultConnectorException {
/* Force status code to be 200, so we don't need to modify the request sequence. */ /* Force status code to be 200, so we don't need to modify the request sequence. */
Map<String, String> param = new HashMap<>(); Map<String, String> param = new HashMap<>(3, 1);
param.put("standbycode", "200"); // Default: 429. param.put("standbycode", "200"); // Default: 429.
param.put("sealedcode", "200"); // Default: 503. param.put("sealedcode", "200"); // Default: 503.
param.put("uninitcode", "200"); // Default: 501. param.put("uninitcode", "200"); // Default: 501.
@ -260,7 +273,7 @@ public class HTTPVaultConnector implements VaultConnector {
@Override @Override
public final List<AuthBackend> getAuthBackends() throws VaultConnectorException { public final List<AuthBackend> getAuthBackends() throws VaultConnectorException {
/* Issue request and parse response */ /* Issue request and parse response */
AuthMethodsResponse amr = request.get(PATH_AUTH, new HashMap<>(), token, AuthMethodsResponse.class); AuthMethodsResponse amr = request.get(PATH_AUTH, emptyMap(), token, AuthMethodsResponse.class);
return amr.getSupportedMethods().values().stream().map(AuthMethod::getType).collect(Collectors.toList()); return amr.getSupportedMethods().values().stream().map(AuthMethod::getType).collect(Collectors.toList());
} }
@ -270,7 +283,7 @@ public class HTTPVaultConnector implements VaultConnector {
/* set token */ /* set token */
this.token = token; this.token = token;
this.tokenTTL = 0; this.tokenTTL = 0;
TokenResponse res = request.post(PATH_TOKEN + PATH_LOOKUP, new HashMap<>(), token, TokenResponse.class); TokenResponse res = request.post(PATH_TOKEN + PATH_LOOKUP, emptyMap(), token, TokenResponse.class);
authorized = true; authorized = true;
return res; return res;
@ -279,15 +292,14 @@ public class HTTPVaultConnector implements VaultConnector {
@Override @Override
public final AuthResponse authUserPass(final String username, final String password) public final AuthResponse authUserPass(final String username, final String password)
throws VaultConnectorException { throws VaultConnectorException {
final Map<String, String> payload = new HashMap<>(); final Map<String, String> payload = singletonMap("password", password);
payload.put("password", password);
return queryAuth(PATH_AUTH_USERPASS + username, payload); return queryAuth(PATH_AUTH_USERPASS + username, payload);
} }
@Override @Override
@Deprecated @Deprecated
public final AuthResponse authAppId(final String appID, final String userID) throws VaultConnectorException { public final AuthResponse authAppId(final String appID, final String userID) throws VaultConnectorException {
final Map<String, String> payload = new HashMap<>(); final Map<String, String> payload = new HashMap<>(2, 1);
payload.put("app_id", appID); payload.put("app_id", appID);
payload.put("user_id", userID); payload.put("user_id", userID);
return queryAuth(PATH_AUTH_APPID + "login", payload); return queryAuth(PATH_AUTH_APPID + "login", payload);
@ -295,7 +307,7 @@ public class HTTPVaultConnector implements VaultConnector {
@Override @Override
public final AuthResponse authAppRole(final String roleID, final String secretID) throws VaultConnectorException { public final AuthResponse authAppRole(final String roleID, final String secretID) throws VaultConnectorException {
final Map<String, String> payload = new HashMap<>(); final Map<String, String> payload = new HashMap<>(2, 1);
payload.put("role_id", roleID); payload.put("role_id", roleID);
if (secretID != null) { if (secretID != null) {
payload.put("secret_id", secretID); payload.put("secret_id", secretID);
@ -328,7 +340,7 @@ public class HTTPVaultConnector implements VaultConnector {
public final boolean registerAppId(final String appID, final String policy, final String displayName) public final boolean registerAppId(final String appID, final String policy, final String displayName)
throws VaultConnectorException { throws VaultConnectorException {
requireAuth(); requireAuth();
Map<String, String> payload = new HashMap<>(); Map<String, String> payload = new HashMap<>(2, 1);
payload.put("value", policy); payload.put("value", policy);
payload.put("display_name", displayName); payload.put("display_name", displayName);
@ -342,11 +354,13 @@ public class HTTPVaultConnector implements VaultConnector {
@Deprecated @Deprecated
public final boolean registerUserId(final String appID, final String userID) throws VaultConnectorException { public final boolean registerUserId(final String appID, final String userID) throws VaultConnectorException {
requireAuth(); requireAuth();
Map<String, String> payload = new HashMap<>();
payload.put("value", appID);
/* Issue request and expect code 204 with empty response */ /* Issue request and expect code 204 with empty response */
request.postWithoutResponse(PATH_AUTH_APPID + "map/user-id/" + userID, payload, token); request.postWithoutResponse(
PATH_AUTH_APPID + "map/user-id/" + userID,
singletonMap("value", appID),
token
);
return true; return true;
} }
@ -366,7 +380,12 @@ public class HTTPVaultConnector implements VaultConnector {
public final AppRoleResponse lookupAppRole(final String roleName) throws VaultConnectorException { public final AppRoleResponse lookupAppRole(final String roleName) throws VaultConnectorException {
requireAuth(); requireAuth();
/* Request HTTP response and parse Secret */ /* Request HTTP response and parse Secret */
return request.get(String.format(PATH_AUTH_APPROLE_ROLE, roleName, ""), new HashMap<>(), token, AppRoleResponse.class); return request.get(
String.format(PATH_AUTH_APPROLE_ROLE, roleName, ""),
emptyMap(),
token,
AppRoleResponse.class
);
} }
@Override @Override
@ -385,7 +404,7 @@ public class HTTPVaultConnector implements VaultConnector {
/* Issue request, parse response and extract Role ID */ /* Issue request, parse response and extract Role ID */
return request.get( return request.get(
String.format(PATH_AUTH_APPROLE_ROLE, roleName, "/role-id"), String.format(PATH_AUTH_APPROLE_ROLE, roleName, "/role-id"),
new HashMap<>(), emptyMap(),
token, token,
RawDataResponse.class RawDataResponse.class
).getData().get("role_id").toString(); ).getData().get("role_id").toString();
@ -394,12 +413,13 @@ public class HTTPVaultConnector implements VaultConnector {
@Override @Override
public final boolean setAppRoleID(final String roleName, final String roleID) throws VaultConnectorException { public final boolean setAppRoleID(final String roleName, final String roleID) throws VaultConnectorException {
requireAuth(); requireAuth();
/* Request HTTP response and parse Secret */
Map<String, String> payload = new HashMap<>();
payload.put("role_id", roleID);
/* Issue request and expect code 204 with empty response */ /* Issue request and expect code 204 with empty response */
request.postWithoutResponse(String.format(PATH_AUTH_APPROLE_ROLE, roleName, "/role-id"), payload, token); request.postWithoutResponse(
String.format(PATH_AUTH_APPROLE_ROLE, roleName, "/role-id"),
singletonMap("role_id", roleID),
token
);
return true; return true;
} }
@ -457,7 +477,13 @@ public class HTTPVaultConnector implements VaultConnector {
public final List<String> listAppRoles() throws VaultConnectorException { public final List<String> listAppRoles() throws VaultConnectorException {
requireAuth(); requireAuth();
SecretListResponse secrets = request.get(PATH_AUTH_APPROLE + "role?list=true", new HashMap<>(), token, SecretListResponse.class); SecretListResponse secrets = request.get(
PATH_AUTH_APPROLE + "role?list=true",
emptyMap(),
token,
SecretListResponse.class
);
return secrets.getKeys(); return secrets.getKeys();
} }
@ -467,7 +493,7 @@ public class HTTPVaultConnector implements VaultConnector {
SecretListResponse secrets = request.get( SecretListResponse secrets = request.get(
String.format(PATH_AUTH_APPROLE_ROLE, roleName, "/secret-id?list=true"), String.format(PATH_AUTH_APPROLE_ROLE, roleName, "/secret-id?list=true"),
new HashMap<>(), emptyMap(),
token, token,
SecretListResponse.class SecretListResponse.class
); );
@ -479,14 +505,14 @@ public class HTTPVaultConnector implements VaultConnector {
public final SecretResponse read(final String key) throws VaultConnectorException { public final SecretResponse read(final String key) throws VaultConnectorException {
requireAuth(); requireAuth();
/* Issue request and parse secret response */ /* Issue request and parse secret response */
return request.get(key, new HashMap<>(), token, SecretResponse.class); return request.get(key, emptyMap(), token, SecretResponse.class);
} }
@Override @Override
public final SecretResponse readSecretVersion(final String mount, final String key, final Integer version) throws VaultConnectorException { public final SecretResponse readSecretVersion(final String mount, final String key, final Integer version) throws VaultConnectorException {
requireAuth(); requireAuth();
/* Request HTTP response and parse secret metadata */ /* Request HTTP response and parse secret metadata */
Map<String, String> args = new HashMap<>(); Map<String, String> args = new HashMap<>(1, 1);
if (version != null) { if (version != null) {
args.put("version", version.toString()); args.put("version", version.toString());
} }
@ -499,14 +525,14 @@ public class HTTPVaultConnector implements VaultConnector {
requireAuth(); requireAuth();
/* Request HTTP response and parse secret metadata */ /* Request HTTP response and parse secret metadata */
return request.get(mount + PATH_METADATA + key, new HashMap<>(), token, MetadataResponse.class); return request.get(mount + PATH_METADATA + key, emptyMap(), token, MetadataResponse.class);
} }
@Override @Override
public void updateSecretMetadata(final String mount, final String key, final Integer maxVersions, final boolean casRequired) throws VaultConnectorException { public void updateSecretMetadata(final String mount, final String key, final Integer maxVersions, final boolean casRequired) throws VaultConnectorException {
requireAuth(); requireAuth();
Map<String, Object> payload = new HashMap<>(); Map<String, Object> payload = new HashMap<>(2, 1);
if (maxVersions != null) { if (maxVersions != null) {
payload.put("max_versions", maxVersions); payload.put("max_versions", maxVersions);
} }
@ -524,12 +550,12 @@ public class HTTPVaultConnector implements VaultConnector {
} }
// Add CAS value to options map if present. // Add CAS value to options map if present.
Map<String, Object> options = new HashMap<>(); Map<String, Object> options = new HashMap<>(1, 1);
if (cas != null) { if (cas != null) {
options.put("cas", cas); options.put("cas", cas);
} }
Map<String, Object> payload = new HashMap<>(); Map<String, Object> payload = new HashMap<>(2, 1);
payload.put("data", data); payload.put("data", data);
payload.put("options", options); payload.put("options", options);
@ -541,7 +567,7 @@ public class HTTPVaultConnector implements VaultConnector {
public final List<String> list(final String path) throws VaultConnectorException { public final List<String> list(final String path) throws VaultConnectorException {
requireAuth(); requireAuth();
SecretListResponse secrets = request.get(path + "/?list=true", new HashMap<>(), token, SecretListResponse.class); SecretListResponse secrets = request.get(path + "/?list=true", emptyMap(), token, SecretListResponse.class);
return secrets.getKeys(); return secrets.getKeys();
} }
@ -559,7 +585,7 @@ public class HTTPVaultConnector implements VaultConnector {
// If options are given, split payload in two parts. // If options are given, split payload in two parts.
if (options != null) { if (options != null) {
Map<String, Object> payloadMap = new HashMap<>(); Map<String, Object> payloadMap = new HashMap<>(2, 1);
payloadMap.put("data", data); payloadMap.put("data", data);
payloadMap.put("options", options); payloadMap.put("options", options);
payload = payloadMap; payload = payloadMap;
@ -616,8 +642,7 @@ public class HTTPVaultConnector implements VaultConnector {
requireAuth(); requireAuth();
/* Request HTTP response and expect empty result */ /* Request HTTP response and expect empty result */
Map<String, Object> payload = new HashMap<>(); Map<String, Object> payload = singletonMap("versions", versions);
payload.put("versions", versions);
/* Issue request and expect code 204 with empty response */ /* Issue request and expect code 204 with empty response */
request.postWithoutResponse(mount + pathPart + key, payload, token); request.postWithoutResponse(mount + pathPart + key, payload, token);
@ -628,14 +653,14 @@ public class HTTPVaultConnector implements VaultConnector {
requireAuth(); requireAuth();
/* Issue request and expect code 204 with empty response */ /* Issue request and expect code 204 with empty response */
request.putWithoutResponse(PATH_REVOKE + leaseID, new HashMap<>(), token); request.putWithoutResponse(PATH_REVOKE + leaseID, emptyMap(), token);
} }
@Override @Override
public final SecretResponse renew(final String leaseID, final Integer increment) throws VaultConnectorException { public final SecretResponse renew(final String leaseID, final Integer increment) throws VaultConnectorException {
requireAuth(); requireAuth();
Map<String, String> payload = new HashMap<>(); Map<String, String> payload = new HashMap<>(2, 1);
payload.put("lease_id", leaseID); payload.put("lease_id", leaseID);
if (increment != null) { if (increment != null) {
payload.put("increment", increment.toString()); payload.put("increment", increment.toString());
@ -694,9 +719,12 @@ public class HTTPVaultConnector implements VaultConnector {
requireAuth(); requireAuth();
/* Request HTTP response and parse Secret */ /* Request HTTP response and parse Secret */
Map<String, String> param = new HashMap<>(); return request.get(
param.put("token", token); PATH_TOKEN + PATH_LOOKUP,
return request.get(PATH_TOKEN + PATH_LOOKUP, param, token, TokenResponse.class); singletonMap("token", token),
token,
TokenResponse.class
);
} }
@Override @Override
@ -720,7 +748,7 @@ public class HTTPVaultConnector implements VaultConnector {
requireAuth(); requireAuth();
// Request HTTP response and parse response. // Request HTTP response and parse response.
return request.get(PATH_TOKEN + PATH_ROLES + "/" + name, new HashMap<>(), token, TokenRoleResponse.class); return request.get(PATH_TOKEN + PATH_ROLES + "/" + name, emptyMap(), token, TokenRoleResponse.class);
} }
@Override @Override

View File

@ -0,0 +1,299 @@
/*
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.stklcode.jvault.connector;
import de.stklcode.jvault.connector.builder.VaultConnectorBuilder;
import de.stklcode.jvault.connector.exception.ConnectionException;
import de.stklcode.jvault.connector.exception.TlsException;
import de.stklcode.jvault.connector.exception.VaultConnectorException;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
/**
* Vault Connector Builder implementation for HTTP Vault connectors.
*
* @author Stefan Kalscheuer
* @since 0.8.0
* @since 0.9.5 Package {@link de.stklcode.jvault.connector}
*/
public class HTTPVaultConnectorBuilder implements VaultConnectorBuilder {
private static final String ENV_VAULT_ADDR = "VAULT_ADDR";
private static final String ENV_VAULT_CACERT = "VAULT_CACERT";
private static final String ENV_VAULT_TOKEN = "VAULT_TOKEN";
private static final String ENV_VAULT_MAX_RETRIES = "VAULT_MAX_RETRIES";
public static final String DEFAULT_HOST = "127.0.0.1";
public static final Integer DEFAULT_PORT = 8200;
public static final boolean DEFAULT_TLS = true;
public static final String DEFAULT_TLS_VERSION = "TLSv1.2";
public static final String DEFAULT_PREFIX = "/v1/";
public static final int DEFAULT_NUMBER_OF_RETRIES = 0;
private String host;
private Integer port;
private boolean tls;
private String tlsVersion;
private String prefix;
private X509Certificate trustedCA;
private int numberOfRetries;
private Integer timeout;
private String token;
/**
* Default empty constructor.
* Initializes factory with default values.
*/
public HTTPVaultConnectorBuilder() {
host = DEFAULT_HOST;
port = DEFAULT_PORT;
tls = DEFAULT_TLS;
tlsVersion = DEFAULT_TLS_VERSION;
prefix = DEFAULT_PREFIX;
numberOfRetries = DEFAULT_NUMBER_OF_RETRIES;
}
/**
* Set hostname (default: 127.0.0.1).
*
* @param host Hostname or IP address
* @return self
*/
public HTTPVaultConnectorBuilder withHost(final String host) {
this.host = host;
return this;
}
/**
* Set port (default: 8200).
*
* @param port Vault TCP port
* @return self
*/
public HTTPVaultConnectorBuilder withPort(final Integer port) {
this.port = port;
return this;
}
/**
* Set TLS usage (default: TRUE).
*
* @param useTLS use TLS or not
* @return self
*/
public HTTPVaultConnectorBuilder withTLS(final boolean useTLS) {
this.tls = useTLS;
return this;
}
/**
* Set TLS usage (default: TRUE).
*
* @param useTLS Use TLS or not.
* @param version Supported TLS version ({@code TLSv1.2}, {@code TLSv1.1}, {@code TLSv1.0}, {@code TLS}).
* @return self
* @since 0.8 Added version parameter (#22).
*/
public HTTPVaultConnectorBuilder withTLS(final boolean useTLS, final String version) {
this.tls = useTLS;
this.tlsVersion = version;
return this;
}
/**
* Convenience Method for TLS usage (enabled by default).
*
* @param version Supported TLS version ({@code TLSv1.2}, {@code TLSv1.1}, {@code TLSv1.0}, {@code TLS}).
* @return self
* @since 0.8 Added version parameter (#22).
*/
public HTTPVaultConnectorBuilder withTLS(final String version) {
return withTLS(true, version);
}
/**
* Convenience Method for TLS usage (enabled by default).
*
* @return self
*/
public HTTPVaultConnectorBuilder withTLS() {
return withTLS(true);
}
/**
* Convenience Method for NOT using TLS.
*
* @return self
*/
public HTTPVaultConnectorBuilder withoutTLS() {
return withTLS(false);
}
/**
* Set API prefix. Default is "/v1/" and changes should not be necessary for current state of development.
*
* @param prefix Vault API prefix (default: "/v1/"
* @return self
*/
public HTTPVaultConnectorBuilder withPrefix(final String prefix) {
this.prefix = prefix;
return this;
}
/**
* Add a trusted CA certificate for HTTPS connections.
*
* @param cert path to certificate file
* @return self
* @throws VaultConnectorException on error
* @since 0.4.0
*/
public HTTPVaultConnectorBuilder withTrustedCA(final Path cert) throws VaultConnectorException {
if (cert != null) {
return withTrustedCA(certificateFromFile(cert));
} else {
this.trustedCA = null;
}
return this;
}
/**
* Add a trusted CA certificate for HTTPS connections.
*
* @param cert path to certificate file
* @return self
* @since 0.8.0
*/
public HTTPVaultConnectorBuilder withTrustedCA(final X509Certificate cert) {
this.trustedCA = cert;
return this;
}
/**
* Set token for automatic authentication, using {@link #buildAndAuth()}.
*
* @param token Vault token
* @return self
* @since 0.6.0
*/
public HTTPVaultConnectorBuilder withToken(final String token) {
this.token = token;
return this;
}
/**
* Build connector based on the {@code }VAULT_ADDR} and {@code VAULT_CACERT} (optional) environment variables.
*
* @return self
* @throws VaultConnectorException if Vault address from environment variables is malformed
* @since 0.6.0
*/
public HTTPVaultConnectorBuilder fromEnv() throws VaultConnectorException {
/* Parse URL from environment variable */
if (System.getenv(ENV_VAULT_ADDR) != null && !System.getenv(ENV_VAULT_ADDR).trim().isEmpty()) {
try {
URL url = new URL(System.getenv(ENV_VAULT_ADDR));
this.host = url.getHost();
this.port = url.getPort();
this.tls = url.getProtocol().equals("https");
} catch (MalformedURLException e) {
throw new ConnectionException("URL provided in environment variable malformed", e);
}
}
/* Read number of retries */
if (System.getenv(ENV_VAULT_MAX_RETRIES) != null) {
try {
numberOfRetries = Integer.parseInt(System.getenv(ENV_VAULT_MAX_RETRIES));
} catch (NumberFormatException ignored) {
/* Ignore malformed values. */
}
}
/* Read token */
token = System.getenv(ENV_VAULT_TOKEN);
/* Parse certificate, if set */
if (System.getenv(ENV_VAULT_CACERT) != null && !System.getenv(ENV_VAULT_CACERT).trim().isEmpty()) {
return withTrustedCA(Paths.get(System.getenv(ENV_VAULT_CACERT)));
}
return this;
}
/**
* Define the number of retries to attempt on 5xx errors.
*
* @param numberOfRetries The number of retries to attempt on 5xx errors (default: 0)
* @return self
* @since 0.6.0
*/
public HTTPVaultConnectorBuilder withNumberOfRetries(final int numberOfRetries) {
this.numberOfRetries = numberOfRetries;
return this;
}
/**
* Define a custom timeout for the HTTP connection.
*
* @param milliseconds Timeout value in milliseconds.
* @return self
* @since 0.6.0
*/
public HTTPVaultConnectorBuilder withTimeout(final int milliseconds) {
this.timeout = milliseconds;
return this;
}
@Override
public HTTPVaultConnector build() {
return new HTTPVaultConnector(host, tls, tlsVersion, port, prefix, trustedCA, numberOfRetries, timeout);
}
@Override
public HTTPVaultConnector buildAndAuth() throws VaultConnectorException {
if (token == null) {
throw new ConnectionException("No vault token provided, unable to authenticate.");
}
HTTPVaultConnector con = build();
con.authToken(token);
return con;
}
/**
* Read given certificate file to X.509 certificate.
*
* @param certFile Path to certificate file
* @return X.509 Certificate object
* @throws TlsException on error
* @since 0.4.0
*/
private X509Certificate certificateFromFile(final Path certFile) throws TlsException {
try (InputStream is = Files.newInputStream(certFile)) {
return (X509Certificate) CertificateFactory.getInstance("X.509").generateCertificate(is);
} catch (IOException | CertificateException e) {
throw new TlsException("Unable to read certificate.", e);
}
}
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -22,10 +22,7 @@ import de.stklcode.jvault.connector.model.*;
import de.stklcode.jvault.connector.model.response.*; import de.stklcode.jvault.connector.model.response.*;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/** /**
* Vault Connector interface. * Vault Connector interface.
@ -404,7 +401,9 @@ public interface VaultConnector extends AutoCloseable, Serializable {
* @param key Secret identifier * @param key Secret identifier
* @return Secret response * @return Secret response
* @throws VaultConnectorException on error * @throws VaultConnectorException on error
* @deprecated Convenience method will be removed in 1.0. Use {@link #read(String)} instead with key prefix "secret/".
*/ */
@Deprecated
default SecretResponse readSecret(final String key) throws VaultConnectorException { default SecretResponse readSecret(final String key) throws VaultConnectorException {
return read(PATH_SECRET + "/" + key); return read(PATH_SECRET + "/" + key);
} }
@ -451,7 +450,9 @@ public interface VaultConnector extends AutoCloseable, Serializable {
* @return Metadata for the created/updated secret. * @return Metadata for the created/updated secret.
* @throws VaultConnectorException on error * @throws VaultConnectorException on error
* @since 0.8 * @since 0.8
* @deprecated Convenience method will be removed in 1.0. Use {@link #writeSecretData(String, String, Map)} instead with mount parameter "secret".
*/ */
@Deprecated
default SecretVersionResponse writeSecretData(final String key, final Map<String, Object> data) throws VaultConnectorException { default SecretVersionResponse writeSecretData(final String key, final Map<String, Object> data) throws VaultConnectorException {
return writeSecretData(PATH_SECRET, key, data, null); return writeSecretData(PATH_SECRET, key, data, null);
} }
@ -500,7 +501,9 @@ public interface VaultConnector extends AutoCloseable, Serializable {
* @return Secret response * @return Secret response
* @throws VaultConnectorException on error * @throws VaultConnectorException on error
* @since 0.8 * @since 0.8
* @deprecated Convenience method will be removed in 1.0. Use {@link #readSecretVersion(String, String, Integer)} instead with mount parameter "secret".
*/ */
@Deprecated
default SecretResponse readSecretVersion(final String key, final Integer version) throws VaultConnectorException { default SecretResponse readSecretVersion(final String key, final Integer version) throws VaultConnectorException {
return readSecretVersion(PATH_SECRET, key, version); return readSecretVersion(PATH_SECRET, key, version);
} }
@ -529,7 +532,9 @@ public interface VaultConnector extends AutoCloseable, Serializable {
* @return Metadata response * @return Metadata response
* @throws VaultConnectorException on error * @throws VaultConnectorException on error
* @since 0.8 * @since 0.8
* @deprecated Convenience method will be removed in 1.0. Use {@link #readSecretMetadata(String, String)} instead with mount parameter "secret".
*/ */
@Deprecated
default MetadataResponse readSecretMetadata(final String key) throws VaultConnectorException { default MetadataResponse readSecretMetadata(final String key) throws VaultConnectorException {
return readSecretMetadata(PATH_SECRET, key); return readSecretMetadata(PATH_SECRET, key);
} }
@ -545,7 +550,9 @@ public interface VaultConnector extends AutoCloseable, Serializable {
* @param casRequired Specify if Check-And-Set is required for this secret. * @param casRequired Specify if Check-And-Set is required for this secret.
* @throws VaultConnectorException on error * @throws VaultConnectorException on error
* @since 0.8 * @since 0.8
* @deprecated Convenience method will be removed in 1.0. Use {@link #updateSecretMetadata(String, String, Integer, boolean)} instead with mount parameter "secret".
*/ */
@Deprecated
default void updateSecretMetadata(final String key, final Integer maxVersions, final boolean casRequired) throws VaultConnectorException { default void updateSecretMetadata(final String key, final Integer maxVersions, final boolean casRequired) throws VaultConnectorException {
updateSecretMetadata(PATH_SECRET, key, maxVersions, casRequired); updateSecretMetadata(PATH_SECRET, key, maxVersions, casRequired);
} }
@ -597,7 +604,9 @@ public interface VaultConnector extends AutoCloseable, Serializable {
* @param path Root path to search * @param path Root path to search
* @return List of secret keys * @return List of secret keys
* @throws VaultConnectorException on error * @throws VaultConnectorException on error
* @deprecated Convenience method will be removed in 1.0. Use {@link #list(String)} instead with key prefix "secret/".
*/ */
@Deprecated
default List<String> listSecrets(final String path) throws VaultConnectorException { default List<String> listSecrets(final String path) throws VaultConnectorException {
return list(PATH_SECRET + "/" + path); return list(PATH_SECRET + "/" + path);
} }
@ -611,9 +620,7 @@ public interface VaultConnector extends AutoCloseable, Serializable {
* @since 0.5.0 * @since 0.5.0
*/ */
default void write(final String key, final String value) throws VaultConnectorException { default void write(final String key, final String value) throws VaultConnectorException {
Map<String, Object> param = new HashMap<>(); write(key, Collections.singletonMap("value", value));
param.put("value", value);
write(key, param);
} }
/** /**
@ -647,11 +654,11 @@ public interface VaultConnector extends AutoCloseable, Serializable {
* @param key Secret path * @param key Secret path
* @param value Secret value * @param value Secret value
* @throws VaultConnectorException on error * @throws VaultConnectorException on error
* @deprecated Convenience method will be removed in 1.0. Use {@link #write(String, String)} instead with key prefix "secret/".
*/ */
@Deprecated
default void writeSecret(final String key, final String value) throws VaultConnectorException { default void writeSecret(final String key, final String value) throws VaultConnectorException {
Map<String, Object> param = new HashMap<>(); writeSecret(key, Collections.singletonMap("value", value));
param.put("value", value);
writeSecret(key, param);
} }
/** /**
@ -663,7 +670,9 @@ public interface VaultConnector extends AutoCloseable, Serializable {
* @param data Secret content. Value must be be JSON serializable. * @param data Secret content. Value must be be JSON serializable.
* @throws VaultConnectorException on error * @throws VaultConnectorException on error
* @since 0.5.0 * @since 0.5.0
* @deprecated Convenience method will be removed in 1.0. Use {@link #write(String, Map)} instead with key prefix "secret/".
*/ */
@Deprecated
default void writeSecret(final String key, final Map<String, Object> data) throws VaultConnectorException { default void writeSecret(final String key, final Map<String, Object> data) throws VaultConnectorException {
if (key == null || key.isEmpty()) { if (key == null || key.isEmpty()) {
throw new InvalidRequestException("Secret path must not be empty."); throw new InvalidRequestException("Secret path must not be empty.");
@ -687,7 +696,9 @@ public interface VaultConnector extends AutoCloseable, Serializable {
* *
* @param key Secret path * @param key Secret path
* @throws VaultConnectorException on error * @throws VaultConnectorException on error
* @deprecated Convenience method will be removed in 1.0. Use {@link #delete(String)} instead with key prefix "secret/".
*/ */
@Deprecated
default void deleteSecret(final String key) throws VaultConnectorException { default void deleteSecret(final String key) throws VaultConnectorException {
delete(PATH_SECRET + "/" + key); delete(PATH_SECRET + "/" + key);
} }
@ -700,7 +711,9 @@ public interface VaultConnector extends AutoCloseable, Serializable {
* @param key Secret path. * @param key Secret path.
* @throws VaultConnectorException on error * @throws VaultConnectorException on error
* @since 0.8 * @since 0.8
* @deprecated Convenience method will be removed in 1.0. Use {@link #deleteLatestSecretVersion(String, String)} instead with mount parameter "secret".
*/ */
@Deprecated
default void deleteLatestSecretVersion(final String key) throws VaultConnectorException { default void deleteLatestSecretVersion(final String key) throws VaultConnectorException {
deleteLatestSecretVersion(PATH_SECRET, key); deleteLatestSecretVersion(PATH_SECRET, key);
} }
@ -726,7 +739,9 @@ public interface VaultConnector extends AutoCloseable, Serializable {
* @param key Secret path. * @param key Secret path.
* @throws VaultConnectorException on error * @throws VaultConnectorException on error
* @since 0.8 * @since 0.8
* @deprecated Convenience method will be removed in 1.0. Use {@link #deleteAllSecretVersions(String)} instead with mount parameter "secret".
*/ */
@Deprecated
default void deleteAllSecretVersions(final String key) throws VaultConnectorException { default void deleteAllSecretVersions(final String key) throws VaultConnectorException {
deleteAllSecretVersions(PATH_SECRET, key); deleteAllSecretVersions(PATH_SECRET, key);
} }
@ -753,7 +768,9 @@ public interface VaultConnector extends AutoCloseable, Serializable {
* @param versions Versions of the secret to delete. * @param versions Versions of the secret to delete.
* @throws VaultConnectorException on error * @throws VaultConnectorException on error
* @since 0.8 * @since 0.8
* @deprecated Convenience method will be removed in 1.0. Use {@link #deleteSecretVersions(String, String, int...)} instead with mount parameter "secret".
*/ */
@Deprecated
default void deleteSecretVersions(final String key, final int... versions) throws VaultConnectorException { default void deleteSecretVersions(final String key, final int... versions) throws VaultConnectorException {
deleteSecretVersions(PATH_SECRET, key, versions); deleteSecretVersions(PATH_SECRET, key, versions);
} }
@ -779,7 +796,9 @@ public interface VaultConnector extends AutoCloseable, Serializable {
* @param versions Versions of the secret to undelete. * @param versions Versions of the secret to undelete.
* @throws VaultConnectorException on error * @throws VaultConnectorException on error
* @since 0.8 * @since 0.8
* @deprecated Convenience method will be removed in 1.0. Use {@link #undeleteSecretVersions(String, String, int...)} instead with mount parameter "secret".
*/ */
@Deprecated
default void undeleteSecretVersions(final String key, final int... versions) throws VaultConnectorException { default void undeleteSecretVersions(final String key, final int... versions) throws VaultConnectorException {
undeleteSecretVersions(PATH_SECRET, key, versions); undeleteSecretVersions(PATH_SECRET, key, versions);
} }
@ -804,7 +823,9 @@ public interface VaultConnector extends AutoCloseable, Serializable {
* @param versions Versions of the secret to destroy. * @param versions Versions of the secret to destroy.
* @throws VaultConnectorException on error * @throws VaultConnectorException on error
* @since 0.8 * @since 0.8
* @deprecated Convenience method will be removed in 1.0. Use {@link #destroySecretVersions(String, String, int...)} instead with mount parameter "secret".
*/ */
@Deprecated
default void destroySecretVersions(final String key, final int... versions) throws VaultConnectorException { default void destroySecretVersions(final String key, final int... versions) throws VaultConnectorException {
destroySecretVersions(PATH_SECRET, key, versions); destroySecretVersions(PATH_SECRET, key, versions);
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,283 +16,17 @@
package de.stklcode.jvault.connector.builder; package de.stklcode.jvault.connector.builder;
import de.stklcode.jvault.connector.HTTPVaultConnector;
import de.stklcode.jvault.connector.exception.ConnectionException;
import de.stklcode.jvault.connector.exception.TlsException;
import de.stklcode.jvault.connector.exception.VaultConnectorException;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
/** /**
* Vault Connector Builder implementation for HTTP Vault connectors. * Vault Connector Builder implementation for HTTP Vault connectors.
* *
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.8.0 * @since 0.8.0
* @since 0.9.5 Extends new class for migration purposes only.
* @deprecated Use {@link de.stklcode.jvault.connector.HTTPVaultConnectorBuilder} instead. Will be removed in 1.0
*/ */
public final class HTTPVaultConnectorBuilder implements VaultConnectorBuilder { @Deprecated
private static final String ENV_VAULT_ADDR = "VAULT_ADDR"; public class HTTPVaultConnectorBuilder extends de.stklcode.jvault.connector.HTTPVaultConnectorBuilder {
private static final String ENV_VAULT_CACERT = "VAULT_CACERT";
private static final String ENV_VAULT_TOKEN = "VAULT_TOKEN";
private static final String ENV_VAULT_MAX_RETRIES = "VAULT_MAX_RETRIES";
public static final String DEFAULT_HOST = "127.0.0.1";
public static final Integer DEFAULT_PORT = 8200;
public static final boolean DEFAULT_TLS = true;
public static final String DEFAULT_TLS_VERSION = "TLSv1.2";
public static final String DEFAULT_PREFIX = "/v1/";
public static final int DEFAULT_NUMBER_OF_RETRIES = 0;
private String host;
private Integer port;
private boolean tls;
private String tlsVersion;
private String prefix;
private X509Certificate trustedCA;
private int numberOfRetries;
private Integer timeout;
private String token;
/**
* Default empty constructor.
* Initializes factory with default values.
*/
public HTTPVaultConnectorBuilder() { public HTTPVaultConnectorBuilder() {
host = DEFAULT_HOST; super();
port = DEFAULT_PORT;
tls = DEFAULT_TLS;
tlsVersion = DEFAULT_TLS_VERSION;
prefix = DEFAULT_PREFIX;
numberOfRetries = DEFAULT_NUMBER_OF_RETRIES;
}
/**
* Set hostname (default: 127.0.0.1).
*
* @param host Hostname or IP address
* @return self
*/
public HTTPVaultConnectorBuilder withHost(final String host) {
this.host = host;
return this;
}
/**
* Set port (default: 8200).
*
* @param port Vault TCP port
* @return self
*/
public HTTPVaultConnectorBuilder withPort(final Integer port) {
this.port = port;
return this;
}
/**
* Set TLS usage (default: TRUE).
*
* @param useTLS use TLS or not
* @return self
*/
public HTTPVaultConnectorBuilder withTLS(final boolean useTLS) {
this.tls = useTLS;
return this;
}
/**
* Set TLS usage (default: TRUE).
*
* @param useTLS Use TLS or not.
* @param version Supported TLS version ({@code TLSv1.2}, {@code TLSv1.1}, {@code TLSv1.0}, {@code TLS}).
* @return self
* @since 0.8 Added version parameter (#22).
*/
public HTTPVaultConnectorBuilder withTLS(final boolean useTLS, final String version) {
this.tls = useTLS;
this.tlsVersion = version;
return this;
}
/**
* Convenience Method for TLS usage (enabled by default).
*
* @param version Supported TLS version ({@code TLSv1.2}, {@code TLSv1.1}, {@code TLSv1.0}, {@code TLS}).
* @return self
* @since 0.8 Added version parameter (#22).
*/
public HTTPVaultConnectorBuilder withTLS(final String version) {
return withTLS(true, version);
}
/**
* Convenience Method for TLS usage (enabled by default).
*
* @return self
*/
public HTTPVaultConnectorBuilder withTLS() {
return withTLS(true);
}
/**
* Convenience Method for NOT using TLS.
*
* @return self
*/
public HTTPVaultConnectorBuilder withoutTLS() {
return withTLS(false);
}
/**
* Set API prefix. Default is "/v1/" and changes should not be necessary for current state of development.
*
* @param prefix Vault API prefix (default: "/v1/"
* @return self
*/
public HTTPVaultConnectorBuilder withPrefix(final String prefix) {
this.prefix = prefix;
return this;
}
/**
* Add a trusted CA certificate for HTTPS connections.
*
* @param cert path to certificate file
* @return self
* @throws VaultConnectorException on error
* @since 0.4.0
*/
public HTTPVaultConnectorBuilder withTrustedCA(final Path cert) throws VaultConnectorException {
if (cert != null) {
return withTrustedCA(certificateFromFile(cert));
} else {
this.trustedCA = null;
}
return this;
}
/**
* Add a trusted CA certificate for HTTPS connections.
*
* @param cert path to certificate file
* @return self
* @since 0.8.0
*/
public HTTPVaultConnectorBuilder withTrustedCA(final X509Certificate cert) {
this.trustedCA = cert;
return this;
}
/**
* Set token for automatic authentication, using {@link #buildAndAuth()}.
*
* @param token Vault token
* @return self
* @since 0.6.0
*/
public HTTPVaultConnectorBuilder withToken(final String token) {
this.token = token;
return this;
}
/**
* Build connector based on the {@code }VAULT_ADDR} and {@code VAULT_CACERT} (optional) environment variables.
*
* @return self
* @throws VaultConnectorException if Vault address from environment variables is malformed
* @since 0.6.0
*/
public HTTPVaultConnectorBuilder fromEnv() throws VaultConnectorException {
/* Parse URL from environment variable */
if (System.getenv(ENV_VAULT_ADDR) != null && !System.getenv(ENV_VAULT_ADDR).trim().isEmpty()) {
try {
URL url = new URL(System.getenv(ENV_VAULT_ADDR));
this.host = url.getHost();
this.port = url.getPort();
this.tls = url.getProtocol().equals("https");
} catch (MalformedURLException e) {
throw new ConnectionException("URL provided in environment variable malformed", e);
}
}
/* Read number of retries */
if (System.getenv(ENV_VAULT_MAX_RETRIES) != null) {
try {
numberOfRetries = Integer.parseInt(System.getenv(ENV_VAULT_MAX_RETRIES));
} catch (NumberFormatException ignored) {
/* Ignore malformed values. */
}
}
/* Read token */
token = System.getenv(ENV_VAULT_TOKEN);
/* Parse certificate, if set */
if (System.getenv(ENV_VAULT_CACERT) != null && !System.getenv(ENV_VAULT_CACERT).trim().isEmpty()) {
return withTrustedCA(Paths.get(System.getenv(ENV_VAULT_CACERT)));
}
return this;
}
/**
* Define the number of retries to attempt on 5xx errors.
*
* @param numberOfRetries The number of retries to attempt on 5xx errors (default: 0)
* @return self
* @since 0.6.0
*/
public HTTPVaultConnectorBuilder withNumberOfRetries(final int numberOfRetries) {
this.numberOfRetries = numberOfRetries;
return this;
}
/**
* Define a custom timeout for the HTTP connection.
*
* @param milliseconds Timeout value in milliseconds.
* @return self
* @since 0.6.0
*/
public HTTPVaultConnectorBuilder withTimeout(final int milliseconds) {
this.timeout = milliseconds;
return this;
}
@Override
public HTTPVaultConnector build() {
return new HTTPVaultConnector(host, tls, tlsVersion, port, prefix, trustedCA, numberOfRetries, timeout);
}
@Override
public HTTPVaultConnector buildAndAuth() throws VaultConnectorException {
if (token == null) {
throw new ConnectionException("No vault token provided, unable to authenticate.");
}
HTTPVaultConnector con = build();
con.authToken(token);
return con;
}
/**
* Read given certificate file to X.509 certificate.
*
* @param certFile Path to certificate file
* @return X.509 Certificate object
* @throws TlsException on error
* @since 0.4.0
*/
private X509Certificate certificateFromFile(final Path certFile) throws TlsException {
try (InputStream is = Files.newInputStream(certFile)) {
return (X509Certificate) CertificateFactory.getInstance("X.509").generateCertificate(is);
} catch (IOException | CertificateException e) {
throw new TlsException("Unable to read certificate.", e);
}
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,6 +16,7 @@
package de.stklcode.jvault.connector.builder; package de.stklcode.jvault.connector.builder;
import de.stklcode.jvault.connector.HTTPVaultConnector;
import de.stklcode.jvault.connector.VaultConnector; import de.stklcode.jvault.connector.VaultConnector;
import de.stklcode.jvault.connector.exception.VaultConnectorException; import de.stklcode.jvault.connector.exception.VaultConnectorException;
@ -31,7 +32,9 @@ public interface VaultConnectorBuilder {
* Get Factory implementation for HTTP Vault Connector. * Get Factory implementation for HTTP Vault Connector.
* *
* @return HTTP Connector Factory * @return HTTP Connector Factory
* @deprecated Use {@link HTTPVaultConnector#builder()} instead. This interface will be removed in 1.0
*/ */
@Deprecated
static HTTPVaultConnectorBuilder http() { static HTTPVaultConnectorBuilder http() {
return new HTTPVaultConnectorBuilder(); return new HTTPVaultConnectorBuilder();
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -26,7 +26,7 @@ public abstract class VaultConnectorException extends Exception {
/** /**
* Constructs a new empty exception. * Constructs a new empty exception.
*/ */
public VaultConnectorException() { protected VaultConnectorException() {
} }
/** /**
@ -34,7 +34,7 @@ public abstract class VaultConnectorException extends Exception {
* *
* @param message the detail message * @param message the detail message
*/ */
public VaultConnectorException(final String message) { protected VaultConnectorException(final String message) {
super(message); super(message);
} }
@ -43,7 +43,7 @@ public abstract class VaultConnectorException extends Exception {
* *
* @param cause the cause * @param cause the cause
*/ */
public VaultConnectorException(final Throwable cause) { protected VaultConnectorException(final Throwable cause) {
super(cause); super(cause);
} }
@ -53,7 +53,7 @@ public abstract class VaultConnectorException extends Exception {
* @param message the detail message * @param message the detail message
* @param cause the cause * @param cause the cause
*/ */
public VaultConnectorException(final String message, final Throwable cause) { protected VaultConnectorException(final String message, final Throwable cause) {
super(message, cause); super(message, cause);
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -17,7 +17,7 @@
package de.stklcode.jvault.connector.factory; package de.stklcode.jvault.connector.factory;
import de.stklcode.jvault.connector.HTTPVaultConnector; import de.stklcode.jvault.connector.HTTPVaultConnector;
import de.stklcode.jvault.connector.builder.HTTPVaultConnectorBuilder; import de.stklcode.jvault.connector.HTTPVaultConnectorBuilder;
import de.stklcode.jvault.connector.exception.VaultConnectorException; import de.stklcode.jvault.connector.exception.VaultConnectorException;
import javax.net.ssl.SSLContext; import javax.net.ssl.SSLContext;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -367,18 +367,22 @@ public final class RequestHelper implements Serializable {
*/ */
private SSLConnectionSocketFactory createSSLSocketFactory() throws TlsException { private SSLConnectionSocketFactory createSSLSocketFactory() throws TlsException {
try { try {
// Create Keystore with trusted certificate. // Create context..
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, null);
keyStore.setCertificateEntry("trustedCert", trustedCaCert);
// Initialize TrustManager.
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(keyStore);
// Create context using this TrustManager.
SSLContext context = SSLContext.getInstance(tlsVersion); SSLContext context = SSLContext.getInstance(tlsVersion);
context.init(null, tmf.getTrustManagers(), new SecureRandom());
if (trustedCaCert != null) {
// Create Keystore with trusted certificate.
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, null);
keyStore.setCertificateEntry("trustedCert", trustedCaCert);
// Initialize TrustManager.
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(keyStore);
context.init(null, tmf.getTrustManagers(), null);
} else {
context.init(null, null, null);
}
return new SSLConnectionSocketFactory( return new SSLConnectionSocketFactory(
context, context,

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -703,21 +703,34 @@ public final class AppRole {
* @return self * @return self
* @since 0.9 * @since 0.9
*/ */
public Builder wit0hTokenPeriod(final Integer tokenPeriod) { public Builder withTokenPeriod(final Integer tokenPeriod) {
this.tokenPeriod = tokenPeriod; this.tokenPeriod = tokenPeriod;
return this; return this;
} }
/**
* Set renewal period for generated token in seconds.
*
* @param tokenPeriod period in seconds
* @return self
* @since 0.9
* @deprecated Use {@link #withTokenPeriod(Integer)} instead.
*/
@Deprecated
public Builder wit0hTokenPeriod(final Integer tokenPeriod) {
return withTokenPeriod(tokenPeriod);
}
/** /**
* Set renewal period for generated token in seconds. * Set renewal period for generated token in seconds.
* *
* @param period period in seconds * @param period period in seconds
* @return self * @return self
* @deprecated Use {@link #wit0hTokenPeriod(Integer)} instead. * @deprecated Use {@link #withTokenPeriod(Integer)} instead.
*/ */
@Deprecated @Deprecated
public Builder withPeriod(final Integer period) { public Builder withPeriod(final Integer period) {
return wit0hTokenPeriod(period); return withTokenPeriod(period);
} }
/** /**

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -308,21 +308,34 @@ public final class AppRoleBuilder {
* @return self * @return self
* @since 0.9 * @since 0.9
*/ */
public AppRoleBuilder wit0hTokenPeriod(final Integer tokenPeriod) { public AppRoleBuilder withTokenPeriod(final Integer tokenPeriod) {
this.tokenPeriod = tokenPeriod; this.tokenPeriod = tokenPeriod;
return this; return this;
} }
/**
* Set renewal period for generated token in seconds.
*
* @param tokenPeriod period in seconds
* @return self
* @since 0.9
* @deprecated Use {@link #withTokenPeriod(Integer)} instead.
*/
@Deprecated
public AppRoleBuilder wit0hTokenPeriod(final Integer tokenPeriod) {
return withTokenPeriod(tokenPeriod);
}
/** /**
* Set renewal period for generated token in seconds. * Set renewal period for generated token in seconds.
* *
* @param period period in seconds * @param period period in seconds
* @return self * @return self
* @deprecated Use {@link #wit0hTokenPeriod(Integer)} instead. * @deprecated Use {@link #withTokenPeriod(Integer)} instead.
*/ */
@Deprecated @Deprecated
public AppRoleBuilder withPeriod(final Integer period) { public AppRoleBuilder withPeriod(final Integer period) {
return wit0hTokenPeriod(period); return withTokenPeriod(period);
} }
/** /**

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -40,7 +40,7 @@ public final class AppRoleResponse extends VaultDataResponse {
ObjectMapper mapper = new ObjectMapper(); ObjectMapper mapper = new ObjectMapper();
try { try {
/* null empty strings on list objects */ /* null empty strings on list objects */
Map<String, Object> filteredData = new HashMap<>(); Map<String, Object> filteredData = new HashMap<>(data.size(), 1);
data.forEach((k, v) -> { data.forEach((k, v) -> {
if (!(v instanceof String && ((String) v).isEmpty())) { if (!(v instanceof String && ((String) v).isEmpty())) {
filteredData.put(k, v); filteredData.put(k, v);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -40,7 +40,7 @@ public final class AppRoleSecretResponse extends VaultDataResponse {
ObjectMapper mapper = new ObjectMapper(); ObjectMapper mapper = new ObjectMapper();
try { try {
/* null empty strings on list objects */ /* null empty strings on list objects */
Map<String, Object> filteredData = new HashMap<>(); Map<String, Object> filteredData = new HashMap<>(data.size(), 1);
data.forEach((k, v) -> { data.forEach((k, v) -> {
if (!(v instanceof String && ((String) v).isEmpty())) { if (!(v instanceof String && ((String) v).isEmpty())) {
filteredData.put(k, v); filteredData.put(k, v);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -22,7 +22,7 @@ import de.stklcode.jvault.connector.exception.InvalidResponseException;
import de.stklcode.jvault.connector.model.response.embedded.VersionMetadata; import de.stklcode.jvault.connector.model.response.embedded.VersionMetadata;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap; import java.util.Collections;
import java.util.Map; import java.util.Map;
/** /**
@ -66,7 +66,7 @@ public class SecretResponse extends VaultDataResponse {
*/ */
public final Map<String, Object> getData() { public final Map<String, Object> getData() {
if (data == null) { if (data == null) {
return new HashMap<>(); return Collections.emptyMap();
} }
return data; return data;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -20,9 +20,6 @@ import de.stklcode.jvault.connector.exception.InvalidRequestException;
import de.stklcode.jvault.connector.exception.InvalidResponseException; import de.stklcode.jvault.connector.exception.InvalidResponseException;
import de.stklcode.jvault.connector.exception.PermissionDeniedException; import de.stklcode.jvault.connector.exception.PermissionDeniedException;
import de.stklcode.jvault.connector.exception.VaultConnectorException; import de.stklcode.jvault.connector.exception.VaultConnectorException;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.agent.ByteBuddyAgent;
import net.bytebuddy.dynamic.loading.ClassReloadingStrategy;
import org.apache.http.ProtocolVersion; import org.apache.http.ProtocolVersion;
import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.entity.ContentType; import org.apache.http.entity.ContentType;
@ -30,9 +27,9 @@ import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicStatusLine; import org.apache.http.message.BasicStatusLine;
import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.*;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.function.Executable;
import org.junit.jupiter.api.Test; import org.mockito.MockedStatic;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@ -42,13 +39,12 @@ import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.util.Collections; import java.util.Collections;
import static net.bytebuddy.implementation.MethodDelegation.to;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static org.hamcrest.CoreMatchers.instanceOf; import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.nullValue; import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is; import static org.hamcrest.core.Is.is;
import static org.junit.jupiter.api.Assertions.fail; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*; import static org.mockito.Mockito.*;
@ -59,79 +55,68 @@ import static org.mockito.Mockito.*;
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.7.0 * @since 0.7.0
*/ */
public class HTTPVaultConnectorOfflineTest { class HTTPVaultConnectorOfflineTest {
private static final String INVALID_URL = "foo:/\\1nv4l1d_UrL"; private static final String INVALID_URL = "foo:/\\1nv4l1d_UrL";
private static CloseableHttpClient httpMock = mock(CloseableHttpClient.class); private static MockedStatic<HttpClientBuilder> hcbMock;
private CloseableHttpResponse responseMock = mock(CloseableHttpResponse.class); private static CloseableHttpClient httpMock;
private final CloseableHttpResponse responseMock = mock(CloseableHttpResponse.class);
@BeforeAll @BeforeAll
public static void initByteBuddy() { static void prepare() {
// Install ByteBuddy Agent. // Mock the static HTTPClient creation.
ByteBuddyAgent.install(); hcbMock = mockStatic(HttpClientBuilder.class);
hcbMock.when(HttpClientBuilder::create).thenReturn(new MockedHttpClientBuilder());
} }
/** @AfterAll
* Helper method for redefinition of {@link HttpClientBuilder#create()} from {@link #initHttpMock()}. static void tearDown() {
* hcbMock.close();
* @return Mocked HTTP client builder. }
*/
public static HttpClientBuilder create() {
return new MockedHttpClientBuilder();
}
@BeforeEach @BeforeEach
public void initHttpMock() { void init() {
// Redefine static method to return Mock on HttpClientBuilder creation.
new ByteBuddy().redefine(HttpClientBuilder.class)
.method(named("create"))
.intercept(to(HTTPVaultConnectorOfflineTest.class))
.make()
.load(HttpClientBuilder.class.getClassLoader(), ClassReloadingStrategy.fromInstalledAgent());
// Re-initialize HTTP mock to ensure fresh (empty) results. // Re-initialize HTTP mock to ensure fresh (empty) results.
httpMock = mock(CloseableHttpClient.class); httpMock = mock(CloseableHttpClient.class);
} }
/** /**
* Test exceptions thrown during request. * Test exceptions thrown during request.
*/ */
@Test @Test
public void requestExceptionTest() throws IOException { void requestExceptionTest() throws IOException {
HTTPVaultConnector connector = new HTTPVaultConnector("http://127.0.0.1", null, 0, 250); HTTPVaultConnector connector = new HTTPVaultConnector("http://127.0.0.1", null, 0, 250);
// Test invalid response code. // Test invalid response code.
final int responseCode = 400; final int responseCode = 400;
mockResponse(responseCode, "", ContentType.APPLICATION_JSON); mockResponse(responseCode, "", ContentType.APPLICATION_JSON);
try { InvalidResponseException e = assertThrows(
connector.getHealth(); InvalidResponseException.class,
fail("Querying health status succeeded on invalid instance"); connector::getHealth,
} catch (Exception e) { "Querying health status succeeded on invalid instance"
assertThat("Unexpected type of exception", e, instanceOf(InvalidResponseException.class)); );
assertThat("Unexpected exception message", e.getMessage(), is("Invalid response code")); assertThat("Unexpected exception message", e.getMessage(), is("Invalid response code"));
assertThat("Unexpected status code in exception", ((InvalidResponseException) e).getStatusCode(), is(responseCode)); assertThat("Unexpected status code in exception", ((InvalidResponseException) e).getStatusCode(), is(responseCode));
assertThat("Response message where none was expected", ((InvalidResponseException) e).getResponse(), is(nullValue())); assertThat("Response message where none was expected", ((InvalidResponseException) e).getResponse(), is(nullValue()));
}
// Simulate permission denied response. // Simulate permission denied response.
mockResponse(responseCode, "{\"errors\":[\"permission denied\"]}", ContentType.APPLICATION_JSON); mockResponse(responseCode, "{\"errors\":[\"permission denied\"]}", ContentType.APPLICATION_JSON);
try { assertThrows(
connector.getHealth(); PermissionDeniedException.class,
fail("Querying health status succeeded on invalid instance"); connector::getHealth,
} catch (Exception e) { "Querying health status succeeded on invalid instance"
assertThat("Unexpected type of exception", e, instanceOf(PermissionDeniedException.class)); );
}
// Test exception thrown during request. // Test exception thrown during request.
when(httpMock.execute(any())).thenThrow(new IOException("Test Exception")); when(httpMock.execute(any())).thenThrow(new IOException("Test Exception"));
try { e = assertThrows(
connector.getHealth(); InvalidResponseException.class,
fail("Querying health status succeeded on invalid instance"); connector::getHealth,
} catch (Exception e) { "Querying health status succeeded on invalid instance"
assertThat("Unexpected type of exception", e, instanceOf(InvalidResponseException.class)); );
assertThat("Unexpected exception message", e.getMessage(), is("Unable to read response")); assertThat("Unexpected exception message", e.getMessage(), is("Unable to read response"));
assertThat("Unexpected cause", e.getCause(), instanceOf(IOException.class)); assertThat("Unexpected cause", e.getCause(), instanceOf(IOException.class));
}
// Now simulate a failing request that succeeds on second try. // Now simulate a failing request that succeeds on second try.
connector = new HTTPVaultConnector("https://127.0.0.1", null, 1, 250); connector = new HTTPVaultConnector("https://127.0.0.1", null, 1, 250);
@ -143,18 +128,14 @@ public class HTTPVaultConnectorOfflineTest {
.when(responseMock).getStatusLine(); .when(responseMock).getStatusLine();
when(responseMock.getEntity()).thenReturn(new StringEntity("{}", ContentType.APPLICATION_JSON)); when(responseMock.getEntity()).thenReturn(new StringEntity("{}", ContentType.APPLICATION_JSON));
try { assertDoesNotThrow(connector::getHealth, "Request failed unexpectedly");
connector.getHealth();
} catch (Exception e) {
fail("Request failed unexpectedly: " + e.getMessage());
}
} }
/** /**
* Test constructors of the {@link HTTPVaultConnector} class. * Test constructors of the {@link HTTPVaultConnector} class.
*/ */
@Test @Test
public void constructorTest() throws IOException, CertificateException { void constructorTest() throws IOException, CertificateException {
final String url = "https://vault.example.net/test/"; final String url = "https://vault.example.net/test/";
final String hostname = "vault.example.com"; final String hostname = "vault.example.com";
final Integer port = 1337; final Integer port = 1337;
@ -206,60 +187,53 @@ public class HTTPVaultConnectorOfflineTest {
* This test is designed to test exceptions caught and thrown by seal-methods if Vault is not reachable. * This test is designed to test exceptions caught and thrown by seal-methods if Vault is not reachable.
*/ */
@Test @Test
public void sealExceptionTest() throws IOException { void sealExceptionTest() {
HTTPVaultConnector connector = new HTTPVaultConnector(INVALID_URL); HTTPVaultConnector connector = new HTTPVaultConnector(INVALID_URL);
try { VaultConnectorException e = assertThrows(
connector.sealStatus(); InvalidRequestException.class,
fail("Querying seal status succeeded on invalid URL"); connector::sealStatus,
} catch (Exception e) { "Querying seal status succeeded on invalid URL"
assertThat("Unexpected type of exception", e, instanceOf(InvalidRequestException.class)); );
assertThat("Unexpected exception message", e.getMessage(), is("Invalid URI format")); assertThat("Unexpected exception message", e.getMessage(), is("Invalid URI format"));
}
connector = new HTTPVaultConnector("https://127.0.0.1", null, 0, 250);
// Simulate NULL response (mock not supplied with data). // Simulate NULL response (mock not supplied with data).
connector = new HTTPVaultConnector("https://127.0.0.1", null, 0, 250);
try { e = assertThrows(
connector.sealStatus(); InvalidResponseException.class,
fail("Querying seal status succeeded on invalid instance"); connector::sealStatus,
} catch (Exception e) { "Querying seal status succeeded on invalid instance"
assertThat("Unexpected type of exception", e, instanceOf(InvalidResponseException.class)); );
assertThat("Unexpected exception message", e.getMessage(), is("Response unavailable")); assertThat("Unexpected exception message", e.getMessage(), is("Response unavailable"));
}
} }
/** /**
* This test is designed to test exceptions caught and thrown by seal-methods if Vault is not reachable. * This test is designed to test exceptions caught and thrown by seal-methods if Vault is not reachable.
*/ */
@Test @Test
public void healthExceptionTest() throws IOException { void healthExceptionTest() {
HTTPVaultConnector connector = new HTTPVaultConnector(INVALID_URL); HTTPVaultConnector connector = new HTTPVaultConnector(INVALID_URL);
try { VaultConnectorException e = assertThrows(
connector.getHealth(); InvalidRequestException.class,
fail("Querying health status succeeded on invalid URL"); connector::getHealth,
} catch (Exception e) { "Querying health status succeeded on invalid URL"
assertThat("Unexpected type of exception", e, instanceOf(InvalidRequestException.class)); );
assertThat("Unexpected exception message", e.getMessage(), is("Invalid URI format")); assertThat("Unexpected exception message", e.getMessage(), is("Invalid URI format"));
}
connector = new HTTPVaultConnector("https://127.0.0.1", null, 0, 250);
// Simulate NULL response (mock not supplied with data). // Simulate NULL response (mock not supplied with data).
try { connector = new HTTPVaultConnector("https://127.0.0.1", null, 0, 250);
connector.getHealth(); e = assertThrows(
fail("Querying health status succeeded on invalid instance"); InvalidResponseException.class,
} catch (Exception e) { connector::getHealth,
assertThat("Unexpected type of exception", e, instanceOf(InvalidResponseException.class)); "Querying health status succeeded on invalid instance"
assertThat("Unexpected exception message", e.getMessage(), is("Response unavailable")); );
} assertThat("Unexpected exception message", e.getMessage(), is("Response unavailable"));
} }
/** /**
* Test behavior on unparsable responses. * Test behavior on unparsable responses.
*/ */
@Test @Test
public void parseExceptionTest() throws IOException { void parseExceptionTest() throws IOException {
HTTPVaultConnector connector = new HTTPVaultConnector("https://127.0.0.1", null, 0, 250); HTTPVaultConnector connector = new HTTPVaultConnector("https://127.0.0.1", null, 0, 250);
// Mock authorization. // Mock authorization.
setPrivate(connector, "authorized", true); setPrivate(connector, "authorized", true);
@ -267,114 +241,25 @@ public class HTTPVaultConnectorOfflineTest {
mockResponse(200, "invalid", ContentType.APPLICATION_JSON); mockResponse(200, "invalid", ContentType.APPLICATION_JSON);
// Now test the methods. // Now test the methods.
try { assertParseError(connector::sealStatus, "sealStatus() succeeded on invalid instance");
connector.sealStatus(); assertParseError(() -> connector.unseal("key"), "unseal() succeeded on invalid instance");
fail("sealStatus() succeeded on invalid instance"); assertParseError(connector::getHealth, "getHealth() succeeded on invalid instance");
} catch (Exception e) { assertParseError(connector::getAuthBackends, "getAuthBackends() succeeded on invalid instance");
assertParseError(e); assertParseError(() -> connector.authToken("token"), "authToken() succeeded on invalid instance");
} assertParseError(() -> connector.lookupAppRole("roleName"), "lookupAppRole() succeeded on invalid instance");
assertParseError(() -> connector.getAppRoleID("roleName"), "getAppRoleID() succeeded on invalid instance");
try { assertParseError(() -> connector.createAppRoleSecret("roleName"), "createAppRoleSecret() succeeded on invalid instance");
connector.unseal("key"); assertParseError(() -> connector.lookupAppRoleSecret("roleName", "secretID"), "lookupAppRoleSecret() succeeded on invalid instance");
fail("unseal() succeeded on invalid instance"); assertParseError(connector::listAppRoles, "listAppRoles() succeeded on invalid instance");
} catch (Exception e) { assertParseError(() -> connector.listAppRoleSecrets("roleName"), "listAppRoleSecrets() succeeded on invalid instance");
assertParseError(e); assertParseError(() -> connector.read("key"), "read() succeeded on invalid instance");
} assertParseError(() -> connector.list("path"), "list() succeeded on invalid instance");
assertParseError(() -> connector.renew("leaseID"), "renew() succeeded on invalid instance");
try { assertParseError(() -> connector.lookupToken("token"), "lookupToken() succeeded on invalid instance");
connector.getHealth();
fail("getHealth() succeeded on invalid instance");
} catch (Exception e) {
assertParseError(e);
}
try {
connector.getAuthBackends();
fail("getAuthBackends() succeeded on invalid instance");
} catch (Exception e) {
assertParseError(e);
}
try {
connector.authToken("token");
fail("authToken() succeeded on invalid instance");
} catch (Exception e) {
assertParseError(e);
}
try {
connector.lookupAppRole("roleName");
fail("lookupAppRole() succeeded on invalid instance");
} catch (Exception e) {
assertParseError(e);
}
try {
connector.getAppRoleID("roleName");
fail("getAppRoleID() succeeded on invalid instance");
} catch (Exception e) {
assertParseError(e);
}
try {
connector.createAppRoleSecret("roleName");
fail("createAppRoleSecret() succeeded on invalid instance");
} catch (Exception e) {
assertParseError(e);
}
try {
connector.lookupAppRoleSecret("roleName", "secretID");
fail("lookupAppRoleSecret() succeeded on invalid instance");
} catch (Exception e) {
assertParseError(e);
}
try {
connector.listAppRoles();
fail("listAppRoles() succeeded on invalid instance");
} catch (Exception e) {
assertParseError(e);
}
try {
connector.listAppRoleSecrets("roleName");
fail("listAppRoleSecrets() succeeded on invalid instance");
} catch (Exception e) {
assertParseError(e);
}
try {
connector.read("key");
fail("read() succeeded on invalid instance");
} catch (Exception e) {
assertParseError(e);
}
try {
connector.list("path");
fail("list() succeeded on invalid instance");
} catch (Exception e) {
assertParseError(e);
}
try {
connector.renew("leaseID");
fail("renew() succeeded on invalid instance");
} catch (Exception e) {
assertParseError(e);
}
try {
connector.lookupToken("token");
fail("lookupToken() succeeded on invalid instance");
} catch (Exception e) {
assertParseError(e);
}
} }
private void assertParseError(Exception e) { private void assertParseError(Executable executable, String message) {
assertThat("Unexpected type of exception", e, instanceOf(InvalidResponseException.class)); InvalidResponseException e = assertThrows(InvalidResponseException.class, executable, message);
assertThat("Unexpected exception message", e.getMessage(), is("Unable to parse response")); assertThat("Unexpected exception message", e.getMessage(), is("Unable to parse response"));
} }
@ -382,7 +267,7 @@ public class HTTPVaultConnectorOfflineTest {
* Test requests that expect an empty response with code 204, but receive a 200 body. * Test requests that expect an empty response with code 204, but receive a 200 body.
*/ */
@Test @Test
public void nonEmpty204ResponseTest() throws IOException { void nonEmpty204ResponseTest() throws IOException {
HTTPVaultConnector connector = new HTTPVaultConnector("https://127.0.0.1", null, 0, 250); HTTPVaultConnector connector = new HTTPVaultConnector("https://127.0.0.1", null, 0, 250);
// Mock authorization. // Mock authorization.
setPrivate(connector, "authorized", true); setPrivate(connector, "authorized", true);
@ -390,71 +275,62 @@ public class HTTPVaultConnectorOfflineTest {
mockResponse(200, "{}", ContentType.APPLICATION_JSON); mockResponse(200, "{}", ContentType.APPLICATION_JSON);
// Now test the methods expecting a 204. // Now test the methods expecting a 204.
try { assertThrows(
connector.registerAppId("appID", "policy", "displayName"); InvalidResponseException.class,
fail("registerAppId() with 200 response succeeded"); () -> connector.registerAppId("appID", "policy", "displayName"),
} catch (VaultConnectorException e) { "registerAppId() with 200 response succeeded"
assertThat("Unexpected exception type", e, instanceOf(InvalidResponseException.class)); );
}
try { assertThrows(
connector.registerUserId("appID", "userID"); InvalidResponseException.class,
fail("registerUserId() with 200 response succeeded"); () -> connector.registerUserId("appID", "userID"),
} catch (VaultConnectorException e) { "registerUserId() with 200 response succeeded"
assertThat("Unexpected exception type", e, instanceOf(InvalidResponseException.class)); );
}
try { assertThrows(
connector.createAppRole("appID", Collections.singletonList("policy")); InvalidResponseException.class,
fail("createAppRole() with 200 response succeeded"); () -> connector.createAppRole("appID", Collections.singletonList("policy")),
} catch (VaultConnectorException e) { "createAppRole() with 200 response succeeded"
assertThat("Unexpected exception type", e, instanceOf(InvalidResponseException.class)); );
}
try { assertThrows(
connector.deleteAppRole("roleName"); InvalidResponseException.class,
fail("deleteAppRole() with 200 response succeeded"); () -> connector.deleteAppRole("roleName"),
} catch (VaultConnectorException e) { "deleteAppRole() with 200 response succeeded"
assertThat("Unexpected exception type", e, instanceOf(InvalidResponseException.class)); );
}
try { assertThrows(
connector.setAppRoleID("roleName", "roleID"); InvalidResponseException.class,
fail("setAppRoleID() with 200 response succeeded"); () -> connector.setAppRoleID("roleName", "roleID"),
} catch (VaultConnectorException e) { "setAppRoleID() with 200 response succeeded"
assertThat("Unexpected exception type", e, instanceOf(InvalidResponseException.class)); );
}
try { assertThrows(
connector.destroyAppRoleSecret("roleName", "secretID"); InvalidResponseException.class,
fail("destroyAppRoleSecret() with 200 response succeeded"); () -> connector.destroyAppRoleSecret("roleName", "secretID"),
} catch (VaultConnectorException e) { "destroyAppRoleSecret() with 200 response succeeded"
assertThat("Unexpected exception type", e, instanceOf(InvalidResponseException.class)); );
}
try { assertThrows(
connector.destroyAppRoleSecret("roleName", "secretUD"); InvalidResponseException.class,
fail("destroyAppRoleSecret() with 200 response succeeded"); () -> connector.destroyAppRoleSecret("roleName", "secretUD"),
} catch (VaultConnectorException e) { "destroyAppRoleSecret() with 200 response succeeded"
assertThat("Unexpected exception type", e, instanceOf(InvalidResponseException.class)); );
}
try { assertThrows(
connector.delete("key"); InvalidResponseException.class,
fail("delete() with 200 response succeeded"); () -> connector.delete("key"),
} catch (VaultConnectorException e) { "delete() with 200 response succeeded"
assertThat("Unexpected exception type", e, instanceOf(InvalidResponseException.class)); );
}
try { assertThrows(
connector.revoke("leaseID"); InvalidResponseException.class,
fail("destroyAppRoleSecret() with 200 response succeeded"); () -> connector.revoke("leaseID"),
} catch (VaultConnectorException e) { "destroyAppRoleSecret() with 200 response succeeded"
assertThat("Unexpected exception type", e, instanceOf(InvalidResponseException.class)); );
}
} }
private Object getRequestHelperPrivate(HTTPVaultConnector connector, String fieldName) { private Object getRequestHelperPrivate(HTTPVaultConnector connector, String fieldName) {
try { try {
return getPrivate(getPrivate(connector, "request"), fieldName); return getPrivate(getPrivate(connector, "request"), fieldName);
} catch (NoSuchFieldException | IllegalAccessException e) { } catch (NoSuchFieldException | IllegalAccessException e) {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,21 +16,22 @@
package de.stklcode.jvault.connector.builder; package de.stklcode.jvault.connector.builder;
import com.github.stefanbirkner.systemlambda.SystemLambda;
import de.stklcode.jvault.connector.HTTPVaultConnector; import de.stklcode.jvault.connector.HTTPVaultConnector;
import de.stklcode.jvault.connector.HTTPVaultConnectorBuilder;
import de.stklcode.jvault.connector.exception.TlsException; import de.stklcode.jvault.connector.exception.TlsException;
import de.stklcode.jvault.connector.exception.VaultConnectorException;
import de.stklcode.jvault.connector.test.EnvironmentMock;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir; import org.junit.jupiter.api.io.TempDir;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.nio.file.NoSuchFileException; import java.nio.file.NoSuchFileException;
import static com.github.stefanbirkner.systemlambda.SystemLambda.withEnvironmentVariable;
import static org.hamcrest.CoreMatchers.*; import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.fail; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertThrows;
/** /**
* JUnit test for HTTP Vault connector factory * JUnit test for HTTP Vault connector factory
@ -38,7 +39,7 @@ import static org.junit.jupiter.api.Assertions.fail;
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.8.0 * @since 0.8.0
*/ */
public class HTTPVaultConnectorBuilderTest { class HTTPVaultConnectorBuilderTest {
private static final String VAULT_ADDR = "https://localhost:8201"; private static final String VAULT_ADDR = "https://localhost:8201";
private static final Integer VAULT_MAX_RETRIES = 13; private static final Integer VAULT_MAX_RETRIES = 13;
private static final String VAULT_TOKEN = "00001111-2222-3333-4444-555566667777"; private static final String VAULT_TOKEN = "00001111-2222-3333-4444-555566667777";
@ -50,66 +51,68 @@ public class HTTPVaultConnectorBuilderTest {
* Test building from environment variables * Test building from environment variables
*/ */
@Test @Test
void testFromEnv() throws NoSuchFieldException, IllegalAccessException, IOException { void testFromEnv() throws Exception {
/* Provide address only should be enough */ /* Provide address only should be enough */
setenv(VAULT_ADDR, null, null, null); withVaultEnv(VAULT_ADDR, null, null, null).execute(() -> {
HTTPVaultConnectorBuilder builder = assertDoesNotThrow(
() -> HTTPVaultConnector.builder().fromEnv(),
"Factory creation from minimal environment failed"
);
HTTPVaultConnector connector = builder.build();
HTTPVaultConnectorBuilder factory = null; assertThat("URL nor set correctly", getRequestHelperPrivate(connector, "baseURL"), is(equalTo(VAULT_ADDR + "/v1/")));
HTTPVaultConnector connector; assertThat("Trusted CA cert set when no cert provided", getRequestHelperPrivate(connector, "trustedCaCert"), is(nullValue()));
try { assertThat("Non-default number of retries, when none set", getRequestHelperPrivate(connector, "retries"), is(0));
factory = VaultConnectorBuilder.http().fromEnv();
} catch (VaultConnectorException e) {
fail("Factory creation from minimal environment failed");
}
connector = factory.build();
assertThat("URL nor set correctly", getRequestHelperPrivate(connector, "baseURL"), is(equalTo(VAULT_ADDR + "/v1/"))); return null;
assertThat("Trusted CA cert set when no cert provided", getRequestHelperPrivate(connector, "trustedCaCert"), is(nullValue())); });
assertThat("Non-default number of retries, when none set", getRequestHelperPrivate(connector, "retries"), is(0));
/* Provide address and number of retries */ /* Provide address and number of retries */
setenv(VAULT_ADDR, null, VAULT_MAX_RETRIES.toString(), null); withVaultEnv(VAULT_ADDR, null, VAULT_MAX_RETRIES.toString(), null).execute(() -> {
HTTPVaultConnectorBuilder builder = assertDoesNotThrow(
() -> HTTPVaultConnector.builder().fromEnv(),
"Factory creation from environment failed"
);
HTTPVaultConnector connector = builder.build();
try { assertThat("URL nor set correctly", getRequestHelperPrivate(connector, "baseURL"), is(equalTo(VAULT_ADDR + "/v1/")));
factory = VaultConnectorBuilder.http().fromEnv(); assertThat("Trusted CA cert set when no cert provided", getRequestHelperPrivate(connector, "trustedCaCert"), is(nullValue()));
} catch (VaultConnectorException e) { assertThat("Number of retries not set correctly", getRequestHelperPrivate(connector, "retries"), is(VAULT_MAX_RETRIES));
fail("Factory creation from environment failed");
}
connector = factory.build();
assertThat("URL nor set correctly", getRequestHelperPrivate(connector, "baseURL"), is(equalTo(VAULT_ADDR + "/v1/"))); return null;
assertThat("Trusted CA cert set when no cert provided", getRequestHelperPrivate(connector, "trustedCaCert"), is(nullValue())); });
assertThat("Number of retries not set correctly", getRequestHelperPrivate(connector, "retries"), is(VAULT_MAX_RETRIES));
/* Provide CA certificate */ /* Provide CA certificate */
String VAULT_CACERT = tempDir.toString() + "/doesnotexist"; String VAULT_CACERT = tempDir.toString() + "/doesnotexist";
setenv(VAULT_ADDR, VAULT_CACERT, VAULT_MAX_RETRIES.toString(), null); withVaultEnv(VAULT_ADDR, VAULT_CACERT, VAULT_MAX_RETRIES.toString(), null).execute(() -> {
TlsException e = assertThrows(
try { TlsException.class,
VaultConnectorBuilder.http().fromEnv(); () -> HTTPVaultConnector.builder().fromEnv(),
fail("Creation with unknown cert path failed."); "Creation with unknown cert path failed."
} catch (VaultConnectorException e) { );
assertThat(e, is(instanceOf(TlsException.class)));
assertThat(e.getCause(), is(instanceOf(NoSuchFileException.class))); assertThat(e.getCause(), is(instanceOf(NoSuchFileException.class)));
assertThat(((NoSuchFileException) e.getCause()).getFile(), is(VAULT_CACERT)); assertThat(((NoSuchFileException) e.getCause()).getFile(), is(VAULT_CACERT));
}
return null;
});
/* Automatic authentication */ /* Automatic authentication */
setenv(VAULT_ADDR, null, VAULT_MAX_RETRIES.toString(), VAULT_TOKEN); withVaultEnv(VAULT_ADDR, null, VAULT_MAX_RETRIES.toString(), VAULT_TOKEN).execute(() -> {
HTTPVaultConnectorBuilder builder = assertDoesNotThrow(
() -> HTTPVaultConnector.builder().fromEnv(),
"Factory creation from minimal environment failed"
);
assertThat("Token nor set correctly", getPrivate(builder, "token"), is(equalTo(VAULT_TOKEN)));
try { return null;
factory = VaultConnectorBuilder.http().fromEnv(); });
} catch (VaultConnectorException e) {
fail("Factory creation from minimal environment failed");
}
assertThat("Token nor set correctly", getPrivate(factory, "token"), is(equalTo(VAULT_TOKEN)));
} }
private void setenv(String vault_addr, String vault_cacert, String vault_max_retries, String vault_token) { private SystemLambda.WithEnvironmentVariables withVaultEnv(String vault_addr, String vault_cacert, String vault_max_retries, String vault_token) {
EnvironmentMock.setenv("VAULT_ADDR", vault_addr); return withEnvironmentVariable("VAULT_ADDR", vault_addr)
EnvironmentMock.setenv("VAULT_CACERT", vault_cacert); .and("VAULT_CACERT", vault_cacert)
EnvironmentMock.setenv("VAULT_MAX_RETRIES", vault_max_retries); .and("VAULT_MAX_RETRIES", vault_max_retries)
EnvironmentMock.setenv("VAULT_TOKEN", vault_token); .and("VAULT_TOKEN", vault_token);
} }
private Object getRequestHelperPrivate(HTTPVaultConnector connector, String fieldName) throws NoSuchFieldException, IllegalAccessException { private Object getRequestHelperPrivate(HTTPVaultConnector connector, String fieldName) throws NoSuchFieldException, IllegalAccessException {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -29,19 +29,19 @@ import static org.hamcrest.core.Is.is;
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.6.2 * @since 0.6.2
*/ */
public class VaultConnectorExceptionTest { class VaultConnectorExceptionTest {
private static final String MSG = "This is a test exception!"; private static final String MSG = "This is a test exception!";
private static final Throwable CAUSE = new Exception("Test-Cause"); private static final Throwable CAUSE = new Exception("Test-Cause");
private static final Integer STATUS_CODE = 1337; private static final Integer STATUS_CODE = 1337;
private static final String RESPONSE = "Dummy response"; private static final String RESPONSE = "Dummy response";
@Test @Test
public void authorizationRequiredExceptionTest() { void authorizationRequiredExceptionTest() {
assertEmptyConstructor(new AuthorizationRequiredException()); assertEmptyConstructor(new AuthorizationRequiredException());
} }
@Test @Test
public void connectionExceptionTest() { void connectionExceptionTest() {
assertEmptyConstructor(new ConnectionException()); assertEmptyConstructor(new ConnectionException());
assertMsgConstructor(new ConnectionException(MSG)); assertMsgConstructor(new ConnectionException(MSG));
assertCauseConstructor(new ConnectionException(CAUSE)); assertCauseConstructor(new ConnectionException(CAUSE));
@ -49,7 +49,7 @@ public class VaultConnectorExceptionTest {
} }
@Test @Test
public void invalidRequestExceptionTest() { void invalidRequestExceptionTest() {
assertEmptyConstructor(new InvalidRequestException()); assertEmptyConstructor(new InvalidRequestException());
assertMsgConstructor(new InvalidRequestException(MSG)); assertMsgConstructor(new InvalidRequestException(MSG));
assertCauseConstructor(new InvalidRequestException(CAUSE)); assertCauseConstructor(new InvalidRequestException(CAUSE));
@ -57,7 +57,7 @@ public class VaultConnectorExceptionTest {
} }
@Test @Test
public void invalidResponseExceptionTest() { void invalidResponseExceptionTest() {
assertEmptyConstructor(new InvalidResponseException()); assertEmptyConstructor(new InvalidResponseException());
assertMsgConstructor(new InvalidResponseException(MSG)); assertMsgConstructor(new InvalidResponseException(MSG));
assertCauseConstructor(new InvalidResponseException(CAUSE)); assertCauseConstructor(new InvalidResponseException(CAUSE));
@ -93,7 +93,7 @@ public class VaultConnectorExceptionTest {
} }
@Test @Test
public void permissionDeniedExceptionTest() { void permissionDeniedExceptionTest() {
// Default message overwritten. // Default message overwritten.
PermissionDeniedException e = new PermissionDeniedException(); PermissionDeniedException e = new PermissionDeniedException();
assertThat(e, is(instanceOf(VaultConnectorException.class))); assertThat(e, is(instanceOf(VaultConnectorException.class)));
@ -108,7 +108,7 @@ public class VaultConnectorExceptionTest {
} }
@Test @Test
public void tlsExceptionTest() { void tlsExceptionTest() {
assertEmptyConstructor(new TlsException()); assertEmptyConstructor(new TlsException());
assertMsgConstructor(new TlsException(MSG)); assertMsgConstructor(new TlsException(MSG));
assertCauseConstructor(new TlsException(CAUSE)); assertCauseConstructor(new TlsException(CAUSE));

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,21 +16,21 @@
package de.stklcode.jvault.connector.factory; package de.stklcode.jvault.connector.factory;
import com.github.stefanbirkner.systemlambda.SystemLambda;
import de.stklcode.jvault.connector.HTTPVaultConnector; import de.stklcode.jvault.connector.HTTPVaultConnector;
import de.stklcode.jvault.connector.exception.TlsException; import de.stklcode.jvault.connector.exception.TlsException;
import de.stklcode.jvault.connector.exception.VaultConnectorException;
import de.stklcode.jvault.connector.test.EnvironmentMock;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir; import org.junit.jupiter.api.io.TempDir;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.nio.file.NoSuchFileException; import java.nio.file.NoSuchFileException;
import static com.github.stefanbirkner.systemlambda.SystemLambda.withEnvironmentVariable;
import static org.hamcrest.CoreMatchers.*; import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.fail; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertThrows;
/** /**
* JUnit test for HTTP Vault connector factory * JUnit test for HTTP Vault connector factory
@ -38,7 +38,7 @@ import static org.junit.jupiter.api.Assertions.fail;
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.6.0 * @since 0.6.0
*/ */
public class HTTPVaultConnectorFactoryTest { class HTTPVaultConnectorFactoryTest {
private static String VAULT_ADDR = "https://localhost:8201"; private static String VAULT_ADDR = "https://localhost:8201";
private static Integer VAULT_MAX_RETRIES = 13; private static Integer VAULT_MAX_RETRIES = 13;
private static String VAULT_TOKEN = "00001111-2222-3333-4444-555566667777"; private static String VAULT_TOKEN = "00001111-2222-3333-4444-555566667777";
@ -50,66 +50,68 @@ public class HTTPVaultConnectorFactoryTest {
* Test building from environment variables * Test building from environment variables
*/ */
@Test @Test
public void testFromEnv() throws NoSuchFieldException, IllegalAccessException, IOException { void testFromEnv() throws Exception {
/* Provide address only should be enough */ /* Provide address only should be enough */
setenv(VAULT_ADDR, null, null, null); withVaultEnv(VAULT_ADDR, null, null, null).execute(() -> {
HTTPVaultConnectorFactory factory = assertDoesNotThrow(
() -> VaultConnectorFactory.httpFactory().fromEnv(),
"Factory creation from minimal environment failed"
);
HTTPVaultConnector connector = factory.build();
HTTPVaultConnectorFactory factory = null; assertThat("URL nor set correctly", getRequestHelperPrivate(connector, "baseURL"), is(equalTo(VAULT_ADDR + "/v1/")));
HTTPVaultConnector connector; assertThat("Trusted CA cert set when no cert provided", getRequestHelperPrivate(connector, "trustedCaCert"), is(nullValue()));
try { assertThat("Non-default number of retries, when none set", getRequestHelperPrivate(connector, "retries"), is(0));
factory = VaultConnectorFactory.httpFactory().fromEnv();
} catch (VaultConnectorException e) {
fail("Factory creation from minimal environment failed");
}
connector = factory.build();
assertThat("URL nor set correctly", getRequestHelperPrivate(connector, "baseURL"), is(equalTo(VAULT_ADDR + "/v1/"))); return null;
assertThat("Trusted CA cert set when no cert provided", getRequestHelperPrivate(connector, "trustedCaCert"), is(nullValue())); });
assertThat("Non-default number of retries, when none set", getRequestHelperPrivate(connector, "retries"), is(0));
/* Provide address and number of retries */ /* Provide address and number of retries */
setenv(VAULT_ADDR, null, VAULT_MAX_RETRIES.toString(), null); withVaultEnv(VAULT_ADDR, null, VAULT_MAX_RETRIES.toString(), null).execute(() -> {
HTTPVaultConnectorFactory factory = assertDoesNotThrow(
() -> VaultConnectorFactory.httpFactory().fromEnv(),
"Factory creation from environment failed"
);
HTTPVaultConnector connector = factory.build();
try { assertThat("URL nor set correctly", getRequestHelperPrivate(connector, "baseURL"), is(equalTo(VAULT_ADDR + "/v1/")));
factory = VaultConnectorFactory.httpFactory().fromEnv(); assertThat("Trusted CA cert set when no cert provided", getRequestHelperPrivate(connector, "trustedCaCert"), is(nullValue()));
} catch (VaultConnectorException e) { assertThat("Number of retries not set correctly", getRequestHelperPrivate(connector, "retries"), is(VAULT_MAX_RETRIES));
fail("Factory creation from environment failed");
}
connector = factory.build();
assertThat("URL nor set correctly", getRequestHelperPrivate(connector, "baseURL"), is(equalTo(VAULT_ADDR + "/v1/"))); return null;
assertThat("Trusted CA cert set when no cert provided", getRequestHelperPrivate(connector, "trustedCaCert"), is(nullValue())); });
assertThat("Number of retries not set correctly", getRequestHelperPrivate(connector, "retries"), is(VAULT_MAX_RETRIES));
/* Provide CA certificate */ /* Provide CA certificate */
String VAULT_CACERT = tempDir.toString() + "/doesnotexist"; String VAULT_CACERT = tempDir.toString() + "/doesnotexist";
setenv(VAULT_ADDR, VAULT_CACERT, VAULT_MAX_RETRIES.toString(), null); withVaultEnv(VAULT_ADDR, VAULT_CACERT, VAULT_MAX_RETRIES.toString(), null).execute(() -> {
TlsException e = assertThrows(
try { TlsException.class,
VaultConnectorFactory.httpFactory().fromEnv(); () -> VaultConnectorFactory.httpFactory().fromEnv(),
fail("Creation with unknown cert path failed."); "Creation with unknown cert path failed."
} catch (VaultConnectorException e) { );
assertThat(e, is(instanceOf(TlsException.class)));
assertThat(e.getCause(), is(instanceOf(NoSuchFileException.class))); assertThat(e.getCause(), is(instanceOf(NoSuchFileException.class)));
assertThat(((NoSuchFileException) e.getCause()).getFile(), is(VAULT_CACERT)); assertThat(((NoSuchFileException) e.getCause()).getFile(), is(VAULT_CACERT));
}
return null;
});
/* Automatic authentication */ /* Automatic authentication */
setenv(VAULT_ADDR, null, VAULT_MAX_RETRIES.toString(), VAULT_TOKEN); withVaultEnv(VAULT_ADDR, null, VAULT_MAX_RETRIES.toString(), VAULT_TOKEN).execute(() -> {
HTTPVaultConnectorFactory factory = assertDoesNotThrow(
() -> VaultConnectorFactory.httpFactory().fromEnv(),
"Factory creation from minimal environment failed"
);
assertThat("Token nor set correctly", getPrivate(getPrivate(factory, "delegate"), "token"), is(equalTo(VAULT_TOKEN)));
try { return null;
factory = VaultConnectorFactory.httpFactory().fromEnv(); });
} catch (VaultConnectorException e) {
fail("Factory creation from minimal environment failed");
}
assertThat("Token nor set correctly", getPrivate(getPrivate(factory, "delegate"), "token"), is(equalTo(VAULT_TOKEN)));
} }
private void setenv(String vault_addr, String vault_cacert, String vault_max_retries, String vault_token) { private SystemLambda.WithEnvironmentVariables withVaultEnv(String vault_addr, String vault_cacert, String vault_max_retries, String vault_token) {
EnvironmentMock.setenv("VAULT_ADDR", vault_addr); return withEnvironmentVariable("VAULT_ADDR", vault_addr)
EnvironmentMock.setenv("VAULT_CACERT", vault_cacert); .and("VAULT_CACERT", vault_cacert)
EnvironmentMock.setenv("VAULT_MAX_RETRIES", vault_max_retries); .and("VAULT_MAX_RETRIES", vault_max_retries)
EnvironmentMock.setenv("VAULT_TOKEN", vault_token); .and("VAULT_TOKEN", vault_token);
} }
private Object getRequestHelperPrivate(HTTPVaultConnector connector, String fieldName) throws NoSuchFieldException, IllegalAccessException { private Object getRequestHelperPrivate(HTTPVaultConnector connector, String fieldName) throws NoSuchFieldException, IllegalAccessException {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -33,7 +33,7 @@ import static org.hamcrest.Matchers.*;
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.4.0 * @since 0.4.0
*/ */
public class AppRoleBuilderTest { class AppRoleBuilderTest {
private static final String NAME = "TestRole"; private static final String NAME = "TestRole";
private static final String ID = "test-id"; private static final String ID = "test-id";
private static final Boolean BIND_SECRET_ID = true; private static final Boolean BIND_SECRET_ID = true;
@ -58,7 +58,7 @@ public class AppRoleBuilderTest {
NAME, ID, BIND_SECRET_ID, CIDR_1, SECRET_ID_NUM_USES, SECRET_ID_TTL, ENABLE_LOCAL_SECRET_IDS, TOKEN_TTL, TOKEN_MAX_TTL, POLICY, CIDR_1, TOKEN_EXPLICIT_MAX_TTL, TOKEN_NO_DEFAULT_POLICY, TOKEN_NUM_USES, TOKEN_PERIOD, TOKEN_TYPE.value()); NAME, ID, BIND_SECRET_ID, CIDR_1, SECRET_ID_NUM_USES, SECRET_ID_TTL, ENABLE_LOCAL_SECRET_IDS, TOKEN_TTL, TOKEN_MAX_TTL, POLICY, CIDR_1, TOKEN_EXPLICIT_MAX_TTL, TOKEN_NO_DEFAULT_POLICY, TOKEN_NUM_USES, TOKEN_PERIOD, TOKEN_TYPE.value());
@BeforeAll @BeforeAll
public static void init() { static void init() {
BOUND_CIDR_LIST.add(CIDR_1); BOUND_CIDR_LIST.add(CIDR_1);
POLICIES.add(POLICY); POLICIES.add(POLICY);
} }
@ -67,7 +67,7 @@ public class AppRoleBuilderTest {
* Build role with only a name. * Build role with only a name.
*/ */
@Test @Test
public void buildDefaultTest() throws JsonProcessingException { void buildDefaultTest() throws JsonProcessingException {
AppRole role = AppRole.builder(NAME).build(); AppRole role = AppRole.builder(NAME).build();
assertThat(role.getId(), is(nullValue())); assertThat(role.getId(), is(nullValue()));
assertThat(role.getBindSecretId(), is(nullValue())); assertThat(role.getBindSecretId(), is(nullValue()));
@ -95,7 +95,7 @@ public class AppRoleBuilderTest {
* Build role with only a name. * Build role with only a name.
*/ */
@Test @Test
public void legacyBuildDefaultTest() throws JsonProcessingException { void legacyBuildDefaultTest() throws JsonProcessingException {
AppRole role = new AppRoleBuilder(NAME).build(); AppRole role = new AppRoleBuilder(NAME).build();
assertThat(role.getId(), is(nullValue())); assertThat(role.getId(), is(nullValue()));
assertThat(role.getBindSecretId(), is(nullValue())); assertThat(role.getBindSecretId(), is(nullValue()));
@ -123,7 +123,7 @@ public class AppRoleBuilderTest {
* Build token without all parameters set. * Build token without all parameters set.
*/ */
@Test @Test
public void buildFullTest() throws JsonProcessingException { void buildFullTest() throws JsonProcessingException {
AppRole role = AppRole.builder(NAME) AppRole role = AppRole.builder(NAME)
.withId(ID) .withId(ID)
.withBindSecretID(BIND_SECRET_ID) .withBindSecretID(BIND_SECRET_ID)
@ -138,7 +138,7 @@ public class AppRoleBuilderTest {
.withTokenExplicitMaxTtl(TOKEN_EXPLICIT_MAX_TTL) .withTokenExplicitMaxTtl(TOKEN_EXPLICIT_MAX_TTL)
.withTokenNoDefaultPolicy(TOKEN_NO_DEFAULT_POLICY) .withTokenNoDefaultPolicy(TOKEN_NO_DEFAULT_POLICY)
.withTokenNumUses(TOKEN_NUM_USES) .withTokenNumUses(TOKEN_NUM_USES)
.wit0hTokenPeriod(TOKEN_PERIOD) .withTokenPeriod(TOKEN_PERIOD)
.withTokenType(TOKEN_TYPE) .withTokenType(TOKEN_TYPE)
.build(); .build();
assertThat(role.getName(), is(NAME)); assertThat(role.getName(), is(NAME));
@ -168,7 +168,7 @@ public class AppRoleBuilderTest {
* Build token without all parameters set. * Build token without all parameters set.
*/ */
@Test @Test
public void legacyBuildFullTest() throws JsonProcessingException { void legacyBuildFullTest() throws JsonProcessingException {
AppRole role = new AppRoleBuilder(NAME) AppRole role = new AppRoleBuilder(NAME)
.withId(ID) .withId(ID)
.withBindSecretID(BIND_SECRET_ID) .withBindSecretID(BIND_SECRET_ID)
@ -183,7 +183,7 @@ public class AppRoleBuilderTest {
.withTokenExplicitMaxTtl(TOKEN_EXPLICIT_MAX_TTL) .withTokenExplicitMaxTtl(TOKEN_EXPLICIT_MAX_TTL)
.withTokenNoDefaultPolicy(TOKEN_NO_DEFAULT_POLICY) .withTokenNoDefaultPolicy(TOKEN_NO_DEFAULT_POLICY)
.withTokenNumUses(TOKEN_NUM_USES) .withTokenNumUses(TOKEN_NUM_USES)
.wit0hTokenPeriod(TOKEN_PERIOD) .withTokenPeriod(TOKEN_PERIOD)
.withTokenType(TOKEN_TYPE) .withTokenType(TOKEN_TYPE)
.build(); .build();
assertThat(role.getName(), is(NAME)); assertThat(role.getName(), is(NAME));
@ -213,7 +213,7 @@ public class AppRoleBuilderTest {
* Test convenience methods * Test convenience methods
*/ */
@Test @Test
public void convenienceMethodsTest() { void convenienceMethodsTest() {
/* bind_secret_id */ /* bind_secret_id */
AppRole role = AppRole.builder(NAME).build(); AppRole role = AppRole.builder(NAME).build();
assertThat(role.getBindSecretId(), is(nullValue())); assertThat(role.getBindSecretId(), is(nullValue()));
@ -257,7 +257,7 @@ public class AppRoleBuilderTest {
* Test convenience methods * Test convenience methods
*/ */
@Test @Test
public void legacyConvenienceMethodsTest() { void legacyConvenienceMethodsTest() {
/* bind_secret_id */ /* bind_secret_id */
AppRole role = new AppRoleBuilder(NAME).build(); AppRole role = new AppRoleBuilder(NAME).build();
assertThat(role.getBindSecretId(), is(nullValue())); assertThat(role.getBindSecretId(), is(nullValue()));

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,11 +16,9 @@
package de.stklcode.jvault.connector.model; package de.stklcode.jvault.connector.model;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
@ -29,7 +27,7 @@ import java.util.Map;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*; import static org.hamcrest.Matchers.*;
import static org.junit.jupiter.api.Assertions.fail; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assumptions.assumeTrue; import static org.junit.jupiter.api.Assumptions.assumeTrue;
@ -39,7 +37,7 @@ import static org.junit.jupiter.api.Assumptions.assumeTrue;
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.5.0 * @since 0.5.0
*/ */
public class AppRoleSecretTest { class AppRoleSecretTest {
private static final String TEST_ID = "abc123"; private static final String TEST_ID = "abc123";
private static final Map<String, Object> TEST_META = new HashMap<>(); private static final Map<String, Object> TEST_META = new HashMap<>();
@ -54,7 +52,7 @@ public class AppRoleSecretTest {
* Test constructors. * Test constructors.
*/ */
@Test @Test
public void constructorTest() { void constructorTest() {
/* Empty constructor */ /* Empty constructor */
AppRoleSecret secret = new AppRoleSecret(); AppRoleSecret secret = new AppRoleSecret();
assertThat(secret.getId(), is(nullValue())); assertThat(secret.getId(), is(nullValue()));
@ -99,7 +97,7 @@ public class AppRoleSecretTest {
* Test setter. * Test setter.
*/ */
@Test @Test
public void setterTest() { void setterTest() {
AppRoleSecret secret = new AppRoleSecret(TEST_ID); AppRoleSecret secret = new AppRoleSecret(TEST_ID);
assertThat(secret.getCidrList(), is(nullValue())); assertThat(secret.getCidrList(), is(nullValue()));
assertThat(secret.getCidrListString(), is(emptyString())); assertThat(secret.getCidrListString(), is(emptyString()));
@ -115,31 +113,22 @@ public class AppRoleSecretTest {
* Test JSON (de)serialization. * Test JSON (de)serialization.
*/ */
@Test @Test
public void jsonTest() throws NoSuchFieldException, IllegalAccessException { void jsonTest() throws NoSuchFieldException, IllegalAccessException {
ObjectMapper mapper = new ObjectMapper(); ObjectMapper mapper = new ObjectMapper();
/* A simple roundtrip first. All set fields should be present afterwards. */ /* A simple roundtrip first. All set fields should be present afterwards. */
AppRoleSecret secret = new AppRoleSecret(TEST_ID, TEST_META, TEST_CIDR); AppRoleSecret secret = new AppRoleSecret(TEST_ID, TEST_META, TEST_CIDR);
String secretJson = ""; String secretJson = assertDoesNotThrow(() -> mapper.writeValueAsString(secret), "Serialization failed");
try {
secretJson = mapper.writeValueAsString(secret);
} catch (JsonProcessingException e) {
e.printStackTrace();
fail("Serialization failed");
}
/* CIDR list is comma-separated when used as input, but List otherwise, hence convert string to list */ /* CIDR list is comma-separated when used as input, but List otherwise, hence convert string to list */
secretJson = commaSeparatedToList(secretJson); String secretJson2 = commaSeparatedToList(secretJson);
AppRoleSecret secret2; AppRoleSecret secret2 = assertDoesNotThrow(
try { () -> mapper.readValue(secretJson2, AppRoleSecret.class),
secret2 = mapper.readValue(secretJson, AppRoleSecret.class); "Deserialization failed"
assertThat(secret.getId(), is(secret2.getId())); );
assertThat(secret.getMetadata(), is(secret2.getMetadata())); assertThat(secret.getId(), is(secret2.getId()));
assertThat(secret.getCidrList(), is(secret2.getCidrList())); assertThat(secret.getMetadata(), is(secret2.getMetadata()));
} catch (IOException e) { assertThat(secret.getCidrList(), is(secret2.getCidrList()));
e.printStackTrace();
fail("Deserialization failed");
}
/* Test fields, that should not be written to JSON */ /* Test fields, that should not be written to JSON */
setPrivateField(secret, "accessor", "TEST_ACCESSOR"); setPrivateField(secret, "accessor", "TEST_ACCESSOR");
@ -154,45 +143,33 @@ public class AppRoleSecretTest {
assumeTrue(secret.getNumUses() == 678); assumeTrue(secret.getNumUses() == 678);
setPrivateField(secret, "ttl", 12345); setPrivateField(secret, "ttl", 12345);
assumeTrue(secret.getTtl() == 12345); assumeTrue(secret.getTtl() == 12345);
try { String secretJson3 = assertDoesNotThrow(() -> mapper.writeValueAsString(secret), "Serialization failed");
secretJson = mapper.writeValueAsString(secret); secret2 = assertDoesNotThrow(
} catch (JsonProcessingException e) { () -> mapper.readValue(commaSeparatedToList(secretJson3), AppRoleSecret.class),
e.printStackTrace(); "Deserialization failed"
fail("Serialization failed"); );
} assertThat(secret.getId(), is(secret2.getId()));
try { assertThat(secret.getMetadata(), is(secret2.getMetadata()));
secret2 = mapper.readValue(commaSeparatedToList(secretJson), AppRoleSecret.class); assertThat(secret.getCidrList(), is(secret2.getCidrList()));
assertThat(secret.getId(), is(secret2.getId())); assertThat(secret2.getAccessor(), is(nullValue()));
assertThat(secret.getMetadata(), is(secret2.getMetadata())); assertThat(secret2.getCreationTime(), is(nullValue()));
assertThat(secret.getCidrList(), is(secret2.getCidrList())); assertThat(secret2.getExpirationTime(), is(nullValue()));
assertThat(secret2.getAccessor(), is(nullValue())); assertThat(secret2.getLastUpdatedTime(), is(nullValue()));
assertThat(secret2.getCreationTime(), is(nullValue())); assertThat(secret2.getNumUses(), is(nullValue()));
assertThat(secret2.getExpirationTime(), is(nullValue())); assertThat(secret2.getTtl(), is(nullValue()));
assertThat(secret2.getLastUpdatedTime(), is(nullValue()));
assertThat(secret2.getNumUses(), is(nullValue()));
assertThat(secret2.getTtl(), is(nullValue()));
} catch (IOException e) {
e.printStackTrace();
fail("Deserialization failed");
}
/* Those fields should be deserialized from JSON though */ /* Those fields should be deserialized from JSON though */
secretJson = "{\"secret_id\":\"abc123\",\"metadata\":{\"number\":1337,\"foo\":\"bar\"}," + String secretJson4 = "{\"secret_id\":\"abc123\",\"metadata\":{\"number\":1337,\"foo\":\"bar\"}," +
"\"cidr_list\":[\"203.0.113.0/24\",\"198.51.100.0/24\"],\"secret_id_accessor\":\"TEST_ACCESSOR\"," + "\"cidr_list\":[\"203.0.113.0/24\",\"198.51.100.0/24\"],\"secret_id_accessor\":\"TEST_ACCESSOR\"," +
"\"creation_time\":\"TEST_CREATION\",\"expiration_time\":\"TEST_EXPIRATION\"," + "\"creation_time\":\"TEST_CREATION\",\"expiration_time\":\"TEST_EXPIRATION\"," +
"\"last_updated_time\":\"TEST_LASTUPDATE\",\"secret_id_num_uses\":678,\"secret_id_ttl\":12345}"; "\"last_updated_time\":\"TEST_LASTUPDATE\",\"secret_id_num_uses\":678,\"secret_id_ttl\":12345}";
try { secret2 = assertDoesNotThrow(() -> mapper.readValue(secretJson4, AppRoleSecret.class), "Deserialization failed");
secret2 = mapper.readValue(secretJson, AppRoleSecret.class); assertThat(secret2.getAccessor(), is("TEST_ACCESSOR"));
assertThat(secret2.getAccessor(), is("TEST_ACCESSOR")); assertThat(secret2.getCreationTime(), is("TEST_CREATION"));
assertThat(secret2.getCreationTime(), is("TEST_CREATION")); assertThat(secret2.getExpirationTime(), is("TEST_EXPIRATION"));
assertThat(secret2.getExpirationTime(), is("TEST_EXPIRATION")); assertThat(secret2.getLastUpdatedTime(), is("TEST_LASTUPDATE"));
assertThat(secret2.getLastUpdatedTime(), is("TEST_LASTUPDATE")); assertThat(secret2.getNumUses(), is(678));
assertThat(secret2.getNumUses(), is(678)); assertThat(secret2.getTtl(), is(12345));
assertThat(secret2.getTtl(), is(12345));
} catch (IOException e) {
e.printStackTrace();
fail("Deserialization failed");
}
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -27,13 +27,13 @@ import static org.hamcrest.Matchers.is;
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.4.0 * @since 0.4.0
*/ */
public class AuthBackendTest { class AuthBackendTest {
/** /**
* Test forType() method. * Test forType() method.
*/ */
@Test @Test
public void forTypeTest() { void forTypeTest() {
assertThat(AuthBackend.forType("token"), is(AuthBackend.TOKEN)); assertThat(AuthBackend.forType("token"), is(AuthBackend.TOKEN));
assertThat(AuthBackend.forType("app-id"), is(AuthBackend.APPID)); assertThat(AuthBackend.forType("app-id"), is(AuthBackend.APPID));
assertThat(AuthBackend.forType("userpass"), is(AuthBackend.USERPASS)); assertThat(AuthBackend.forType("userpass"), is(AuthBackend.USERPASS));

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -35,7 +35,7 @@ import static org.hamcrest.Matchers.*;
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.4.0 * @since 0.4.0
*/ */
public class TokenBuilderTest { class TokenBuilderTest {
private static final String ID = "test-id"; private static final String ID = "test-id";
private static final String DISPLAY_NAME = "display-name"; private static final String DISPLAY_NAME = "display-name";
private static final Boolean NO_PARENT = false; private static final Boolean NO_PARENT = false;
@ -59,7 +59,7 @@ public class TokenBuilderTest {
private static final String JSON_FULL = "{\"id\":\"test-id\",\"type\":\"service\",\"display_name\":\"display-name\",\"no_parent\":false,\"no_default_policy\":false,\"ttl\":123,\"explicit_max_ttl\":456,\"num_uses\":4,\"policies\":[\"policy\"],\"meta\":{\"key\":\"value\"},\"renewable\":true,\"period\":3600,\"entity_alias\":\"alias-value\"}"; private static final String JSON_FULL = "{\"id\":\"test-id\",\"type\":\"service\",\"display_name\":\"display-name\",\"no_parent\":false,\"no_default_policy\":false,\"ttl\":123,\"explicit_max_ttl\":456,\"num_uses\":4,\"policies\":[\"policy\"],\"meta\":{\"key\":\"value\"},\"renewable\":true,\"period\":3600,\"entity_alias\":\"alias-value\"}";
@BeforeAll @BeforeAll
public static void init() { static void init() {
POLICIES.add(POLICY); POLICIES.add(POLICY);
META.put(META_KEY, META_VALUE); META.put(META_KEY, META_VALUE);
} }
@ -68,7 +68,7 @@ public class TokenBuilderTest {
* Build token without any parameters. * Build token without any parameters.
*/ */
@Test @Test
public void buildDefaultTest() throws JsonProcessingException { void buildDefaultTest() throws JsonProcessingException {
Token token = Token.builder().build(); Token token = Token.builder().build();
assertThat(token.getId(), is(nullValue())); assertThat(token.getId(), is(nullValue()));
assertThat(token.getType(), is(nullValue())); assertThat(token.getType(), is(nullValue()));
@ -92,7 +92,7 @@ public class TokenBuilderTest {
* Build token without any parameters. * Build token without any parameters.
*/ */
@Test @Test
public void legacyBuildDefaultTest() throws JsonProcessingException { void legacyBuildDefaultTest() throws JsonProcessingException {
Token token = new TokenBuilder().build(); Token token = new TokenBuilder().build();
assertThat(token.getId(), is(nullValue())); assertThat(token.getId(), is(nullValue()));
assertThat(token.getType(), is(nullValue())); assertThat(token.getType(), is(nullValue()));
@ -113,7 +113,7 @@ public class TokenBuilderTest {
* Build token without all parameters set. * Build token without all parameters set.
*/ */
@Test @Test
public void buildFullTest() throws JsonProcessingException { void buildFullTest() throws JsonProcessingException {
Token token = Token.builder() Token token = Token.builder()
.withId(ID) .withId(ID)
.withType(Token.Type.SERVICE) .withType(Token.Type.SERVICE)
@ -150,7 +150,7 @@ public class TokenBuilderTest {
* Build token without all parameters set. * Build token without all parameters set.
*/ */
@Test @Test
public void legacyBuildFullTest() throws JsonProcessingException { void legacyBuildFullTest() throws JsonProcessingException {
Token token = new TokenBuilder() Token token = new TokenBuilder()
.withId(ID) .withId(ID)
.withType(Token.Type.SERVICE) .withType(Token.Type.SERVICE)
@ -182,7 +182,7 @@ public class TokenBuilderTest {
* Test convenience methods * Test convenience methods
*/ */
@Test @Test
public void convenienceMethodsTest() { void convenienceMethodsTest() {
/* Parent */ /* Parent */
Token token = Token.builder().asOrphan().build(); Token token = Token.builder().asOrphan().build();
assertThat(token.getNoParent(), is(true)); assertThat(token.getNoParent(), is(true));
@ -230,7 +230,7 @@ public class TokenBuilderTest {
* Test convenience methods * Test convenience methods
*/ */
@Test @Test
public void legacyConvenienceMethodsTest() { void legacyConvenienceMethodsTest() {
/* Parent */ /* Parent */
Token token = new TokenBuilder().asOrphan().build(); Token token = new TokenBuilder().asOrphan().build();
assertThat(token.getNoParent(), is(true)); assertThat(token.getNoParent(), is(true));

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -32,7 +32,7 @@ import static org.hamcrest.Matchers.*;
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.9 * @since 0.9
*/ */
public class TokenRoleBuilderTest { class TokenRoleBuilderTest {
private static final String NAME = "test-role"; private static final String NAME = "test-role";
private static final String ALLOWED_POLICY_1 = "apol-1"; private static final String ALLOWED_POLICY_1 = "apol-1";
private static final String ALLOWED_POLICY_2 = "apol-2"; private static final String ALLOWED_POLICY_2 = "apol-2";
@ -78,7 +78,7 @@ public class TokenRoleBuilderTest {
* Build token without any parameters. * Build token without any parameters.
*/ */
@Test @Test
public void buildDefaultTest() throws JsonProcessingException { void buildDefaultTest() throws JsonProcessingException {
TokenRole role = TokenRole.builder().build(); TokenRole role = TokenRole.builder().build();
assertThat(role.getAllowedPolicies(), is(nullValue())); assertThat(role.getAllowedPolicies(), is(nullValue()));
assertThat(role.getDisallowedPolicies(), is(nullValue())); assertThat(role.getDisallowedPolicies(), is(nullValue()));
@ -100,7 +100,7 @@ public class TokenRoleBuilderTest {
* Build token without all parameters NULL. * Build token without all parameters NULL.
*/ */
@Test @Test
public void buildNullTest() throws JsonProcessingException { void buildNullTest() throws JsonProcessingException {
TokenRole role = TokenRole.builder() TokenRole role = TokenRole.builder()
.forName(null) .forName(null)
.withAllowedPolicies(null) .withAllowedPolicies(null)
@ -141,7 +141,7 @@ public class TokenRoleBuilderTest {
* Build token without all parameters set. * Build token without all parameters set.
*/ */
@Test @Test
public void buildFullTest() throws JsonProcessingException { void buildFullTest() throws JsonProcessingException {
TokenRole role = TokenRole.builder() TokenRole role = TokenRole.builder()
.forName(NAME) .forName(NAME)
.withAllowedPolicies(ALLOWED_POLICIES) .withAllowedPolicies(ALLOWED_POLICIES)

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -21,13 +21,13 @@ import de.stklcode.jvault.connector.exception.InvalidResponseException;
import de.stklcode.jvault.connector.model.AppRole; import de.stklcode.jvault.connector.model.AppRole;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*; import static org.hamcrest.Matchers.*;
import static org.junit.jupiter.api.Assertions.fail; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertThrows;
/** /**
* JUnit Test for {@link AppRoleResponse} model. * JUnit Test for {@link AppRoleResponse} model.
@ -35,7 +35,7 @@ import static org.junit.jupiter.api.Assertions.fail;
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.6.2 * @since 0.6.2
*/ */
public class AppRoleResponseTest { class AppRoleResponseTest {
private static final Integer ROLE_TOKEN_TTL = 1200; private static final Integer ROLE_TOKEN_TTL = 1200;
private static final Integer ROLE_TOKEN_MAX_TTL = 1800; private static final Integer ROLE_TOKEN_MAX_TTL = 1800;
private static final Integer ROLE_SECRET_TTL = 600; private static final Integer ROLE_SECRET_TTL = 600;
@ -75,46 +75,44 @@ public class AppRoleResponseTest {
* Test getter, setter and get-methods for response data. * Test getter, setter and get-methods for response data.
*/ */
@Test @Test
public void getDataRoundtrip() { void getDataRoundtrip() {
// Create empty Object. // Create empty Object.
AppRoleResponse res = new AppRoleResponse(); AppRoleResponse res = new AppRoleResponse();
assertThat("Initial data should be empty", res.getRole(), is(nullValue())); assertThat("Initial data should be empty", res.getRole(), is(nullValue()));
// Parsing invalid auth data map should fail. // Parsing invalid auth data map should fail.
try { assertThrows(
res.setData(INVALID_DATA); InvalidResponseException.class,
fail("Parsing invalid data succeeded"); () -> res.setData(INVALID_DATA),
} catch (Exception e) { "Parsing invalid data succeeded"
assertThat(e, is(instanceOf(InvalidResponseException.class))); );
}
} }
/** /**
* Test creation from JSON value as returned by Vault (JSON example copied from Vault documentation). * Test creation from JSON value as returned by Vault (JSON example copied from Vault documentation).
*/ */
@Test @Test
public void jsonRoundtrip() { void jsonRoundtrip() {
try { AppRoleResponse res = assertDoesNotThrow(
AppRoleResponse res = new ObjectMapper().readValue(RES_JSON, AppRoleResponse.class); () -> new ObjectMapper().readValue(RES_JSON, AppRoleResponse.class),
assertThat("Parsed response is NULL", res, is(notNullValue())); "AuthResponse deserialization failed."
// Extract role data. );
AppRole role = res.getRole(); assertThat("Parsed response is NULL", res, is(notNullValue()));
assertThat("Role data is NULL", role, is(notNullValue())); // Extract role data.
assertThat("Incorrect token TTL", role.getTokenTtl(), is(ROLE_TOKEN_TTL)); AppRole role = res.getRole();
assertThat("Incorrect token max TTL", role.getTokenMaxTtl(), is(ROLE_TOKEN_MAX_TTL)); assertThat("Role data is NULL", role, is(notNullValue()));
assertThat("Incorrect secret ID TTL", role.getSecretIdTtl(), is(ROLE_SECRET_TTL)); assertThat("Incorrect token TTL", role.getTokenTtl(), is(ROLE_TOKEN_TTL));
assertThat("Incorrect secret ID umber of uses", role.getSecretIdNumUses(), is(ROLE_SECRET_NUM_USES)); assertThat("Incorrect token max TTL", role.getTokenMaxTtl(), is(ROLE_TOKEN_MAX_TTL));
assertThat("Incorrect number of policies", role.getTokenPolicies(), hasSize(1)); assertThat("Incorrect secret ID TTL", role.getSecretIdTtl(), is(ROLE_SECRET_TTL));
assertThat("Incorrect role policies", role.getTokenPolicies(), contains(ROLE_POLICY)); assertThat("Incorrect secret ID umber of uses", role.getSecretIdNumUses(), is(ROLE_SECRET_NUM_USES));
assertThat("Incorrect number of policies", role.getPolicies(), hasSize(1)); assertThat("Incorrect number of policies", role.getTokenPolicies(), hasSize(1));
assertThat("Incorrect role policies", role.getPolicies(), contains(ROLE_POLICY)); assertThat("Incorrect role policies", role.getTokenPolicies(), contains(ROLE_POLICY));
assertThat("Incorrect role period", role.getTokenPeriod(), is(ROLE_PERIOD)); assertThat("Incorrect number of policies", role.getPolicies(), hasSize(1));
assertThat("Incorrect role period", role.getPeriod(), is(ROLE_PERIOD)); assertThat("Incorrect role policies", role.getPolicies(), contains(ROLE_POLICY));
assertThat("Incorrect role bind secret ID flag", role.getBindSecretId(), is(ROLE_BIND_SECRET)); assertThat("Incorrect role period", role.getTokenPeriod(), is(ROLE_PERIOD));
assertThat("Incorrect bound CIDR list", role.getTokenBoundCidrs(), is(nullValue())); assertThat("Incorrect role period", role.getPeriod(), is(ROLE_PERIOD));
assertThat("Incorrect bound CIDR list string", role.getTokenBoundCidrsString(), is(emptyString())); assertThat("Incorrect role bind secret ID flag", role.getBindSecretId(), is(ROLE_BIND_SECRET));
} catch (IOException e) { assertThat("Incorrect bound CIDR list", role.getTokenBoundCidrs(), is(nullValue()));
fail("AuthResponse deserialization failed: " + e.getMessage()); assertThat("Incorrect bound CIDR list string", role.getTokenBoundCidrsString(), is(emptyString()));
}
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -22,13 +22,13 @@ import de.stklcode.jvault.connector.model.AuthBackend;
import de.stklcode.jvault.connector.model.response.embedded.AuthMethod; import de.stklcode.jvault.connector.model.response.embedded.AuthMethod;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*; import static org.hamcrest.Matchers.*;
import static org.junit.jupiter.api.Assertions.fail; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertThrows;
/** /**
* JUnit Test for {@link AuthMethodsResponse} model. * JUnit Test for {@link AuthMethodsResponse} model.
@ -36,7 +36,7 @@ import static org.junit.jupiter.api.Assertions.fail;
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.6.2 * @since 0.6.2
*/ */
public class AuthMethodsResponseTest { class AuthMethodsResponseTest {
private static final String GH_PATH = "github/"; private static final String GH_PATH = "github/";
private static final String GH_TYPE = "github"; private static final String GH_TYPE = "github";
private static final String GH_DESCR = "GitHub auth"; private static final String GH_DESCR = "GitHub auth";
@ -73,53 +73,51 @@ public class AuthMethodsResponseTest {
* Test getter, setter and get-methods for response data. * Test getter, setter and get-methods for response data.
*/ */
@Test @Test
public void getDataRoundtrip() { void getDataRoundtrip() {
// Create empty Object. // Create empty Object.
AuthMethodsResponse res = new AuthMethodsResponse(); AuthMethodsResponse res = new AuthMethodsResponse();
assertThat("Initial method map should be empty", res.getSupportedMethods(), is(anEmptyMap())); assertThat("Initial method map should be empty", res.getSupportedMethods(), is(anEmptyMap()));
// Parsing invalid data map should fail. // Parsing invalid data map should fail.
try { assertThrows(
res.setData(INVALID_DATA); InvalidResponseException.class,
fail("Parsing invalid data succeeded"); () -> res.setData(INVALID_DATA),
} catch (Exception e) { "Parsing invalid data succeeded"
assertThat(e, is(instanceOf(InvalidResponseException.class))); );
}
} }
/** /**
* Test creation from JSON value as returned by Vault (JSON example copied from Vault documentation). * Test creation from JSON value as returned by Vault (JSON example copied from Vault documentation).
*/ */
@Test @Test
public void jsonRoundtrip() { void jsonRoundtrip() {
try { AuthMethodsResponse res = assertDoesNotThrow(
AuthMethodsResponse res = new ObjectMapper().readValue(RES_JSON, AuthMethodsResponse.class); () -> new ObjectMapper().readValue(RES_JSON, AuthMethodsResponse.class),
assertThat("Parsed response is NULL", res, is(notNullValue())); "AuthResponse deserialization failed"
// Extract auth data. );
Map<String, AuthMethod> supported = res.getSupportedMethods(); assertThat("Parsed response is NULL", res, is(notNullValue()));
assertThat("Auth data is NULL", supported, is(notNullValue())); // Extract auth data.
assertThat("Incorrect number of supported methods", supported.entrySet(), hasSize(2)); Map<String, AuthMethod> supported = res.getSupportedMethods();
assertThat("Incorrect method paths", supported.keySet(), containsInAnyOrder(GH_PATH, TK_PATH)); assertThat("Auth data is NULL", supported, is(notNullValue()));
assertThat("Incorrect number of supported methods", supported.entrySet(), hasSize(2));
assertThat("Incorrect method paths", supported.keySet(), containsInAnyOrder(GH_PATH, TK_PATH));
// Verify first method. // Verify first method.
AuthMethod method = supported.get(GH_PATH); AuthMethod method = supported.get(GH_PATH);
assertThat("Incorrect raw type for GitHub", method.getRawType(), is(GH_TYPE)); assertThat("Incorrect raw type for GitHub", method.getRawType(), is(GH_TYPE));
assertThat("Incorrect parsed type for GitHub", method.getType(), is(AuthBackend.GITHUB)); assertThat("Incorrect parsed type for GitHub", method.getType(), is(AuthBackend.GITHUB));
assertThat("Incorrect description for GitHub", method.getDescription(), is(GH_DESCR)); assertThat("Incorrect description for GitHub", method.getDescription(), is(GH_DESCR));
assertThat("Unexpected config for GitHub", method.getConfig(), is(nullValue())); assertThat("Unexpected config for GitHub", method.getConfig(), is(nullValue()));
// Verify first method. // Verify first method.
method = supported.get(TK_PATH); method = supported.get(TK_PATH);
assertThat("Incorrect raw type for Token", method.getRawType(), is(TK_TYPE)); assertThat("Incorrect raw type for Token", method.getRawType(), is(TK_TYPE));
assertThat("Incorrect parsed type for Token", method.getType(), is(AuthBackend.TOKEN)); assertThat("Incorrect parsed type for Token", method.getType(), is(AuthBackend.TOKEN));
assertThat("Incorrect description for Token", method.getDescription(), is(TK_DESCR)); assertThat("Incorrect description for Token", method.getDescription(), is(TK_DESCR));
assertThat("Missing config for Token", method.getConfig(), is(notNullValue())); assertThat("Missing config for Token", method.getConfig(), is(notNullValue()));
assertThat("Unexpected config size for Token", method.getConfig().keySet(), hasSize(2)); assertThat("Unexpected config size for Token", method.getConfig().keySet(), hasSize(2));
assertThat("Incorrect lease TTL config", method.getConfig().get("default_lease_ttl"), is(TK_LEASE_TTL.toString())); assertThat("Incorrect lease TTL config", method.getConfig().get("default_lease_ttl"), is(TK_LEASE_TTL.toString()));
assertThat("Incorrect max lease TTL config", method.getConfig().get("max_lease_ttl"), is(TK_MAX_LEASE_TTL.toString())); assertThat("Incorrect max lease TTL config", method.getConfig().get("max_lease_ttl"), is(TK_MAX_LEASE_TTL.toString()));
} catch (IOException e) {
fail("AuthResponse deserialization failed: " + e.getMessage());
}
} }
private static class Dummy { private static class Dummy {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -21,13 +21,13 @@ import de.stklcode.jvault.connector.exception.InvalidResponseException;
import de.stklcode.jvault.connector.model.response.embedded.AuthData; import de.stklcode.jvault.connector.model.response.embedded.AuthData;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*; import static org.hamcrest.Matchers.*;
import static org.junit.jupiter.api.Assertions.fail; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertThrows;
/** /**
* JUnit Test for {@link AuthResponse} model. * JUnit Test for {@link AuthResponse} model.
@ -35,7 +35,7 @@ import static org.junit.jupiter.api.Assertions.fail;
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.6.2 * @since 0.6.2
*/ */
public class AuthResponseTest { class AuthResponseTest {
private static final String AUTH_ACCESSOR = "2c84f488-2133-4ced-87b0-570f93a76830"; private static final String AUTH_ACCESSOR = "2c84f488-2133-4ced-87b0-570f93a76830";
private static final String AUTH_CLIENT_TOKEN = "ABCD"; private static final String AUTH_CLIENT_TOKEN = "ABCD";
private static final String AUTH_POLICY_1 = "web"; private static final String AUTH_POLICY_1 = "web";
@ -81,18 +81,17 @@ public class AuthResponseTest {
* Test getter, setter and get-methods for response data. * Test getter, setter and get-methods for response data.
*/ */
@Test @Test
public void getDataRoundtrip() { void getDataRoundtrip() {
// Create empty Object. // Create empty Object.
AuthResponse res = new AuthResponse(); AuthResponse res = new AuthResponse();
assertThat("Initial data should be empty", res.getData(), is(nullValue())); assertThat("Initial data should be empty", res.getData(), is(nullValue()));
// Parsing invalid auth data map should fail. // Parsing invalid auth data map should fail.
try { assertThrows(
res.setAuth(INVALID_AUTH_DATA); InvalidResponseException.class,
fail("Parsing invalid auth data succeeded"); () -> res.setAuth(INVALID_AUTH_DATA),
} catch (Exception e) { "Parsing invalid auth data succeeded"
assertThat(e, is(instanceOf(InvalidResponseException.class))); );
}
// Data method should be agnostic. // Data method should be agnostic.
res.setData(INVALID_AUTH_DATA); res.setData(INVALID_AUTH_DATA);
@ -103,9 +102,11 @@ public class AuthResponseTest {
* Test creation from JSON value as returned by Vault (JSON example copied from Vault documentation). * Test creation from JSON value as returned by Vault (JSON example copied from Vault documentation).
*/ */
@Test @Test
public void jsonRoundtrip() { void jsonRoundtrip() {
try { AuthResponse res = assertDoesNotThrow(
AuthResponse res = new ObjectMapper().readValue(RES_JSON, AuthResponse.class); () -> new ObjectMapper().readValue(RES_JSON, AuthResponse.class),
"AuthResponse deserialization failed."
);
assertThat("Parsed response is NULL", res, is(notNullValue())); assertThat("Parsed response is NULL", res, is(notNullValue()));
// Extract auth data. // Extract auth data.
AuthData data = res.getAuth(); AuthData data = res.getAuth();
@ -123,9 +124,5 @@ public class AuthResponseTest {
assertThat("Incorrect token policies", data.getTokenPolicies(), containsInRelativeOrder(AUTH_POLICY_2, AUTH_POLICY_1)); assertThat("Incorrect token policies", data.getTokenPolicies(), containsInRelativeOrder(AUTH_POLICY_2, AUTH_POLICY_1));
assertThat("Incorrect auth metadata size", data.getMetadata().entrySet(), hasSize(1)); assertThat("Incorrect auth metadata size", data.getMetadata().entrySet(), hasSize(1));
assertThat("Incorrect auth metadata", data.getMetadata().get(AUTH_META_KEY), is(AUTH_META_VALUE)); assertThat("Incorrect auth metadata", data.getMetadata().get(AUTH_META_KEY), is(AUTH_META_VALUE));
} catch (IOException e) {
fail("AuthResponse deserialization failed: " + e.getMessage());
}
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -35,7 +35,7 @@ import static org.junit.jupiter.api.Assertions.fail;
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.8 * @since 0.8
*/ */
public class CredentialsResponseTest { class CredentialsResponseTest {
private static final Map<String, Object> DATA = new HashMap<>(); private static final Map<String, Object> DATA = new HashMap<>();
private static final String VAL_USER = "testUserName"; private static final String VAL_USER = "testUserName";
private static final String VAL_PASS = "5up3r5ecr3tP455"; private static final String VAL_PASS = "5up3r5ecr3tP455";
@ -52,7 +52,7 @@ public class CredentialsResponseTest {
*/ */
@Test @Test
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void getCredentialsTest() throws InvalidResponseException { void getCredentialsTest() throws InvalidResponseException {
// Create empty Object. // Create empty Object.
CredentialsResponse res = new CredentialsResponse(); CredentialsResponse res = new CredentialsResponse();
assertThat("Username not present in data map should not return anything", res.getUsername(), is(nullValue())); assertThat("Username not present in data map should not return anything", res.getUsername(), is(nullValue()));

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -19,12 +19,10 @@ package de.stklcode.jvault.connector.model.response;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.io.IOException;
import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.notNullValue;
import static org.junit.jupiter.api.Assertions.fail; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/** /**
* JUnit Test for {@link AuthResponse} model. * JUnit Test for {@link AuthResponse} model.
@ -32,7 +30,7 @@ import static org.junit.jupiter.api.Assertions.fail;
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.7.0 * @since 0.7.0
*/ */
public class HealthResponseTest { class HealthResponseTest {
private static final String CLUSTER_ID = "c9abceea-4f46-4dab-a688-5ce55f89e228"; private static final String CLUSTER_ID = "c9abceea-4f46-4dab-a688-5ce55f89e228";
private static final String CLUSTER_NAME = "vault-cluster-5515c810"; private static final String CLUSTER_NAME = "vault-cluster-5515c810";
private static final String VERSION = "0.9.2"; private static final String VERSION = "0.9.2";
@ -56,26 +54,26 @@ public class HealthResponseTest {
" \"replication_dr_mode\": \"" + REPL_DR_MODE + "\",\n" + " \"replication_dr_mode\": \"" + REPL_DR_MODE + "\",\n" +
" \"performance_standby\": " + PERF_STANDBY + "\n" + " \"performance_standby\": " + PERF_STANDBY + "\n" +
"}"; "}";
/** /**
* Test creation from JSON value as returned by Vault (JSON example copied from Vault documentation). * Test creation from JSON value as returned by Vault (JSON example copied from Vault documentation).
*/ */
@Test @Test
public void jsonRoundtrip() { void jsonRoundtrip() {
try { HealthResponse res = assertDoesNotThrow(
HealthResponse res = new ObjectMapper().readValue(RES_JSON, HealthResponse.class); () -> new ObjectMapper().readValue(RES_JSON, HealthResponse.class),
assertThat("Parsed response is NULL", res, is(notNullValue())); "Health deserialization failed."
assertThat("Incorrect cluster ID", res.getClusterID(), is(CLUSTER_ID)); );
assertThat("Incorrect cluster name", res.getClusterName(), is(CLUSTER_NAME)); assertThat("Parsed response is NULL", res, is(notNullValue()));
assertThat("Incorrect version", res.getVersion(), is(VERSION)); assertThat("Incorrect cluster ID", res.getClusterID(), is(CLUSTER_ID));
assertThat("Incorrect server time", res.getServerTimeUTC(), is(SERVER_TIME_UTC)); assertThat("Incorrect cluster name", res.getClusterName(), is(CLUSTER_NAME));
assertThat("Incorrect standby state", res.isStandby(), is(STANDBY)); assertThat("Incorrect version", res.getVersion(), is(VERSION));
assertThat("Incorrect seal state", res.isSealed(), is(SEALED)); assertThat("Incorrect server time", res.getServerTimeUTC(), is(SERVER_TIME_UTC));
assertThat("Incorrect initialization state", res.isInitialized(), is(INITIALIZED)); assertThat("Incorrect standby state", res.isStandby(), is(STANDBY));
assertThat("Incorrect performance standby state", res.isPerformanceStandby(), is(PERF_STANDBY)); assertThat("Incorrect seal state", res.isSealed(), is(SEALED));
assertThat("Incorrect replication perf mode", res.getReplicationPerfMode(), is(REPL_PERF_MODE)); assertThat("Incorrect initialization state", res.isInitialized(), is(INITIALIZED));
assertThat("Incorrect replication DR mode", res.getReplicationDrMode(), is(REPL_DR_MODE)); assertThat("Incorrect performance standby state", res.isPerformanceStandby(), is(PERF_STANDBY));
} catch (IOException e) { assertThat("Incorrect replication perf mode", res.getReplicationPerfMode(), is(REPL_PERF_MODE));
fail("Health deserialization failed: " + e.getMessage()); assertThat("Incorrect replication DR mode", res.getReplicationDrMode(), is(REPL_DR_MODE));
}
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -17,16 +17,12 @@
package de.stklcode.jvault.connector.model.response; package de.stklcode.jvault.connector.model.response;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import de.stklcode.jvault.connector.exception.InvalidResponseException;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*; import static org.hamcrest.Matchers.is;
import static org.junit.jupiter.api.Assertions.fail; import static org.hamcrest.Matchers.notNullValue;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/** /**
* JUnit Test for {@link MetadataResponse} model. * JUnit Test for {@link MetadataResponse} model.
@ -34,7 +30,7 @@ import static org.junit.jupiter.api.Assertions.fail;
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.8 * @since 0.8
*/ */
public class MetadataResponseTest { class MetadataResponseTest {
private static final String V1_TIME = "2018-03-22T02:24:06.945319214Z"; private static final String V1_TIME = "2018-03-22T02:24:06.945319214Z";
private static final String V3_TIME = "2018-03-22T02:36:43.986212308Z"; private static final String V3_TIME = "2018-03-22T02:36:43.986212308Z";
private static final String V2_TIME = "2018-03-22T02:36:33.954880664Z"; private static final String V2_TIME = "2018-03-22T02:36:33.954880664Z";
@ -73,28 +69,26 @@ public class MetadataResponseTest {
* Test creation from JSON value as returned by Vault (JSON example copied from Vault documentation). * Test creation from JSON value as returned by Vault (JSON example copied from Vault documentation).
*/ */
@Test @Test
public void jsonRoundtrip() { void jsonRoundtrip() {
try { MetadataResponse res = assertDoesNotThrow(
MetadataResponse res = new ObjectMapper().readValue(META_JSON, MetadataResponse.class); () -> new ObjectMapper().readValue(META_JSON, MetadataResponse.class),
assertThat("Parsed response is NULL", res, is(notNullValue())); "MetadataResponse deserialization failed."
assertThat("Parsed metadata is NULL", res.getMetadata(), is(notNullValue())); );
assertThat("Incorrect created time", res.getMetadata().getCreatedTimeString(), is(V1_TIME)); assertThat("Parsed response is NULL", res, is(notNullValue()));
assertThat("Parting created time failed", res.getMetadata().getCreatedTime(), is(notNullValue())); assertThat("Parsed metadata is NULL", res.getMetadata(), is(notNullValue()));
assertThat("Incorrect current version", res.getMetadata().getCurrentVersion(), is(CURRENT_VERSION)); assertThat("Incorrect created time", res.getMetadata().getCreatedTimeString(), is(V1_TIME));
assertThat("Incorrect max versions", res.getMetadata().getMaxVersions(), is(MAX_VERSIONS)); assertThat("Parting created time failed", res.getMetadata().getCreatedTime(), is(notNullValue()));
assertThat("Incorrect oldest version", res.getMetadata().getOldestVersion(), is(OLDEST_VERSION)); assertThat("Incorrect current version", res.getMetadata().getCurrentVersion(), is(CURRENT_VERSION));
assertThat("Incorrect updated time", res.getMetadata().getUpdatedTimeString(), is(V3_TIME)); assertThat("Incorrect max versions", res.getMetadata().getMaxVersions(), is(MAX_VERSIONS));
assertThat("Parting updated time failed", res.getMetadata().getUpdatedTime(), is(notNullValue())); assertThat("Incorrect oldest version", res.getMetadata().getOldestVersion(), is(OLDEST_VERSION));
assertThat("Incorrect number of versions", res.getMetadata().getVersions().size(), is(3)); assertThat("Incorrect updated time", res.getMetadata().getUpdatedTimeString(), is(V3_TIME));
assertThat("Incorrect version 1 delete time", res.getMetadata().getVersions().get(1).getDeletionTimeString(), is(V2_TIME)); assertThat("Parting updated time failed", res.getMetadata().getUpdatedTime(), is(notNullValue()));
assertThat("Parsing version delete time failed", res.getMetadata().getVersions().get(1).getDeletionTime(), is(notNullValue())); assertThat("Incorrect number of versions", res.getMetadata().getVersions().size(), is(3));
assertThat("Incorrect version 1 destroyed state", res.getMetadata().getVersions().get(1).isDestroyed(), is(true)); assertThat("Incorrect version 1 delete time", res.getMetadata().getVersions().get(1).getDeletionTimeString(), is(V2_TIME));
assertThat("Incorrect version 2 created time", res.getMetadata().getVersions().get(2).getCreatedTimeString(), is(V2_TIME)); assertThat("Parsing version delete time failed", res.getMetadata().getVersions().get(1).getDeletionTime(), is(notNullValue()));
assertThat("Parsing version created failed", res.getMetadata().getVersions().get(2).getCreatedTime(), is(notNullValue())); assertThat("Incorrect version 1 destroyed state", res.getMetadata().getVersions().get(1).isDestroyed(), is(true));
assertThat("Incorrect version 3 destroyed state", res.getMetadata().getVersions().get(3).isDestroyed(), is(false)); assertThat("Incorrect version 2 created time", res.getMetadata().getVersions().get(2).getCreatedTimeString(), is(V2_TIME));
assertThat("Parsing version created failed", res.getMetadata().getVersions().get(2).getCreatedTime(), is(notNullValue()));
} catch (IOException e) { assertThat("Incorrect version 3 destroyed state", res.getMetadata().getVersions().get(3).isDestroyed(), is(false));
fail("MetadataResponse deserialization failed: " + e.getMessage());
}
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -19,11 +19,9 @@ package de.stklcode.jvault.connector.model.response;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.io.IOException;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*; import static org.hamcrest.Matchers.*;
import static org.junit.jupiter.api.Assertions.fail; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/** /**
* JUnit Test for {@link SealResponse} model. * JUnit Test for {@link SealResponse} model.
@ -31,7 +29,7 @@ import static org.junit.jupiter.api.Assertions.fail;
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.8 * @since 0.8
*/ */
public class SealResponseTest { class SealResponseTest {
private static final String TYPE = "shamir"; private static final String TYPE = "shamir";
private static final Integer THRESHOLD = 3; private static final Integer THRESHOLD = 3;
private static final Integer SHARES = 5; private static final Integer SHARES = 5;
@ -70,43 +68,41 @@ public class SealResponseTest {
* Test creation from JSON value as returned by Vault when sealed (JSON example close to Vault documentation). * Test creation from JSON value as returned by Vault when sealed (JSON example close to Vault documentation).
*/ */
@Test @Test
public void jsonRoundtripSealed() { void jsonRoundtripSealed() {
// First test sealed Vault's response. // First test sealed Vault's response.
try { SealResponse res = assertDoesNotThrow(
SealResponse res = new ObjectMapper().readValue(RES_SEALED, SealResponse.class); () -> new ObjectMapper().readValue(RES_SEALED, SealResponse.class),
assertThat("Parsed response is NULL", res, is(notNullValue())); "TokenResponse deserialization failed."
assertThat("Incorrect seal type", res.getType(), is(TYPE)); );
assertThat("Incorrect seal status", res.isSealed(), is(true)); assertThat("Parsed response is NULL", res, is(notNullValue()));
assertThat("Incorrect initialization status", res.isInitialized(), is(true)); assertThat("Incorrect seal type", res.getType(), is(TYPE));
assertThat("Incorrect threshold", res.getThreshold(), is(THRESHOLD)); assertThat("Incorrect seal status", res.isSealed(), is(true));
assertThat("Incorrect number of shares", res.getNumberOfShares(), is(SHARES)); assertThat("Incorrect initialization status", res.isInitialized(), is(true));
assertThat("Incorrect progress", res.getProgress(), is(PROGRESS_SEALED)); assertThat("Incorrect threshold", res.getThreshold(), is(THRESHOLD));
assertThat("Nonce not empty", res.getNonce(), is("")); assertThat("Incorrect number of shares", res.getNumberOfShares(), is(SHARES));
assertThat("Incorrect version", res.getVersion(), is(VERSION)); assertThat("Incorrect progress", res.getProgress(), is(PROGRESS_SEALED));
// And the fields, that should not be filled. assertThat("Nonce not empty", res.getNonce(), is(""));
assertThat("Cluster name should not be populated", res.getClusterName(), is(nullValue())); assertThat("Incorrect version", res.getVersion(), is(VERSION));
assertThat("Cluster ID should not be populated", res.getClusterId(), is(nullValue())); // And the fields, that should not be filled.
} catch (IOException e) { assertThat("Cluster name should not be populated", res.getClusterName(), is(nullValue()));
fail("TokenResponse deserialization failed: " + e.getMessage()); assertThat("Cluster ID should not be populated", res.getClusterId(), is(nullValue()));
}
// Not test unsealed Vault's response. // Not test unsealed Vault's response.
try { res = assertDoesNotThrow(
SealResponse res = new ObjectMapper().readValue(RES_UNSEALED, SealResponse.class); () -> new ObjectMapper().readValue(RES_UNSEALED, SealResponse.class),
assertThat("Parsed response is NULL", res, is(notNullValue())); "TokenResponse deserialization failed."
assertThat("Incorrect seal type", res.getType(), is(TYPE)); );
assertThat("Incorrect seal status", res.isSealed(), is(false)); assertThat("Parsed response is NULL", res, is(notNullValue()));
assertThat("Incorrect initialization status", res.isInitialized(), is(true)); assertThat("Incorrect seal type", res.getType(), is(TYPE));
assertThat("Incorrect threshold", res.getThreshold(), is(THRESHOLD)); assertThat("Incorrect seal status", res.isSealed(), is(false));
assertThat("Incorrect number of shares", res.getNumberOfShares(), is(SHARES)); assertThat("Incorrect initialization status", res.isInitialized(), is(true));
assertThat("Incorrect progress", res.getProgress(), is(PROGRESS_UNSEALED)); assertThat("Incorrect threshold", res.getThreshold(), is(THRESHOLD));
assertThat("Incorrect nonce", res.getNonce(), is(NONCE)); assertThat("Incorrect number of shares", res.getNumberOfShares(), is(SHARES));
assertThat("Incorrect version", res.getVersion(), is(VERSION)); assertThat("Incorrect progress", res.getProgress(), is(PROGRESS_UNSEALED));
assertThat("Incorrect cluster name", res.getClusterName(), is(CLUSTER_NAME)); assertThat("Incorrect nonce", res.getNonce(), is(NONCE));
assertThat("Incorrect cluster ID", res.getClusterId(), is(CLUSTER_ID)); assertThat("Incorrect version", res.getVersion(), is(VERSION));
} catch (IOException e) { assertThat("Incorrect cluster name", res.getClusterName(), is(CLUSTER_NAME));
fail("TokenResponse deserialization failed: " + e.getMessage()); assertThat("Incorrect cluster ID", res.getClusterId(), is(CLUSTER_ID));
}
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -26,7 +26,7 @@ import java.util.Map;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*; import static org.hamcrest.Matchers.*;
import static org.junit.jupiter.api.Assertions.fail; import static org.junit.jupiter.api.Assertions.assertThrows;
/** /**
* JUnit Test for {@link SecretListResponse} model. * JUnit Test for {@link SecretListResponse} model.
@ -34,7 +34,7 @@ import static org.junit.jupiter.api.Assertions.fail;
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.8 * @since 0.8
*/ */
public class SecretListResponseTest { class SecretListResponseTest {
private static final Map<String, Object> DATA = new HashMap<>(); private static final Map<String, Object> DATA = new HashMap<>();
private static final String KEY1 = "key1"; private static final String KEY1 = "key1";
private static final String KEY2 = "key-2"; private static final String KEY2 = "key-2";
@ -50,20 +50,19 @@ public class SecretListResponseTest {
* @throws InvalidResponseException Should not occur * @throws InvalidResponseException Should not occur
*/ */
@Test @Test
public void getKeysTest() throws InvalidResponseException { void getKeysTest() throws InvalidResponseException {
// Create empty Object. // Create empty Object.
SecretListResponse res = new SecretListResponse(); SecretListResponse res = new SecretListResponse();
assertThat("Keys should be null without initialization", res.getKeys(), is(nullValue())); assertThat("Keys should be null without initialization", res.getKeys(), is(nullValue()));
// Provoke internal ClassCastException. // Provoke internal ClassCastException.
try { Map<String, Object> invalidData = new HashMap<>();
Map<String, Object> invalidData = new HashMap<>(); invalidData.put("keys", "some string");
invalidData.put("keys", "some string"); assertThrows(
res.setData(invalidData); InvalidResponseException.class,
fail("Setting incorrect class succeeded"); () -> res.setData(invalidData),
} catch (Exception e) { "Setting incorrect class succeeded"
assertThat("Unexpected exception type", e, instanceOf(InvalidResponseException.class)); );
}
// Fill correct data. // Fill correct data.
res.setData(DATA); res.setData(DATA);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -20,14 +20,14 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import de.stklcode.jvault.connector.exception.InvalidResponseException; import de.stklcode.jvault.connector.exception.InvalidResponseException;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*; import static org.hamcrest.Matchers.*;
import static org.junit.jupiter.api.Assertions.fail; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertThrows;
/** /**
* JUnit Test for {@link SecretResponse} model. * JUnit Test for {@link SecretResponse} model.
@ -35,7 +35,7 @@ import static org.junit.jupiter.api.Assertions.fail;
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.6.2 * @since 0.6.2
*/ */
public class SecretResponseTest { class SecretResponseTest {
private static final Map<String, Object> DATA = new HashMap<>(); private static final Map<String, Object> DATA = new HashMap<>();
private static final String KEY_UNKNOWN = "unknown"; private static final String KEY_UNKNOWN = "unknown";
private static final String KEY_STRING = "test1"; private static final String KEY_STRING = "test1";
@ -120,7 +120,7 @@ public class SecretResponseTest {
*/ */
@Test @Test
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void getDataRoundtrip() throws InvalidResponseException { void getDataRoundtrip() throws InvalidResponseException {
// Create empty Object. // Create empty Object.
SecretResponse res = new SecretResponse(); SecretResponse res = new SecretResponse();
assertThat("Initial data should be Map", res.getData(), is(instanceOf(Map.class))); assertThat("Initial data should be Map", res.getData(), is(instanceOf(Map.class)));
@ -137,61 +137,58 @@ public class SecretResponseTest {
assertThat("Non-Null returned on unknown key", res.get(KEY_UNKNOWN), is(nullValue())); assertThat("Non-Null returned on unknown key", res.get(KEY_UNKNOWN), is(nullValue()));
// Try explicit JSON conversion. // Try explicit JSON conversion.
final List list = res.get(KEY_LIST, List.class); final List<?> list = res.get(KEY_LIST, List.class);
assertThat("JSON parsing of list failed", list, is(notNullValue())); assertThat("JSON parsing of list failed", list, is(notNullValue()));
assertThat("JSON parsing of list returned incorrect size", list.size(), is(2)); assertThat("JSON parsing of list returned incorrect size", list.size(), is(2));
assertThat("JSON parsing of list returned incorrect elements", (List<Object>)list, contains("first", "second")); assertThat("JSON parsing of list returned incorrect elements", list, contains("first", "second"));
assertThat("Non-Null returned on unknown key", res.get(KEY_UNKNOWN, Object.class), is(nullValue())); assertThat("Non-Null returned on unknown key", res.get(KEY_UNKNOWN, Object.class), is(nullValue()));
// Requesting invalid class should result in Exception. // Requesting invalid class should result in Exception.
try { assertThrows(
res.get(KEY_LIST, Double.class); InvalidResponseException.class,
fail("JSON parsing to incorrect type succeeded."); () -> res.get(KEY_LIST, Double.class),
} catch (Exception e) { "JSON parsing to incorrect type succeeded."
assertThat(e, is(instanceOf(InvalidResponseException.class))); );
}
} }
/** /**
* Test creation from JSON value as returned by Vault (JSON example copied from Vault documentation). * Test creation from JSON value as returned by Vault (JSON example copied from Vault documentation).
*/ */
@Test @Test
public void jsonRoundtrip() { void jsonRoundtrip() {
try { SecretResponse res = assertDoesNotThrow(
assertSecretData(new ObjectMapper().readValue(SECRET_JSON, SecretResponse.class)); () -> new ObjectMapper().readValue(SECRET_JSON, SecretResponse.class),
} catch (IOException e) { "SecretResponse deserialization failed."
fail("SecretResponse deserialization failed: " + e.getMessage()); );
} assertSecretData(res);
// KV v2 secret. // KV v2 secret.
try { res = assertDoesNotThrow(
SecretResponse res = new ObjectMapper().readValue(SECRET_JSON_V2, SecretResponse.class); () -> new ObjectMapper().readValue(SECRET_JSON_V2, SecretResponse.class),
assertSecretData(res); "SecretResponse deserialization failed."
assertThat("SecretResponse does not contain metadata", res.getMetadata(), is(notNullValue())); );
assertThat("Incorrect creation date string", res.getMetadata().getCreatedTimeString(), is(SECRET_META_CREATED)); assertSecretData(res);
assertThat("Creation date parsing failed", res.getMetadata().getCreatedTime(), is(notNullValue())); assertThat("SecretResponse does not contain metadata", res.getMetadata(), is(notNullValue()));
assertThat("Incorrect deletion date string", res.getMetadata().getDeletionTimeString(), is(emptyString())); assertThat("Incorrect creation date string", res.getMetadata().getCreatedTimeString(), is(SECRET_META_CREATED));
assertThat("Incorrect deletion date", res.getMetadata().getDeletionTime(), is(nullValue())); assertThat("Creation date parsing failed", res.getMetadata().getCreatedTime(), is(notNullValue()));
assertThat("Secret destroyed when not expected", res.getMetadata().isDestroyed(), is(false)); assertThat("Incorrect deletion date string", res.getMetadata().getDeletionTimeString(), is(emptyString()));
assertThat("Incorrect secret version", res.getMetadata().getVersion(), is(1)); assertThat("Incorrect deletion date", res.getMetadata().getDeletionTime(), is(nullValue()));
} catch (IOException e) { assertThat("Secret destroyed when not expected", res.getMetadata().isDestroyed(), is(false));
fail("SecretResponse deserialization failed: " + e.getMessage()); assertThat("Incorrect secret version", res.getMetadata().getVersion(), is(1));
}
// Deleted KV v2 secret. // Deleted KV v2 secret.
try { res = assertDoesNotThrow(
SecretResponse res = new ObjectMapper().readValue(SECRET_JSON_V2_2, SecretResponse.class); () -> new ObjectMapper().readValue(SECRET_JSON_V2_2, SecretResponse.class),
assertSecretData(res); "SecretResponse deserialization failed."
assertThat("SecretResponse does not contain metadata", res.getMetadata(), is(notNullValue())); );
assertThat("Incorrect creation date string", res.getMetadata().getCreatedTimeString(), is(SECRET_META_CREATED)); assertSecretData(res);
assertThat("Creation date parsing failed", res.getMetadata().getCreatedTime(), is(notNullValue())); assertThat("SecretResponse does not contain metadata", res.getMetadata(), is(notNullValue()));
assertThat("Incorrect deletion date string", res.getMetadata().getDeletionTimeString(), is(SECRET_META_DELETED)); assertThat("Incorrect creation date string", res.getMetadata().getCreatedTimeString(), is(SECRET_META_CREATED));
assertThat("Incorrect deletion date", res.getMetadata().getDeletionTime(), is(notNullValue())); assertThat("Creation date parsing failed", res.getMetadata().getCreatedTime(), is(notNullValue()));
assertThat("Secret destroyed when not expected", res.getMetadata().isDestroyed(), is(true)); assertThat("Incorrect deletion date string", res.getMetadata().getDeletionTimeString(), is(SECRET_META_DELETED));
assertThat("Incorrect secret version", res.getMetadata().getVersion(), is(2)); assertThat("Incorrect deletion date", res.getMetadata().getDeletionTime(), is(notNullValue()));
} catch (IOException e) { assertThat("Secret destroyed when not expected", res.getMetadata().isDestroyed(), is(true));
fail("SecretResponse deserialization failed: " + e.getMessage()); assertThat("Incorrect secret version", res.getMetadata().getVersion(), is(2));
}
} }
private void assertSecretData(SecretResponse res) { private void assertSecretData(SecretResponse res) {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -19,12 +19,10 @@ package de.stklcode.jvault.connector.model.response;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.io.IOException;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.notNullValue;
import static org.junit.jupiter.api.Assertions.fail; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/** /**
* JUnit Test for {@link SecretVersionResponse} model. * JUnit Test for {@link SecretVersionResponse} model.
@ -32,7 +30,7 @@ import static org.junit.jupiter.api.Assertions.fail;
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.8 * @since 0.8
*/ */
public class SecretVersionResponseTest { class SecretVersionResponseTest {
private static final String CREATION_TIME = "2018-03-22T02:24:06.945319214Z"; private static final String CREATION_TIME = "2018-03-22T02:24:06.945319214Z";
private static final String DELETION_TIME = "2018-03-22T02:36:43.986212308Z"; private static final String DELETION_TIME = "2018-03-22T02:36:43.986212308Z";
private static final Integer VERSION = 42; private static final Integer VERSION = 42;
@ -50,17 +48,16 @@ public class SecretVersionResponseTest {
* Test creation from JSON value as returned by Vault (JSON example copied from Vault documentation). * Test creation from JSON value as returned by Vault (JSON example copied from Vault documentation).
*/ */
@Test @Test
public void jsonRoundtrip() { void jsonRoundtrip() {
try { SecretVersionResponse res = assertDoesNotThrow(
SecretVersionResponse res = new ObjectMapper().readValue(META_JSON, SecretVersionResponse.class); () -> new ObjectMapper().readValue(META_JSON, SecretVersionResponse.class),
assertThat("Parsed response is NULL", res, is(notNullValue())); "SecretVersionResponse deserialization failed"
assertThat("Parsed metadata is NULL", res.getMetadata(), is(notNullValue())); );
assertThat("Incorrect created time", res.getMetadata().getCreatedTimeString(), is(CREATION_TIME)); assertThat("Parsed response is NULL", res, is(notNullValue()));
assertThat("Incorrect deletion time", res.getMetadata().getDeletionTimeString(), is(DELETION_TIME)); assertThat("Parsed metadata is NULL", res.getMetadata(), is(notNullValue()));
assertThat("Incorrect destroyed state", res.getMetadata().isDestroyed(), is(false)); assertThat("Incorrect created time", res.getMetadata().getCreatedTimeString(), is(CREATION_TIME));
assertThat("Incorrect version", res.getMetadata().getVersion(), is(VERSION)); assertThat("Incorrect deletion time", res.getMetadata().getDeletionTimeString(), is(DELETION_TIME));
} catch (IOException e) { assertThat("Incorrect destroyed state", res.getMetadata().isDestroyed(), is(false));
fail("SecretVersionResponse deserialization failed: " + e.getMessage()); assertThat("Incorrect version", res.getMetadata().getVersion(), is(VERSION));
}
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -21,14 +21,14 @@ import de.stklcode.jvault.connector.exception.InvalidResponseException;
import de.stklcode.jvault.connector.model.response.embedded.TokenData; import de.stklcode.jvault.connector.model.response.embedded.TokenData;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*; import static org.hamcrest.Matchers.*;
import static org.junit.jupiter.api.Assertions.fail; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertThrows;
/** /**
* JUnit Test for {@link TokenResponse} model. * JUnit Test for {@link TokenResponse} model.
@ -36,7 +36,7 @@ import static org.junit.jupiter.api.Assertions.fail;
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.6.2 * @since 0.6.2
*/ */
public class TokenResponseTest { class TokenResponseTest {
private static final Integer TOKEN_CREATION_TIME = 1457533232; private static final Integer TOKEN_CREATION_TIME = 1457533232;
private static final Integer TOKEN_TTL = 2764800; private static final Integer TOKEN_TTL = 2764800;
private static final Integer TOKEN_EXPLICIT_MAX_TTL = 0; private static final Integer TOKEN_EXPLICIT_MAX_TTL = 0;
@ -101,57 +101,55 @@ public class TokenResponseTest {
* Test getter, setter and get-methods for response data. * Test getter, setter and get-methods for response data.
*/ */
@Test @Test
public void getDataRoundtrip() { void getDataRoundtrip() {
// Create empty Object. // Create empty Object.
TokenResponse res = new TokenResponse(); TokenResponse res = new TokenResponse();
assertThat("Initial data should be empty", res.getData(), is(nullValue())); assertThat("Initial data should be empty", res.getData(), is(nullValue()));
// Parsing invalid data map should fail. // Parsing invalid data map should fail.
try { assertThrows(
res.setData(INVALID_TOKEN_DATA); InvalidResponseException.class,
fail("Parsing invalid token data succeeded"); () -> res.setData(INVALID_TOKEN_DATA),
} catch (Exception e) { "Parsing invalid token data succeeded"
assertThat(e, is(instanceOf(InvalidResponseException.class))); );
}
} }
/** /**
* Test creation from JSON value as returned by Vault (JSON example copied from Vault documentation). * Test creation from JSON value as returned by Vault (JSON example copied from Vault documentation).
*/ */
@Test @Test
public void jsonRoundtrip() { void jsonRoundtrip() {
try { TokenResponse res = assertDoesNotThrow(
TokenResponse res = new ObjectMapper().readValue(RES_JSON, TokenResponse.class); () -> new ObjectMapper().readValue(RES_JSON, TokenResponse.class),
assertThat("Parsed response is NULL", res, is(notNullValue())); "TokenResponse deserialization failed."
assertThat("Incorrect lease duration", res.getLeaseDuration(), is(RES_LEASE_DURATION)); );
assertThat("Incorrect response renewable flag", res.isRenewable(), is(RES_RENEWABLE)); assertThat("Parsed response is NULL", res, is(notNullValue()));
assertThat("Incorrect response lease duration", res.getLeaseDuration(), is(RES_LEASE_DURATION)); assertThat("Incorrect lease duration", res.getLeaseDuration(), is(RES_LEASE_DURATION));
// Extract token data. assertThat("Incorrect response renewable flag", res.isRenewable(), is(RES_RENEWABLE));
TokenData data = res.getData(); assertThat("Incorrect response lease duration", res.getLeaseDuration(), is(RES_LEASE_DURATION));
assertThat("Token data is NULL", data, is(notNullValue())); // Extract token data.
assertThat("Incorrect token accessor", data.getAccessor(), is(TOKEN_ACCESSOR)); TokenData data = res.getData();
assertThat("Incorrect token creation time", data.getCreationTime(), is(TOKEN_CREATION_TIME)); assertThat("Token data is NULL", data, is(notNullValue()));
assertThat("Incorrect token creation TTL", data.getCreationTtl(), is(TOKEN_TTL)); assertThat("Incorrect token accessor", data.getAccessor(), is(TOKEN_ACCESSOR));
assertThat("Incorrect token display name", data.getName(), is(TOKEN_DISPLAY_NAME)); assertThat("Incorrect token creation time", data.getCreationTime(), is(TOKEN_CREATION_TIME));
assertThat("Incorrect token entity ID", data.getEntityId(), is(TOKEN_ENTITY_ID)); assertThat("Incorrect token creation TTL", data.getCreationTtl(), is(TOKEN_TTL));
assertThat("Incorrect token expire time", data.getExpireTimeString(), is(TOKEN_EXPIRE_TIME)); assertThat("Incorrect token display name", data.getName(), is(TOKEN_DISPLAY_NAME));
assertThat("Incorrect parsed token expire time", data.getExpireTime(), is(ZonedDateTime.parse(TOKEN_EXPIRE_TIME))); assertThat("Incorrect token entity ID", data.getEntityId(), is(TOKEN_ENTITY_ID));
assertThat("Incorrect token explicit max TTL", data.getExplicitMaxTtl(), is(TOKEN_EXPLICIT_MAX_TTL)); assertThat("Incorrect token expire time", data.getExpireTimeString(), is(TOKEN_EXPIRE_TIME));
assertThat("Incorrect token ID", data.getId(), is(TOKEN_ID)); assertThat("Incorrect parsed token expire time", data.getExpireTime(), is(ZonedDateTime.parse(TOKEN_EXPIRE_TIME)));
assertThat("Incorrect token issue time", data.getIssueTimeString(), is(TOKEN_ISSUE_TIME)); assertThat("Incorrect token explicit max TTL", data.getExplicitMaxTtl(), is(TOKEN_EXPLICIT_MAX_TTL));
assertThat("Incorrect parsed token issue time", data.getIssueTime(), is(ZonedDateTime.parse(TOKEN_ISSUE_TIME))); assertThat("Incorrect token ID", data.getId(), is(TOKEN_ID));
assertThat("Incorrect token metadata size", data.getMeta().entrySet(), hasSize(1)); assertThat("Incorrect token issue time", data.getIssueTimeString(), is(TOKEN_ISSUE_TIME));
assertThat("Incorrect token metadata", data.getMeta().get(TOKEN_META_KEY), is(TOKEN_META_VALUE)); assertThat("Incorrect parsed token issue time", data.getIssueTime(), is(ZonedDateTime.parse(TOKEN_ISSUE_TIME)));
assertThat("Incorrect token number of uses", data.getNumUses(), is(TOKEN_NUM_USES)); assertThat("Incorrect token metadata size", data.getMeta().entrySet(), hasSize(1));
assertThat("Incorrect token orphan flag", data.isOrphan(), is(TOKEN_ORPHAN)); assertThat("Incorrect token metadata", data.getMeta().get(TOKEN_META_KEY), is(TOKEN_META_VALUE));
assertThat("Incorrect token path", data.getPath(), is(TOKEN_PATH)); assertThat("Incorrect token number of uses", data.getNumUses(), is(TOKEN_NUM_USES));
assertThat("Incorrect number of token policies", data.getPolicies(), hasSize(2)); assertThat("Incorrect token orphan flag", data.isOrphan(), is(TOKEN_ORPHAN));
assertThat("Incorrect token policies", data.getPolicies(), contains(TOKEN_POLICY_1, TOKEN_POLICY_2)); assertThat("Incorrect token path", data.getPath(), is(TOKEN_PATH));
assertThat("Incorrect token renewable flag", data.isRenewable(), is(TOKEN_RENEWABLE)); assertThat("Incorrect number of token policies", data.getPolicies(), hasSize(2));
assertThat("Incorrect token TTL", data.getTtl(), is(RES_TTL)); assertThat("Incorrect token policies", data.getPolicies(), contains(TOKEN_POLICY_1, TOKEN_POLICY_2));
assertThat("Incorrect token type", data.getType(), is(TOKEN_TYPE)); assertThat("Incorrect token renewable flag", data.isRenewable(), is(TOKEN_RENEWABLE));
} catch (IOException e) { assertThat("Incorrect token TTL", data.getTtl(), is(RES_TTL));
fail("TokenResponse deserialization failed: " + e.getMessage()); assertThat("Incorrect token type", data.getType(), is(TOKEN_TYPE));
}
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -1,51 +0,0 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.stklcode.jvault.connector.test;
import java.lang.reflect.Field;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.fail;
/**
* Test helper to modify system environment.
*
* @author Stefan Kalscheuer
*/
@SuppressWarnings("unchecked")
public class EnvironmentMock {
private static Map<String, String> environment;
static {
try {
Map<String, String> originalEnv = System.getenv();
Field mapField = originalEnv.getClass().getDeclaredField("m");
mapField.setAccessible(true);
environment = (Map<String, String>) mapField.get(originalEnv);
} catch (NoSuchFieldException | IllegalAccessException | ClassCastException e) {
fail("Failed to intercept unmodifiable system environment");
}
}
public static void setenv(String key, String value) {
if (value != null) {
environment.put(key, value);
} else {
environment.remove(key);
}
}
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2020 Stefan Kalscheuer * Copyright 2016-2021 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.