Compare commits
22 Commits
Author | SHA1 | Date | |
---|---|---|---|
bbceee35f2 | |||
3a920fe960 | |||
eed61c4569 | |||
53d954ea12 | |||
e578591a49 | |||
de17f48be2 | |||
5f9950e048 | |||
e2c439379e | |||
ce33d37396 | |||
bdf4fc4b83 | |||
50d485fab8 | |||
5b508374d9 | |||
fbc61e065f | |||
56a52cb22a | |||
c43ec190ca | |||
639d0e3c5b | |||
8e97f3c1dd | |||
c04d940a80 | |||
76a5ea4fe9 | |||
2b0f458da3 | |||
63278c09c8 | |||
600f3d0d0f |
14
.drone.yml
14
.drone.yml
@ -8,7 +8,7 @@ steps:
|
||||
- mvn -B clean compile
|
||||
when:
|
||||
branch:
|
||||
- master
|
||||
- main
|
||||
- develop
|
||||
- feature/*
|
||||
- fix/*
|
||||
@ -25,15 +25,15 @@ steps:
|
||||
- name: unit-integration-tests
|
||||
image: maven:3-jdk-11
|
||||
environment:
|
||||
VAULT_VERSION: 1.6.1
|
||||
VAULT_VERSION: 1.8.0
|
||||
commands:
|
||||
- curl -s -o vault_1.6.1_linux_amd64.zip https://releases.hashicorp.com/vault/1.6.1/vault_1.6.1_linux_amd64.zip
|
||||
- curl -s https://releases.hashicorp.com/vault/1.6.1/vault_1.6.1_SHA256SUMS | grep linux_amd64 | sha256sum -c
|
||||
- unzip vault_1.6.1_linux_amd64.zip
|
||||
- rm vault_1.6.1_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.8.0/vault_1.8.0_SHA256SUMS | grep linux_amd64 | sha256sum -c
|
||||
- unzip vault_1.8.0_linux_amd64.zip
|
||||
- rm vault_1.8.0_linux_amd64.zip
|
||||
- mv vault /bin/
|
||||
- mvn -B resources:testResources compiler:testCompile surefire:test
|
||||
when:
|
||||
branch:
|
||||
- master
|
||||
- main
|
||||
- release/*
|
10
.travis.yml
10
.travis.yml
@ -7,7 +7,7 @@ addons:
|
||||
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="
|
||||
|
||||
env:
|
||||
- PATH=$PATH:. VAULT_VERSION=1.6.1 ANALYSIS=false
|
||||
- PATH=$PATH:. VAULT_VERSION=1.8.0 ANALYSIS=false
|
||||
|
||||
cache:
|
||||
directories:
|
||||
@ -18,12 +18,12 @@ jobs:
|
||||
include:
|
||||
- jdk: openjdk8
|
||||
- jdk: openjdk11
|
||||
env: PATH=$PATH:. VAULT_VERSION=1.6.1 ANALYSIS=true
|
||||
- jdk: openjdk15
|
||||
env: PATH=$PATH:. VAULT_VERSION=1.8.0 ANALYSIS=true
|
||||
- jdk: openjdk16
|
||||
|
||||
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 -O - https://releases.hashicorp.com/vault/${VAULT_VERSION}/vault_${VAULT_VERSION}_SHA256SUMS | grep linux_amd64 | sha256sum -c
|
||||
unzip vault_${VAULT_VERSION}_linux_amd64.zip
|
||||
@ -33,7 +33,7 @@ before_script:
|
||||
script:
|
||||
- mvn -B clean compile
|
||||
- |
|
||||
if [[ "$TRAVIS_BRANCH" =~ ^master|(release\/.+)$ ]]; then
|
||||
if [[ "$TRAVIS_BRANCH" =~ ^main|(release\/.+)$ ]]; then
|
||||
mvn -B resources:testResources compiler:testCompile surefire:test -P coverage
|
||||
else
|
||||
mvn -B resources:testResources compiler:testCompile surefire:test -P coverage -P offline-tests
|
||||
|
36
CHANGELOG.md
36
CHANGELOG.md
@ -1,3 +1,39 @@
|
||||
## 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
|
||||
|
28
README.md
28
README.md
@ -1,11 +1,11 @@
|
||||
# Java Vault Connector
|
||||
|
||||
[](https://travis-ci.com/stklcode/jvaultconnector)
|
||||
[](https://travis-ci.com/stklcode/jvaultconnector)
|
||||
[](https://sonarcloud.io/dashboard?id=de.stklcode.jvault%3Ajvault-connector)
|
||||
[](https://github.com/stklcode/jvaultconnector/blob/master/LICENSE.txt)
|
||||
[](https://github.com/stklcode/jvaultconnector/blob/main/LICENSE.txt)
|
||||
[](https://search.maven.org/#search%7Cga%7C1%7Cg%3A%22de.stklcode.jvault%22%20AND%20a%3A%22jvault-connector%22)
|
||||
|
||||

|
||||

|
||||
|
||||
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
|
||||
* KV v1 and v2 support
|
||||
* Connector Factory with builder pattern
|
||||
* Tested against Vault 1.6.1
|
||||
* Tested against Vault 1.8.0
|
||||
|
||||
|
||||
## Maven Artifact
|
||||
@ -40,7 +40,7 @@ Java Vault Connector is a connector library for [Vault](https://www.vaultproject
|
||||
<dependency>
|
||||
<groupId>de.stklcode.jvault</groupId>
|
||||
<artifactId>jvault-connector</artifactId>
|
||||
<version>0.9.2</version>
|
||||
<version>0.9.5</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
@ -50,21 +50,21 @@ Java Vault Connector is a connector library for [Vault](https://www.vaultproject
|
||||
|
||||
```java
|
||||
// Instantiate using builder pattern style factory (TLS enabled by default)
|
||||
VaultConnector vault = VaultConnectorBuilder.http()
|
||||
VaultConnector vault = HTTPVaultConnector.builder()
|
||||
.withHost("127.0.0.1")
|
||||
.withPort(8200)
|
||||
.withTLS()
|
||||
.build();
|
||||
|
||||
// Instantiate with custom SSL context
|
||||
VaultConnector vault = VaultConnectorBuilder.http()
|
||||
VaultConnector vault = HTTPVaultConnector.builder()
|
||||
.withHost("example.com")
|
||||
.withPort(8200)
|
||||
.withTrustedCA(Paths.get("/path/to/CA.pem"))
|
||||
.build();
|
||||
|
||||
// Initialization from environment variables
|
||||
VaultConnector vault = VaultConnectorBuilder.http()
|
||||
VaultConnector vault = HTTPVaultConnector.builder()
|
||||
.fromEnv()
|
||||
.build();
|
||||
```
|
||||
@ -86,20 +86,20 @@ vault.authAppRole("01234567-89ab-cdef-0123-456789abcdef", "fedcba98-7654-3210-fe
|
||||
|
||||
```java
|
||||
// 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.
|
||||
Map<String, Object> secretData = vault.readSecret("another/secret/key").getData();
|
||||
Map<String, Object> secretData = vault.read("secret/another/key").getData();
|
||||
|
||||
// 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 = ...;
|
||||
vault.write("any/path/to/write", map);
|
||||
vault.write("path/to/write", map);
|
||||
|
||||
// Delete secret.
|
||||
vault.delete("any/path/to/write");
|
||||
vault.delete("path/to/delete");
|
||||
```
|
||||
|
||||
### Token and role creation
|
||||
|
55
pom.xml
55
pom.xml
@ -4,7 +4,7 @@
|
||||
|
||||
<groupId>de.stklcode.jvault</groupId>
|
||||
<artifactId>jvault-connector</artifactId>
|
||||
<version>0.9.2</version>
|
||||
<version>0.9.5</version>
|
||||
|
||||
<packaging>jar</packaging>
|
||||
|
||||
@ -23,6 +23,7 @@
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<argLine></argLine>
|
||||
</properties>
|
||||
|
||||
<developers>
|
||||
@ -96,6 +97,7 @@
|
||||
<version>2.22.2</version>
|
||||
<configuration>
|
||||
<reuseForks>false</reuseForks>
|
||||
<argLine>@{argLine} --illegal-access=permit</argLine>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
@ -111,13 +113,13 @@
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>2.12.1</version>
|
||||
<version>2.12.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter</artifactId>
|
||||
<version>5.7.0</version>
|
||||
<version>5.7.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -128,20 +130,20 @@
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<version>3.7.7</version>
|
||||
<artifactId>mockito-inline</artifactId>
|
||||
<version>3.11.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-inline</artifactId>
|
||||
<version>3.7.7</version>
|
||||
<groupId>com.github.stefanbirkner</groupId>
|
||||
<artifactId>system-lambda</artifactId>
|
||||
<version>1.2.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>2.8.0</version>
|
||||
<version>2.11.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
@ -151,7 +153,7 @@
|
||||
<dependency>
|
||||
<groupId>org.sonarsource.scanner.maven</groupId>
|
||||
<artifactId>sonar-maven-plugin</artifactId>
|
||||
<version>3.8.0.2131</version>
|
||||
<version>3.9.0.2155</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
@ -192,7 +194,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0</version>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
</configuration>
|
||||
@ -216,7 +218,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-gpg-plugin</artifactId>
|
||||
<version>1.6</version>
|
||||
<version>3.0.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>sign-artifacts</id>
|
||||
@ -241,17 +243,16 @@
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
<version>0.8.6</version>
|
||||
<version>0.8.7</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>prepare-agent</id>
|
||||
<id>default-prepare-agent</id>
|
||||
<goals>
|
||||
<goal>prepare-agent</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>report</id>
|
||||
<phase>prepare-package</phase>
|
||||
<id>default-report</id>
|
||||
<goals>
|
||||
<goal>report</goal>
|
||||
</goals>
|
||||
@ -286,7 +287,7 @@
|
||||
<plugin>
|
||||
<groupId>org.owasp</groupId>
|
||||
<artifactId>dependency-check-maven</artifactId>
|
||||
<version>6.0.5</version>
|
||||
<version>6.2.2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
@ -299,6 +300,26 @@
|
||||
</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>
|
||||
<id>sonatype</id>
|
||||
<distributionManagement>
|
||||
|
@ -30,6 +30,9 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
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.
|
||||
*
|
||||
@ -68,6 +71,16 @@ public class HTTPVaultConnector implements VaultConnector {
|
||||
private String token; // 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.
|
||||
*
|
||||
@ -222,17 +235,17 @@ public class HTTPVaultConnector implements VaultConnector {
|
||||
|
||||
@Override
|
||||
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
|
||||
public final void seal() throws VaultConnectorException {
|
||||
request.put(PATH_SEAL, new HashMap<>(), token);
|
||||
request.put(PATH_SEAL, emptyMap(), token);
|
||||
}
|
||||
|
||||
@Override
|
||||
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);
|
||||
if (reset != null) {
|
||||
param.put("reset", reset.toString());
|
||||
@ -244,7 +257,7 @@ public class HTTPVaultConnector implements VaultConnector {
|
||||
@Override
|
||||
public HealthResponse getHealth() throws VaultConnectorException {
|
||||
/* 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("sealedcode", "200"); // Default: 503.
|
||||
param.put("uninitcode", "200"); // Default: 501.
|
||||
@ -260,7 +273,7 @@ public class HTTPVaultConnector implements VaultConnector {
|
||||
@Override
|
||||
public final List<AuthBackend> getAuthBackends() throws VaultConnectorException {
|
||||
/* 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());
|
||||
}
|
||||
@ -270,7 +283,7 @@ public class HTTPVaultConnector implements VaultConnector {
|
||||
/* set token */
|
||||
this.token = token;
|
||||
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;
|
||||
|
||||
return res;
|
||||
@ -279,15 +292,14 @@ public class HTTPVaultConnector implements VaultConnector {
|
||||
@Override
|
||||
public final AuthResponse authUserPass(final String username, final String password)
|
||||
throws VaultConnectorException {
|
||||
final Map<String, String> payload = new HashMap<>();
|
||||
payload.put("password", password);
|
||||
final Map<String, String> payload = singletonMap("password", password);
|
||||
return queryAuth(PATH_AUTH_USERPASS + username, payload);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
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("user_id", userID);
|
||||
return queryAuth(PATH_AUTH_APPID + "login", payload);
|
||||
@ -295,7 +307,7 @@ public class HTTPVaultConnector implements VaultConnector {
|
||||
|
||||
@Override
|
||||
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);
|
||||
if (secretID != null) {
|
||||
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)
|
||||
throws VaultConnectorException {
|
||||
requireAuth();
|
||||
Map<String, String> payload = new HashMap<>();
|
||||
Map<String, String> payload = new HashMap<>(2, 1);
|
||||
payload.put("value", policy);
|
||||
payload.put("display_name", displayName);
|
||||
|
||||
@ -342,11 +354,13 @@ public class HTTPVaultConnector implements VaultConnector {
|
||||
@Deprecated
|
||||
public final boolean registerUserId(final String appID, final String userID) throws VaultConnectorException {
|
||||
requireAuth();
|
||||
Map<String, String> payload = new HashMap<>();
|
||||
payload.put("value", appID);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
@ -366,7 +380,12 @@ public class HTTPVaultConnector implements VaultConnector {
|
||||
public final AppRoleResponse lookupAppRole(final String roleName) throws VaultConnectorException {
|
||||
requireAuth();
|
||||
/* 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
|
||||
@ -385,7 +404,7 @@ public class HTTPVaultConnector implements VaultConnector {
|
||||
/* Issue request, parse response and extract Role ID */
|
||||
return request.get(
|
||||
String.format(PATH_AUTH_APPROLE_ROLE, roleName, "/role-id"),
|
||||
new HashMap<>(),
|
||||
emptyMap(),
|
||||
token,
|
||||
RawDataResponse.class
|
||||
).getData().get("role_id").toString();
|
||||
@ -394,12 +413,13 @@ public class HTTPVaultConnector implements VaultConnector {
|
||||
@Override
|
||||
public final boolean setAppRoleID(final String roleName, final String roleID) throws VaultConnectorException {
|
||||
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 */
|
||||
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;
|
||||
}
|
||||
@ -457,7 +477,13 @@ public class HTTPVaultConnector implements VaultConnector {
|
||||
public final List<String> listAppRoles() throws VaultConnectorException {
|
||||
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();
|
||||
}
|
||||
|
||||
@ -467,7 +493,7 @@ public class HTTPVaultConnector implements VaultConnector {
|
||||
|
||||
SecretListResponse secrets = request.get(
|
||||
String.format(PATH_AUTH_APPROLE_ROLE, roleName, "/secret-id?list=true"),
|
||||
new HashMap<>(),
|
||||
emptyMap(),
|
||||
token,
|
||||
SecretListResponse.class
|
||||
);
|
||||
@ -479,14 +505,14 @@ public class HTTPVaultConnector implements VaultConnector {
|
||||
public final SecretResponse read(final String key) throws VaultConnectorException {
|
||||
requireAuth();
|
||||
/* Issue request and parse secret response */
|
||||
return request.get(key, new HashMap<>(), token, SecretResponse.class);
|
||||
return request.get(key, emptyMap(), token, SecretResponse.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final SecretResponse readSecretVersion(final String mount, final String key, final Integer version) throws VaultConnectorException {
|
||||
requireAuth();
|
||||
/* Request HTTP response and parse secret metadata */
|
||||
Map<String, String> args = new HashMap<>();
|
||||
Map<String, String> args = new HashMap<>(1, 1);
|
||||
if (version != null) {
|
||||
args.put("version", version.toString());
|
||||
}
|
||||
@ -499,14 +525,14 @@ public class HTTPVaultConnector implements VaultConnector {
|
||||
requireAuth();
|
||||
|
||||
/* 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
|
||||
public void updateSecretMetadata(final String mount, final String key, final Integer maxVersions, final boolean casRequired) throws VaultConnectorException {
|
||||
requireAuth();
|
||||
|
||||
Map<String, Object> payload = new HashMap<>();
|
||||
Map<String, Object> payload = new HashMap<>(2, 1);
|
||||
if (maxVersions != null) {
|
||||
payload.put("max_versions", maxVersions);
|
||||
}
|
||||
@ -524,12 +550,12 @@ public class HTTPVaultConnector implements VaultConnector {
|
||||
}
|
||||
|
||||
// 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) {
|
||||
options.put("cas", cas);
|
||||
}
|
||||
|
||||
Map<String, Object> payload = new HashMap<>();
|
||||
Map<String, Object> payload = new HashMap<>(2, 1);
|
||||
payload.put("data", data);
|
||||
payload.put("options", options);
|
||||
|
||||
@ -541,7 +567,7 @@ public class HTTPVaultConnector implements VaultConnector {
|
||||
public final List<String> list(final String path) throws VaultConnectorException {
|
||||
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();
|
||||
}
|
||||
@ -559,7 +585,7 @@ public class HTTPVaultConnector implements VaultConnector {
|
||||
|
||||
// If options are given, split payload in two parts.
|
||||
if (options != null) {
|
||||
Map<String, Object> payloadMap = new HashMap<>();
|
||||
Map<String, Object> payloadMap = new HashMap<>(2, 1);
|
||||
payloadMap.put("data", data);
|
||||
payloadMap.put("options", options);
|
||||
payload = payloadMap;
|
||||
@ -616,8 +642,7 @@ public class HTTPVaultConnector implements VaultConnector {
|
||||
requireAuth();
|
||||
|
||||
/* Request HTTP response and expect empty result */
|
||||
Map<String, Object> payload = new HashMap<>();
|
||||
payload.put("versions", versions);
|
||||
Map<String, Object> payload = singletonMap("versions", versions);
|
||||
|
||||
/* Issue request and expect code 204 with empty response */
|
||||
request.postWithoutResponse(mount + pathPart + key, payload, token);
|
||||
@ -628,14 +653,14 @@ public class HTTPVaultConnector implements VaultConnector {
|
||||
requireAuth();
|
||||
|
||||
/* 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
|
||||
public final SecretResponse renew(final String leaseID, final Integer increment) throws VaultConnectorException {
|
||||
requireAuth();
|
||||
|
||||
Map<String, String> payload = new HashMap<>();
|
||||
Map<String, String> payload = new HashMap<>(2, 1);
|
||||
payload.put("lease_id", leaseID);
|
||||
if (increment != null) {
|
||||
payload.put("increment", increment.toString());
|
||||
@ -694,9 +719,12 @@ public class HTTPVaultConnector implements VaultConnector {
|
||||
requireAuth();
|
||||
|
||||
/* Request HTTP response and parse Secret */
|
||||
Map<String, String> param = new HashMap<>();
|
||||
param.put("token", token);
|
||||
return request.get(PATH_TOKEN + PATH_LOOKUP, param, token, TokenResponse.class);
|
||||
return request.get(
|
||||
PATH_TOKEN + PATH_LOOKUP,
|
||||
singletonMap("token", token),
|
||||
token,
|
||||
TokenResponse.class
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -720,7 +748,7 @@ public class HTTPVaultConnector implements VaultConnector {
|
||||
requireAuth();
|
||||
|
||||
// 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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -22,10 +22,7 @@ import de.stklcode.jvault.connector.model.*;
|
||||
import de.stklcode.jvault.connector.model.response.*;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Vault Connector interface.
|
||||
@ -404,7 +401,9 @@ public interface VaultConnector extends AutoCloseable, Serializable {
|
||||
* @param key Secret identifier
|
||||
* @return Secret response
|
||||
* @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 {
|
||||
return read(PATH_SECRET + "/" + key);
|
||||
}
|
||||
@ -451,7 +450,9 @@ public interface VaultConnector extends AutoCloseable, Serializable {
|
||||
* @return Metadata for the created/updated secret.
|
||||
* @throws VaultConnectorException on error
|
||||
* @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 {
|
||||
return writeSecretData(PATH_SECRET, key, data, null);
|
||||
}
|
||||
@ -500,7 +501,9 @@ public interface VaultConnector extends AutoCloseable, Serializable {
|
||||
* @return Secret response
|
||||
* @throws VaultConnectorException on error
|
||||
* @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 {
|
||||
return readSecretVersion(PATH_SECRET, key, version);
|
||||
}
|
||||
@ -529,7 +532,9 @@ public interface VaultConnector extends AutoCloseable, Serializable {
|
||||
* @return Metadata response
|
||||
* @throws VaultConnectorException on error
|
||||
* @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 {
|
||||
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.
|
||||
* @throws VaultConnectorException on error
|
||||
* @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 {
|
||||
updateSecretMetadata(PATH_SECRET, key, maxVersions, casRequired);
|
||||
}
|
||||
@ -597,7 +604,9 @@ public interface VaultConnector extends AutoCloseable, Serializable {
|
||||
* @param path Root path to search
|
||||
* @return List of secret keys
|
||||
* @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 {
|
||||
return list(PATH_SECRET + "/" + path);
|
||||
}
|
||||
@ -611,9 +620,7 @@ public interface VaultConnector extends AutoCloseable, Serializable {
|
||||
* @since 0.5.0
|
||||
*/
|
||||
default void write(final String key, final String value) throws VaultConnectorException {
|
||||
Map<String, Object> param = new HashMap<>();
|
||||
param.put("value", value);
|
||||
write(key, param);
|
||||
write(key, Collections.singletonMap("value", value));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -647,11 +654,11 @@ public interface VaultConnector extends AutoCloseable, Serializable {
|
||||
* @param key Secret path
|
||||
* @param value Secret value
|
||||
* @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 {
|
||||
Map<String, Object> param = new HashMap<>();
|
||||
param.put("value", value);
|
||||
writeSecret(key, param);
|
||||
writeSecret(key, Collections.singletonMap("value", value));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -663,7 +670,9 @@ public interface VaultConnector extends AutoCloseable, Serializable {
|
||||
* @param data Secret content. Value must be be JSON serializable.
|
||||
* @throws VaultConnectorException on error
|
||||
* @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 {
|
||||
if (key == null || key.isEmpty()) {
|
||||
throw new InvalidRequestException("Secret path must not be empty.");
|
||||
@ -687,7 +696,9 @@ public interface VaultConnector extends AutoCloseable, Serializable {
|
||||
*
|
||||
* @param key Secret path
|
||||
* @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 {
|
||||
delete(PATH_SECRET + "/" + key);
|
||||
}
|
||||
@ -700,7 +711,9 @@ public interface VaultConnector extends AutoCloseable, Serializable {
|
||||
* @param key Secret path.
|
||||
* @throws VaultConnectorException on error
|
||||
* @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 {
|
||||
deleteLatestSecretVersion(PATH_SECRET, key);
|
||||
}
|
||||
@ -726,7 +739,9 @@ public interface VaultConnector extends AutoCloseable, Serializable {
|
||||
* @param key Secret path.
|
||||
* @throws VaultConnectorException on error
|
||||
* @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 {
|
||||
deleteAllSecretVersions(PATH_SECRET, key);
|
||||
}
|
||||
@ -753,7 +768,9 @@ public interface VaultConnector extends AutoCloseable, Serializable {
|
||||
* @param versions Versions of the secret to delete.
|
||||
* @throws VaultConnectorException on error
|
||||
* @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 {
|
||||
deleteSecretVersions(PATH_SECRET, key, versions);
|
||||
}
|
||||
@ -779,7 +796,9 @@ public interface VaultConnector extends AutoCloseable, Serializable {
|
||||
* @param versions Versions of the secret to undelete.
|
||||
* @throws VaultConnectorException on error
|
||||
* @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 {
|
||||
undeleteSecretVersions(PATH_SECRET, key, versions);
|
||||
}
|
||||
@ -804,7 +823,9 @@ public interface VaultConnector extends AutoCloseable, Serializable {
|
||||
* @param versions Versions of the secret to destroy.
|
||||
* @throws VaultConnectorException on error
|
||||
* @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 {
|
||||
destroySecretVersions(PATH_SECRET, key, versions);
|
||||
}
|
||||
|
@ -16,283 +16,17 @@
|
||||
|
||||
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.
|
||||
*
|
||||
* @author Stefan Kalscheuer
|
||||
* @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 {
|
||||
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.
|
||||
*/
|
||||
@Deprecated
|
||||
public class HTTPVaultConnectorBuilder extends de.stklcode.jvault.connector.HTTPVaultConnectorBuilder {
|
||||
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);
|
||||
}
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
package de.stklcode.jvault.connector.builder;
|
||||
|
||||
import de.stklcode.jvault.connector.HTTPVaultConnector;
|
||||
import de.stklcode.jvault.connector.VaultConnector;
|
||||
import de.stklcode.jvault.connector.exception.VaultConnectorException;
|
||||
|
||||
@ -31,7 +32,9 @@ public interface VaultConnectorBuilder {
|
||||
* Get Factory implementation for HTTP Vault Connector.
|
||||
*
|
||||
* @return HTTP Connector Factory
|
||||
* @deprecated Use {@link HTTPVaultConnector#builder()} instead. This interface will be removed in 1.0
|
||||
*/
|
||||
@Deprecated
|
||||
static HTTPVaultConnectorBuilder http() {
|
||||
return new HTTPVaultConnectorBuilder();
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ public abstract class VaultConnectorException extends 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
|
||||
*/
|
||||
public VaultConnectorException(final String message) {
|
||||
protected VaultConnectorException(final String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
@ -43,7 +43,7 @@ public abstract class VaultConnectorException extends Exception {
|
||||
*
|
||||
* @param cause the cause
|
||||
*/
|
||||
public VaultConnectorException(final Throwable cause) {
|
||||
protected VaultConnectorException(final Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
@ -53,7 +53,7 @@ public abstract class VaultConnectorException extends Exception {
|
||||
* @param message the detail message
|
||||
* @param cause the cause
|
||||
*/
|
||||
public VaultConnectorException(final String message, final Throwable cause) {
|
||||
protected VaultConnectorException(final String message, final Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
package de.stklcode.jvault.connector.factory;
|
||||
|
||||
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 javax.net.ssl.SSLContext;
|
||||
|
@ -703,21 +703,34 @@ public final class AppRole {
|
||||
* @return self
|
||||
* @since 0.9
|
||||
*/
|
||||
public Builder wit0hTokenPeriod(final Integer tokenPeriod) {
|
||||
public Builder withTokenPeriod(final Integer tokenPeriod) {
|
||||
this.tokenPeriod = tokenPeriod;
|
||||
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.
|
||||
*
|
||||
* @param period period in seconds
|
||||
* @return self
|
||||
* @deprecated Use {@link #wit0hTokenPeriod(Integer)} instead.
|
||||
* @deprecated Use {@link #withTokenPeriod(Integer)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public Builder withPeriod(final Integer period) {
|
||||
return wit0hTokenPeriod(period);
|
||||
return withTokenPeriod(period);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -308,21 +308,34 @@ public final class AppRoleBuilder {
|
||||
* @return self
|
||||
* @since 0.9
|
||||
*/
|
||||
public AppRoleBuilder wit0hTokenPeriod(final Integer tokenPeriod) {
|
||||
public AppRoleBuilder withTokenPeriod(final Integer tokenPeriod) {
|
||||
this.tokenPeriod = tokenPeriod;
|
||||
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.
|
||||
*
|
||||
* @param period period in seconds
|
||||
* @return self
|
||||
* @deprecated Use {@link #wit0hTokenPeriod(Integer)} instead.
|
||||
* @deprecated Use {@link #withTokenPeriod(Integer)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public AppRoleBuilder withPeriod(final Integer period) {
|
||||
return wit0hTokenPeriod(period);
|
||||
return withTokenPeriod(period);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -40,7 +40,7 @@ public final class AppRoleResponse extends VaultDataResponse {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
try {
|
||||
/* 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) -> {
|
||||
if (!(v instanceof String && ((String) v).isEmpty())) {
|
||||
filteredData.put(k, v);
|
||||
|
@ -40,7 +40,7 @@ public final class AppRoleSecretResponse extends VaultDataResponse {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
try {
|
||||
/* 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) -> {
|
||||
if (!(v instanceof String && ((String) v).isEmpty())) {
|
||||
filteredData.put(k, v);
|
||||
|
@ -22,7 +22,7 @@ import de.stklcode.jvault.connector.exception.InvalidResponseException;
|
||||
import de.stklcode.jvault.connector.model.response.embedded.VersionMetadata;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@ -66,7 +66,7 @@ public class SecretResponse extends VaultDataResponse {
|
||||
*/
|
||||
public final Map<String, Object> getData() {
|
||||
if (data == null) {
|
||||
return new HashMap<>();
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
@ -20,9 +20,6 @@ import de.stklcode.jvault.connector.exception.InvalidRequestException;
|
||||
import de.stklcode.jvault.connector.exception.InvalidResponseException;
|
||||
import de.stklcode.jvault.connector.exception.PermissionDeniedException;
|
||||
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.client.methods.CloseableHttpResponse;
|
||||
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.HttpClientBuilder;
|
||||
import org.apache.http.message.BasicStatusLine;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.*;
|
||||
import org.junit.jupiter.api.function.Executable;
|
||||
import org.mockito.MockedStatic;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@ -42,13 +39,12 @@ import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.X509Certificate;
|
||||
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.nullValue;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
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.Mockito.*;
|
||||
|
||||
@ -59,79 +55,68 @@ import static org.mockito.Mockito.*;
|
||||
* @author Stefan Kalscheuer
|
||||
* @since 0.7.0
|
||||
*/
|
||||
public class HTTPVaultConnectorOfflineTest {
|
||||
class HTTPVaultConnectorOfflineTest {
|
||||
private static final String INVALID_URL = "foo:/\\1nv4l1d_UrL";
|
||||
|
||||
private static CloseableHttpClient httpMock = mock(CloseableHttpClient.class);
|
||||
private CloseableHttpResponse responseMock = mock(CloseableHttpResponse.class);
|
||||
private static MockedStatic<HttpClientBuilder> hcbMock;
|
||||
private static CloseableHttpClient httpMock;
|
||||
private final CloseableHttpResponse responseMock = mock(CloseableHttpResponse.class);
|
||||
|
||||
@BeforeAll
|
||||
public static void initByteBuddy() {
|
||||
// Install ByteBuddy Agent.
|
||||
ByteBuddyAgent.install();
|
||||
static void prepare() {
|
||||
// Mock the static HTTPClient creation.
|
||||
hcbMock = mockStatic(HttpClientBuilder.class);
|
||||
hcbMock.when(HttpClientBuilder::create).thenReturn(new MockedHttpClientBuilder());
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method for redefinition of {@link HttpClientBuilder#create()} from {@link #initHttpMock()}.
|
||||
*
|
||||
* @return Mocked HTTP client builder.
|
||||
*/
|
||||
public static HttpClientBuilder create() {
|
||||
return new MockedHttpClientBuilder();
|
||||
}
|
||||
@AfterAll
|
||||
static void tearDown() {
|
||||
hcbMock.close();
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
public void initHttpMock() {
|
||||
// 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());
|
||||
|
||||
void init() {
|
||||
// Re-initialize HTTP mock to ensure fresh (empty) results.
|
||||
httpMock = mock(CloseableHttpClient.class);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test exceptions thrown during request.
|
||||
*/
|
||||
@Test
|
||||
public void requestExceptionTest() throws IOException {
|
||||
void requestExceptionTest() throws IOException {
|
||||
HTTPVaultConnector connector = new HTTPVaultConnector("http://127.0.0.1", null, 0, 250);
|
||||
|
||||
// Test invalid response code.
|
||||
final int responseCode = 400;
|
||||
mockResponse(responseCode, "", ContentType.APPLICATION_JSON);
|
||||
try {
|
||||
connector.getHealth();
|
||||
fail("Querying health status succeeded on invalid instance");
|
||||
} catch (Exception e) {
|
||||
assertThat("Unexpected type of exception", e, instanceOf(InvalidResponseException.class));
|
||||
assertThat("Unexpected exception message", e.getMessage(), is("Invalid response code"));
|
||||
assertThat("Unexpected status code in exception", ((InvalidResponseException) e).getStatusCode(), is(responseCode));
|
||||
assertThat("Response message where none was expected", ((InvalidResponseException) e).getResponse(), is(nullValue()));
|
||||
}
|
||||
InvalidResponseException e = assertThrows(
|
||||
InvalidResponseException.class,
|
||||
connector::getHealth,
|
||||
"Querying health status succeeded on invalid instance"
|
||||
);
|
||||
assertThat("Unexpected exception message", e.getMessage(), is("Invalid response code"));
|
||||
assertThat("Unexpected status code in exception", ((InvalidResponseException) e).getStatusCode(), is(responseCode));
|
||||
assertThat("Response message where none was expected", ((InvalidResponseException) e).getResponse(), is(nullValue()));
|
||||
|
||||
// Simulate permission denied response.
|
||||
mockResponse(responseCode, "{\"errors\":[\"permission denied\"]}", ContentType.APPLICATION_JSON);
|
||||
try {
|
||||
connector.getHealth();
|
||||
fail("Querying health status succeeded on invalid instance");
|
||||
} catch (Exception e) {
|
||||
assertThat("Unexpected type of exception", e, instanceOf(PermissionDeniedException.class));
|
||||
}
|
||||
assertThrows(
|
||||
PermissionDeniedException.class,
|
||||
connector::getHealth,
|
||||
"Querying health status succeeded on invalid instance"
|
||||
);
|
||||
|
||||
// Test exception thrown during request.
|
||||
when(httpMock.execute(any())).thenThrow(new IOException("Test Exception"));
|
||||
try {
|
||||
connector.getHealth();
|
||||
fail("Querying health status succeeded on invalid instance");
|
||||
} catch (Exception e) {
|
||||
assertThat("Unexpected type of exception", e, instanceOf(InvalidResponseException.class));
|
||||
assertThat("Unexpected exception message", e.getMessage(), is("Unable to read response"));
|
||||
assertThat("Unexpected cause", e.getCause(), instanceOf(IOException.class));
|
||||
}
|
||||
e = assertThrows(
|
||||
InvalidResponseException.class,
|
||||
connector::getHealth,
|
||||
"Querying health status succeeded on invalid instance"
|
||||
);
|
||||
assertThat("Unexpected exception message", e.getMessage(), is("Unable to read response"));
|
||||
assertThat("Unexpected cause", e.getCause(), instanceOf(IOException.class));
|
||||
|
||||
// Now simulate a failing request that succeeds on second try.
|
||||
connector = new HTTPVaultConnector("https://127.0.0.1", null, 1, 250);
|
||||
@ -143,18 +128,14 @@ public class HTTPVaultConnectorOfflineTest {
|
||||
.when(responseMock).getStatusLine();
|
||||
when(responseMock.getEntity()).thenReturn(new StringEntity("{}", ContentType.APPLICATION_JSON));
|
||||
|
||||
try {
|
||||
connector.getHealth();
|
||||
} catch (Exception e) {
|
||||
fail("Request failed unexpectedly: " + e.getMessage());
|
||||
}
|
||||
assertDoesNotThrow(connector::getHealth, "Request failed unexpectedly");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test constructors of the {@link HTTPVaultConnector} class.
|
||||
*/
|
||||
@Test
|
||||
public void constructorTest() throws IOException, CertificateException {
|
||||
void constructorTest() throws IOException, CertificateException {
|
||||
final String url = "https://vault.example.net/test/";
|
||||
final String hostname = "vault.example.com";
|
||||
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.
|
||||
*/
|
||||
@Test
|
||||
public void sealExceptionTest() throws IOException {
|
||||
void sealExceptionTest() {
|
||||
HTTPVaultConnector connector = new HTTPVaultConnector(INVALID_URL);
|
||||
try {
|
||||
connector.sealStatus();
|
||||
fail("Querying seal status succeeded on invalid URL");
|
||||
} catch (Exception e) {
|
||||
assertThat("Unexpected type of exception", e, instanceOf(InvalidRequestException.class));
|
||||
assertThat("Unexpected exception message", e.getMessage(), is("Invalid URI format"));
|
||||
}
|
||||
|
||||
connector = new HTTPVaultConnector("https://127.0.0.1", null, 0, 250);
|
||||
VaultConnectorException e = assertThrows(
|
||||
InvalidRequestException.class,
|
||||
connector::sealStatus,
|
||||
"Querying seal status succeeded on invalid URL"
|
||||
);
|
||||
assertThat("Unexpected exception message", e.getMessage(), is("Invalid URI format"));
|
||||
|
||||
// Simulate NULL response (mock not supplied with data).
|
||||
|
||||
try {
|
||||
connector.sealStatus();
|
||||
fail("Querying seal status succeeded on invalid instance");
|
||||
} catch (Exception e) {
|
||||
assertThat("Unexpected type of exception", e, instanceOf(InvalidResponseException.class));
|
||||
assertThat("Unexpected exception message", e.getMessage(), is("Response unavailable"));
|
||||
}
|
||||
connector = new HTTPVaultConnector("https://127.0.0.1", null, 0, 250);
|
||||
e = assertThrows(
|
||||
InvalidResponseException.class,
|
||||
connector::sealStatus,
|
||||
"Querying seal status succeeded on invalid instance"
|
||||
);
|
||||
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.
|
||||
*/
|
||||
@Test
|
||||
public void healthExceptionTest() throws IOException {
|
||||
void healthExceptionTest() {
|
||||
HTTPVaultConnector connector = new HTTPVaultConnector(INVALID_URL);
|
||||
try {
|
||||
connector.getHealth();
|
||||
fail("Querying health status succeeded on invalid URL");
|
||||
} catch (Exception e) {
|
||||
assertThat("Unexpected type of exception", e, instanceOf(InvalidRequestException.class));
|
||||
assertThat("Unexpected exception message", e.getMessage(), is("Invalid URI format"));
|
||||
}
|
||||
|
||||
connector = new HTTPVaultConnector("https://127.0.0.1", null, 0, 250);
|
||||
VaultConnectorException e = assertThrows(
|
||||
InvalidRequestException.class,
|
||||
connector::getHealth,
|
||||
"Querying health status succeeded on invalid URL"
|
||||
);
|
||||
assertThat("Unexpected exception message", e.getMessage(), is("Invalid URI format"));
|
||||
|
||||
// Simulate NULL response (mock not supplied with data).
|
||||
try {
|
||||
connector.getHealth();
|
||||
fail("Querying health status succeeded on invalid instance");
|
||||
} catch (Exception e) {
|
||||
assertThat("Unexpected type of exception", e, instanceOf(InvalidResponseException.class));
|
||||
assertThat("Unexpected exception message", e.getMessage(), is("Response unavailable"));
|
||||
}
|
||||
connector = new HTTPVaultConnector("https://127.0.0.1", null, 0, 250);
|
||||
e = assertThrows(
|
||||
InvalidResponseException.class,
|
||||
connector::getHealth,
|
||||
"Querying health status succeeded on invalid instance"
|
||||
);
|
||||
assertThat("Unexpected exception message", e.getMessage(), is("Response unavailable"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test behavior on unparsable responses.
|
||||
*/
|
||||
@Test
|
||||
public void parseExceptionTest() throws IOException {
|
||||
void parseExceptionTest() throws IOException {
|
||||
HTTPVaultConnector connector = new HTTPVaultConnector("https://127.0.0.1", null, 0, 250);
|
||||
// Mock authorization.
|
||||
setPrivate(connector, "authorized", true);
|
||||
@ -267,114 +241,25 @@ public class HTTPVaultConnectorOfflineTest {
|
||||
mockResponse(200, "invalid", ContentType.APPLICATION_JSON);
|
||||
|
||||
// Now test the methods.
|
||||
try {
|
||||
connector.sealStatus();
|
||||
fail("sealStatus() succeeded on invalid instance");
|
||||
} catch (Exception e) {
|
||||
assertParseError(e);
|
||||
}
|
||||
|
||||
try {
|
||||
connector.unseal("key");
|
||||
fail("unseal() succeeded on invalid instance");
|
||||
} catch (Exception e) {
|
||||
assertParseError(e);
|
||||
}
|
||||
|
||||
try {
|
||||
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);
|
||||
}
|
||||
assertParseError(connector::sealStatus, "sealStatus() succeeded on invalid instance");
|
||||
assertParseError(() -> connector.unseal("key"), "unseal() succeeded on invalid instance");
|
||||
assertParseError(connector::getHealth, "getHealth() succeeded on invalid instance");
|
||||
assertParseError(connector::getAuthBackends, "getAuthBackends() succeeded on invalid instance");
|
||||
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");
|
||||
assertParseError(() -> connector.createAppRoleSecret("roleName"), "createAppRoleSecret() succeeded on invalid instance");
|
||||
assertParseError(() -> connector.lookupAppRoleSecret("roleName", "secretID"), "lookupAppRoleSecret() succeeded on invalid instance");
|
||||
assertParseError(connector::listAppRoles, "listAppRoles() succeeded on invalid instance");
|
||||
assertParseError(() -> connector.listAppRoleSecrets("roleName"), "listAppRoleSecrets() succeeded on invalid instance");
|
||||
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");
|
||||
assertParseError(() -> connector.lookupToken("token"), "lookupToken() succeeded on invalid instance");
|
||||
}
|
||||
|
||||
private void assertParseError(Exception e) {
|
||||
assertThat("Unexpected type of exception", e, instanceOf(InvalidResponseException.class));
|
||||
private void assertParseError(Executable executable, String message) {
|
||||
InvalidResponseException e = assertThrows(InvalidResponseException.class, executable, message);
|
||||
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
|
||||
public void nonEmpty204ResponseTest() throws IOException {
|
||||
void nonEmpty204ResponseTest() throws IOException {
|
||||
HTTPVaultConnector connector = new HTTPVaultConnector("https://127.0.0.1", null, 0, 250);
|
||||
// Mock authorization.
|
||||
setPrivate(connector, "authorized", true);
|
||||
@ -390,71 +275,62 @@ public class HTTPVaultConnectorOfflineTest {
|
||||
mockResponse(200, "{}", ContentType.APPLICATION_JSON);
|
||||
|
||||
// Now test the methods expecting a 204.
|
||||
try {
|
||||
connector.registerAppId("appID", "policy", "displayName");
|
||||
fail("registerAppId() with 200 response succeeded");
|
||||
} catch (VaultConnectorException e) {
|
||||
assertThat("Unexpected exception type", e, instanceOf(InvalidResponseException.class));
|
||||
}
|
||||
assertThrows(
|
||||
InvalidResponseException.class,
|
||||
() -> connector.registerAppId("appID", "policy", "displayName"),
|
||||
"registerAppId() with 200 response succeeded"
|
||||
);
|
||||
|
||||
try {
|
||||
connector.registerUserId("appID", "userID");
|
||||
fail("registerUserId() with 200 response succeeded");
|
||||
} catch (VaultConnectorException e) {
|
||||
assertThat("Unexpected exception type", e, instanceOf(InvalidResponseException.class));
|
||||
}
|
||||
assertThrows(
|
||||
InvalidResponseException.class,
|
||||
() -> connector.registerUserId("appID", "userID"),
|
||||
"registerUserId() with 200 response succeeded"
|
||||
);
|
||||
|
||||
try {
|
||||
connector.createAppRole("appID", Collections.singletonList("policy"));
|
||||
fail("createAppRole() with 200 response succeeded");
|
||||
} catch (VaultConnectorException e) {
|
||||
assertThat("Unexpected exception type", e, instanceOf(InvalidResponseException.class));
|
||||
}
|
||||
assertThrows(
|
||||
InvalidResponseException.class,
|
||||
() -> connector.createAppRole("appID", Collections.singletonList("policy")),
|
||||
"createAppRole() with 200 response succeeded"
|
||||
);
|
||||
|
||||
try {
|
||||
connector.deleteAppRole("roleName");
|
||||
fail("deleteAppRole() with 200 response succeeded");
|
||||
} catch (VaultConnectorException e) {
|
||||
assertThat("Unexpected exception type", e, instanceOf(InvalidResponseException.class));
|
||||
}
|
||||
assertThrows(
|
||||
InvalidResponseException.class,
|
||||
() -> connector.deleteAppRole("roleName"),
|
||||
"deleteAppRole() with 200 response succeeded"
|
||||
);
|
||||
|
||||
try {
|
||||
connector.setAppRoleID("roleName", "roleID");
|
||||
fail("setAppRoleID() with 200 response succeeded");
|
||||
} catch (VaultConnectorException e) {
|
||||
assertThat("Unexpected exception type", e, instanceOf(InvalidResponseException.class));
|
||||
}
|
||||
assertThrows(
|
||||
InvalidResponseException.class,
|
||||
() -> connector.setAppRoleID("roleName", "roleID"),
|
||||
"setAppRoleID() with 200 response succeeded"
|
||||
);
|
||||
|
||||
try {
|
||||
connector.destroyAppRoleSecret("roleName", "secretID");
|
||||
fail("destroyAppRoleSecret() with 200 response succeeded");
|
||||
} catch (VaultConnectorException e) {
|
||||
assertThat("Unexpected exception type", e, instanceOf(InvalidResponseException.class));
|
||||
}
|
||||
assertThrows(
|
||||
InvalidResponseException.class,
|
||||
() -> connector.destroyAppRoleSecret("roleName", "secretID"),
|
||||
"destroyAppRoleSecret() with 200 response succeeded"
|
||||
);
|
||||
|
||||
try {
|
||||
connector.destroyAppRoleSecret("roleName", "secretUD");
|
||||
fail("destroyAppRoleSecret() with 200 response succeeded");
|
||||
} catch (VaultConnectorException e) {
|
||||
assertThat("Unexpected exception type", e, instanceOf(InvalidResponseException.class));
|
||||
}
|
||||
assertThrows(
|
||||
InvalidResponseException.class,
|
||||
() -> connector.destroyAppRoleSecret("roleName", "secretUD"),
|
||||
"destroyAppRoleSecret() with 200 response succeeded"
|
||||
);
|
||||
|
||||
try {
|
||||
connector.delete("key");
|
||||
fail("delete() with 200 response succeeded");
|
||||
} catch (VaultConnectorException e) {
|
||||
assertThat("Unexpected exception type", e, instanceOf(InvalidResponseException.class));
|
||||
}
|
||||
assertThrows(
|
||||
InvalidResponseException.class,
|
||||
() -> connector.delete("key"),
|
||||
"delete() with 200 response succeeded"
|
||||
);
|
||||
|
||||
try {
|
||||
connector.revoke("leaseID");
|
||||
fail("destroyAppRoleSecret() with 200 response succeeded");
|
||||
} catch (VaultConnectorException e) {
|
||||
assertThat("Unexpected exception type", e, instanceOf(InvalidResponseException.class));
|
||||
}
|
||||
assertThrows(
|
||||
InvalidResponseException.class,
|
||||
() -> connector.revoke("leaseID"),
|
||||
"destroyAppRoleSecret() with 200 response succeeded"
|
||||
);
|
||||
}
|
||||
|
||||
private Object getRequestHelperPrivate(HTTPVaultConnector connector, String fieldName) {
|
||||
private Object getRequestHelperPrivate(HTTPVaultConnector connector, String fieldName) {
|
||||
try {
|
||||
return getPrivate(getPrivate(connector, "request"), fieldName);
|
||||
} catch (NoSuchFieldException | IllegalAccessException e) {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -16,21 +16,22 @@
|
||||
|
||||
package de.stklcode.jvault.connector.builder;
|
||||
|
||||
import com.github.stefanbirkner.systemlambda.SystemLambda;
|
||||
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.VaultConnectorException;
|
||||
import de.stklcode.jvault.connector.test.EnvironmentMock;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.nio.file.NoSuchFileException;
|
||||
|
||||
import static com.github.stefanbirkner.systemlambda.SystemLambda.withEnvironmentVariable;
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
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
|
||||
@ -38,7 +39,7 @@ import static org.junit.jupiter.api.Assertions.fail;
|
||||
* @author Stefan Kalscheuer
|
||||
* @since 0.8.0
|
||||
*/
|
||||
public class HTTPVaultConnectorBuilderTest {
|
||||
class HTTPVaultConnectorBuilderTest {
|
||||
private static final String VAULT_ADDR = "https://localhost:8201";
|
||||
private static final Integer VAULT_MAX_RETRIES = 13;
|
||||
private static final String VAULT_TOKEN = "00001111-2222-3333-4444-555566667777";
|
||||
@ -50,66 +51,68 @@ public class HTTPVaultConnectorBuilderTest {
|
||||
* Test building from environment variables
|
||||
*/
|
||||
@Test
|
||||
void testFromEnv() throws NoSuchFieldException, IllegalAccessException, IOException {
|
||||
void testFromEnv() throws Exception {
|
||||
/* 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;
|
||||
HTTPVaultConnector connector;
|
||||
try {
|
||||
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/")));
|
||||
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));
|
||||
|
||||
assertThat("URL nor set correctly", getRequestHelperPrivate(connector, "baseURL"), is(equalTo(VAULT_ADDR + "/v1/")));
|
||||
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));
|
||||
return null;
|
||||
});
|
||||
|
||||
/* 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 {
|
||||
factory = VaultConnectorBuilder.http().fromEnv();
|
||||
} catch (VaultConnectorException e) {
|
||||
fail("Factory creation from environment failed");
|
||||
}
|
||||
connector = factory.build();
|
||||
assertThat("URL nor set correctly", getRequestHelperPrivate(connector, "baseURL"), is(equalTo(VAULT_ADDR + "/v1/")));
|
||||
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));
|
||||
|
||||
assertThat("URL nor set correctly", getRequestHelperPrivate(connector, "baseURL"), is(equalTo(VAULT_ADDR + "/v1/")));
|
||||
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));
|
||||
return null;
|
||||
});
|
||||
|
||||
/* Provide CA certificate */
|
||||
String VAULT_CACERT = tempDir.toString() + "/doesnotexist";
|
||||
setenv(VAULT_ADDR, VAULT_CACERT, VAULT_MAX_RETRIES.toString(), null);
|
||||
|
||||
try {
|
||||
VaultConnectorBuilder.http().fromEnv();
|
||||
fail("Creation with unknown cert path failed.");
|
||||
} catch (VaultConnectorException e) {
|
||||
assertThat(e, is(instanceOf(TlsException.class)));
|
||||
withVaultEnv(VAULT_ADDR, VAULT_CACERT, VAULT_MAX_RETRIES.toString(), null).execute(() -> {
|
||||
TlsException e = assertThrows(
|
||||
TlsException.class,
|
||||
() -> HTTPVaultConnector.builder().fromEnv(),
|
||||
"Creation with unknown cert path failed."
|
||||
);
|
||||
assertThat(e.getCause(), is(instanceOf(NoSuchFileException.class)));
|
||||
assertThat(((NoSuchFileException) e.getCause()).getFile(), is(VAULT_CACERT));
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
|
||||
/* 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 {
|
||||
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)));
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
private void setenv(String vault_addr, String vault_cacert, String vault_max_retries, String vault_token) {
|
||||
EnvironmentMock.setenv("VAULT_ADDR", vault_addr);
|
||||
EnvironmentMock.setenv("VAULT_CACERT", vault_cacert);
|
||||
EnvironmentMock.setenv("VAULT_MAX_RETRIES", vault_max_retries);
|
||||
EnvironmentMock.setenv("VAULT_TOKEN", vault_token);
|
||||
private SystemLambda.WithEnvironmentVariables withVaultEnv(String vault_addr, String vault_cacert, String vault_max_retries, String vault_token) {
|
||||
return withEnvironmentVariable("VAULT_ADDR", vault_addr)
|
||||
.and("VAULT_CACERT", vault_cacert)
|
||||
.and("VAULT_MAX_RETRIES", vault_max_retries)
|
||||
.and("VAULT_TOKEN", vault_token);
|
||||
}
|
||||
|
||||
private Object getRequestHelperPrivate(HTTPVaultConnector connector, String fieldName) throws NoSuchFieldException, IllegalAccessException {
|
||||
|
@ -29,19 +29,19 @@ import static org.hamcrest.core.Is.is;
|
||||
* @author Stefan Kalscheuer
|
||||
* @since 0.6.2
|
||||
*/
|
||||
public class VaultConnectorExceptionTest {
|
||||
class VaultConnectorExceptionTest {
|
||||
private static final String MSG = "This is a test exception!";
|
||||
private static final Throwable CAUSE = new Exception("Test-Cause");
|
||||
private static final Integer STATUS_CODE = 1337;
|
||||
private static final String RESPONSE = "Dummy response";
|
||||
|
||||
@Test
|
||||
public void authorizationRequiredExceptionTest() {
|
||||
void authorizationRequiredExceptionTest() {
|
||||
assertEmptyConstructor(new AuthorizationRequiredException());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void connectionExceptionTest() {
|
||||
void connectionExceptionTest() {
|
||||
assertEmptyConstructor(new ConnectionException());
|
||||
assertMsgConstructor(new ConnectionException(MSG));
|
||||
assertCauseConstructor(new ConnectionException(CAUSE));
|
||||
@ -49,7 +49,7 @@ public class VaultConnectorExceptionTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invalidRequestExceptionTest() {
|
||||
void invalidRequestExceptionTest() {
|
||||
assertEmptyConstructor(new InvalidRequestException());
|
||||
assertMsgConstructor(new InvalidRequestException(MSG));
|
||||
assertCauseConstructor(new InvalidRequestException(CAUSE));
|
||||
@ -57,7 +57,7 @@ public class VaultConnectorExceptionTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invalidResponseExceptionTest() {
|
||||
void invalidResponseExceptionTest() {
|
||||
assertEmptyConstructor(new InvalidResponseException());
|
||||
assertMsgConstructor(new InvalidResponseException(MSG));
|
||||
assertCauseConstructor(new InvalidResponseException(CAUSE));
|
||||
@ -93,7 +93,7 @@ public class VaultConnectorExceptionTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void permissionDeniedExceptionTest() {
|
||||
void permissionDeniedExceptionTest() {
|
||||
// Default message overwritten.
|
||||
PermissionDeniedException e = new PermissionDeniedException();
|
||||
assertThat(e, is(instanceOf(VaultConnectorException.class)));
|
||||
@ -108,7 +108,7 @@ public class VaultConnectorExceptionTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void tlsExceptionTest() {
|
||||
void tlsExceptionTest() {
|
||||
assertEmptyConstructor(new TlsException());
|
||||
assertMsgConstructor(new TlsException(MSG));
|
||||
assertCauseConstructor(new TlsException(CAUSE));
|
||||
|
@ -16,21 +16,21 @@
|
||||
|
||||
package de.stklcode.jvault.connector.factory;
|
||||
|
||||
import com.github.stefanbirkner.systemlambda.SystemLambda;
|
||||
import de.stklcode.jvault.connector.HTTPVaultConnector;
|
||||
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.io.TempDir;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.nio.file.NoSuchFileException;
|
||||
|
||||
import static com.github.stefanbirkner.systemlambda.SystemLambda.withEnvironmentVariable;
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
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
|
||||
@ -38,7 +38,7 @@ import static org.junit.jupiter.api.Assertions.fail;
|
||||
* @author Stefan Kalscheuer
|
||||
* @since 0.6.0
|
||||
*/
|
||||
public class HTTPVaultConnectorFactoryTest {
|
||||
class HTTPVaultConnectorFactoryTest {
|
||||
private static String VAULT_ADDR = "https://localhost:8201";
|
||||
private static Integer VAULT_MAX_RETRIES = 13;
|
||||
private static String VAULT_TOKEN = "00001111-2222-3333-4444-555566667777";
|
||||
@ -50,66 +50,68 @@ public class HTTPVaultConnectorFactoryTest {
|
||||
* Test building from environment variables
|
||||
*/
|
||||
@Test
|
||||
public void testFromEnv() throws NoSuchFieldException, IllegalAccessException, IOException {
|
||||
void testFromEnv() throws Exception {
|
||||
/* 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;
|
||||
HTTPVaultConnector connector;
|
||||
try {
|
||||
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/")));
|
||||
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));
|
||||
|
||||
assertThat("URL nor set correctly", getRequestHelperPrivate(connector, "baseURL"), is(equalTo(VAULT_ADDR + "/v1/")));
|
||||
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));
|
||||
return null;
|
||||
});
|
||||
|
||||
/* 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 {
|
||||
factory = VaultConnectorFactory.httpFactory().fromEnv();
|
||||
} catch (VaultConnectorException e) {
|
||||
fail("Factory creation from environment failed");
|
||||
}
|
||||
connector = factory.build();
|
||||
assertThat("URL nor set correctly", getRequestHelperPrivate(connector, "baseURL"), is(equalTo(VAULT_ADDR + "/v1/")));
|
||||
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));
|
||||
|
||||
assertThat("URL nor set correctly", getRequestHelperPrivate(connector, "baseURL"), is(equalTo(VAULT_ADDR + "/v1/")));
|
||||
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));
|
||||
return null;
|
||||
});
|
||||
|
||||
/* Provide CA certificate */
|
||||
String VAULT_CACERT = tempDir.toString() + "/doesnotexist";
|
||||
setenv(VAULT_ADDR, VAULT_CACERT, VAULT_MAX_RETRIES.toString(), null);
|
||||
|
||||
try {
|
||||
VaultConnectorFactory.httpFactory().fromEnv();
|
||||
fail("Creation with unknown cert path failed.");
|
||||
} catch (VaultConnectorException e) {
|
||||
assertThat(e, is(instanceOf(TlsException.class)));
|
||||
withVaultEnv(VAULT_ADDR, VAULT_CACERT, VAULT_MAX_RETRIES.toString(), null).execute(() -> {
|
||||
TlsException e = assertThrows(
|
||||
TlsException.class,
|
||||
() -> VaultConnectorFactory.httpFactory().fromEnv(),
|
||||
"Creation with unknown cert path failed."
|
||||
);
|
||||
assertThat(e.getCause(), is(instanceOf(NoSuchFileException.class)));
|
||||
assertThat(((NoSuchFileException) e.getCause()).getFile(), is(VAULT_CACERT));
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
|
||||
/* 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 {
|
||||
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)));
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
private void setenv(String vault_addr, String vault_cacert, String vault_max_retries, String vault_token) {
|
||||
EnvironmentMock.setenv("VAULT_ADDR", vault_addr);
|
||||
EnvironmentMock.setenv("VAULT_CACERT", vault_cacert);
|
||||
EnvironmentMock.setenv("VAULT_MAX_RETRIES", vault_max_retries);
|
||||
EnvironmentMock.setenv("VAULT_TOKEN", vault_token);
|
||||
private SystemLambda.WithEnvironmentVariables withVaultEnv(String vault_addr, String vault_cacert, String vault_max_retries, String vault_token) {
|
||||
return withEnvironmentVariable("VAULT_ADDR", vault_addr)
|
||||
.and("VAULT_CACERT", vault_cacert)
|
||||
.and("VAULT_MAX_RETRIES", vault_max_retries)
|
||||
.and("VAULT_TOKEN", vault_token);
|
||||
}
|
||||
|
||||
private Object getRequestHelperPrivate(HTTPVaultConnector connector, String fieldName) throws NoSuchFieldException, IllegalAccessException {
|
||||
|
@ -33,7 +33,7 @@ import static org.hamcrest.Matchers.*;
|
||||
* @author Stefan Kalscheuer
|
||||
* @since 0.4.0
|
||||
*/
|
||||
public class AppRoleBuilderTest {
|
||||
class AppRoleBuilderTest {
|
||||
private static final String NAME = "TestRole";
|
||||
private static final String ID = "test-id";
|
||||
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());
|
||||
|
||||
@BeforeAll
|
||||
public static void init() {
|
||||
static void init() {
|
||||
BOUND_CIDR_LIST.add(CIDR_1);
|
||||
POLICIES.add(POLICY);
|
||||
}
|
||||
@ -67,7 +67,7 @@ public class AppRoleBuilderTest {
|
||||
* Build role with only a name.
|
||||
*/
|
||||
@Test
|
||||
public void buildDefaultTest() throws JsonProcessingException {
|
||||
void buildDefaultTest() throws JsonProcessingException {
|
||||
AppRole role = AppRole.builder(NAME).build();
|
||||
assertThat(role.getId(), is(nullValue()));
|
||||
assertThat(role.getBindSecretId(), is(nullValue()));
|
||||
@ -95,7 +95,7 @@ public class AppRoleBuilderTest {
|
||||
* Build role with only a name.
|
||||
*/
|
||||
@Test
|
||||
public void legacyBuildDefaultTest() throws JsonProcessingException {
|
||||
void legacyBuildDefaultTest() throws JsonProcessingException {
|
||||
AppRole role = new AppRoleBuilder(NAME).build();
|
||||
assertThat(role.getId(), is(nullValue()));
|
||||
assertThat(role.getBindSecretId(), is(nullValue()));
|
||||
@ -123,7 +123,7 @@ public class AppRoleBuilderTest {
|
||||
* Build token without all parameters set.
|
||||
*/
|
||||
@Test
|
||||
public void buildFullTest() throws JsonProcessingException {
|
||||
void buildFullTest() throws JsonProcessingException {
|
||||
AppRole role = AppRole.builder(NAME)
|
||||
.withId(ID)
|
||||
.withBindSecretID(BIND_SECRET_ID)
|
||||
@ -138,7 +138,7 @@ public class AppRoleBuilderTest {
|
||||
.withTokenExplicitMaxTtl(TOKEN_EXPLICIT_MAX_TTL)
|
||||
.withTokenNoDefaultPolicy(TOKEN_NO_DEFAULT_POLICY)
|
||||
.withTokenNumUses(TOKEN_NUM_USES)
|
||||
.wit0hTokenPeriod(TOKEN_PERIOD)
|
||||
.withTokenPeriod(TOKEN_PERIOD)
|
||||
.withTokenType(TOKEN_TYPE)
|
||||
.build();
|
||||
assertThat(role.getName(), is(NAME));
|
||||
@ -168,7 +168,7 @@ public class AppRoleBuilderTest {
|
||||
* Build token without all parameters set.
|
||||
*/
|
||||
@Test
|
||||
public void legacyBuildFullTest() throws JsonProcessingException {
|
||||
void legacyBuildFullTest() throws JsonProcessingException {
|
||||
AppRole role = new AppRoleBuilder(NAME)
|
||||
.withId(ID)
|
||||
.withBindSecretID(BIND_SECRET_ID)
|
||||
@ -183,7 +183,7 @@ public class AppRoleBuilderTest {
|
||||
.withTokenExplicitMaxTtl(TOKEN_EXPLICIT_MAX_TTL)
|
||||
.withTokenNoDefaultPolicy(TOKEN_NO_DEFAULT_POLICY)
|
||||
.withTokenNumUses(TOKEN_NUM_USES)
|
||||
.wit0hTokenPeriod(TOKEN_PERIOD)
|
||||
.withTokenPeriod(TOKEN_PERIOD)
|
||||
.withTokenType(TOKEN_TYPE)
|
||||
.build();
|
||||
assertThat(role.getName(), is(NAME));
|
||||
@ -213,7 +213,7 @@ public class AppRoleBuilderTest {
|
||||
* Test convenience methods
|
||||
*/
|
||||
@Test
|
||||
public void convenienceMethodsTest() {
|
||||
void convenienceMethodsTest() {
|
||||
/* bind_secret_id */
|
||||
AppRole role = AppRole.builder(NAME).build();
|
||||
assertThat(role.getBindSecretId(), is(nullValue()));
|
||||
@ -257,7 +257,7 @@ public class AppRoleBuilderTest {
|
||||
* Test convenience methods
|
||||
*/
|
||||
@Test
|
||||
public void legacyConvenienceMethodsTest() {
|
||||
void legacyConvenienceMethodsTest() {
|
||||
/* bind_secret_id */
|
||||
AppRole role = new AppRoleBuilder(NAME).build();
|
||||
assertThat(role.getBindSecretId(), is(nullValue()));
|
||||
|
@ -16,11 +16,9 @@
|
||||
|
||||
package de.stklcode.jvault.connector.model;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
@ -29,7 +27,7 @@ import java.util.Map;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
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;
|
||||
|
||||
|
||||
@ -39,7 +37,7 @@ import static org.junit.jupiter.api.Assumptions.assumeTrue;
|
||||
* @author Stefan Kalscheuer
|
||||
* @since 0.5.0
|
||||
*/
|
||||
public class AppRoleSecretTest {
|
||||
class AppRoleSecretTest {
|
||||
|
||||
private static final String TEST_ID = "abc123";
|
||||
private static final Map<String, Object> TEST_META = new HashMap<>();
|
||||
@ -54,7 +52,7 @@ public class AppRoleSecretTest {
|
||||
* Test constructors.
|
||||
*/
|
||||
@Test
|
||||
public void constructorTest() {
|
||||
void constructorTest() {
|
||||
/* Empty constructor */
|
||||
AppRoleSecret secret = new AppRoleSecret();
|
||||
assertThat(secret.getId(), is(nullValue()));
|
||||
@ -99,7 +97,7 @@ public class AppRoleSecretTest {
|
||||
* Test setter.
|
||||
*/
|
||||
@Test
|
||||
public void setterTest() {
|
||||
void setterTest() {
|
||||
AppRoleSecret secret = new AppRoleSecret(TEST_ID);
|
||||
assertThat(secret.getCidrList(), is(nullValue()));
|
||||
assertThat(secret.getCidrListString(), is(emptyString()));
|
||||
@ -115,31 +113,22 @@ public class AppRoleSecretTest {
|
||||
* Test JSON (de)serialization.
|
||||
*/
|
||||
@Test
|
||||
public void jsonTest() throws NoSuchFieldException, IllegalAccessException {
|
||||
void jsonTest() throws NoSuchFieldException, IllegalAccessException {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
/* A simple roundtrip first. All set fields should be present afterwards. */
|
||||
AppRoleSecret secret = new AppRoleSecret(TEST_ID, TEST_META, TEST_CIDR);
|
||||
String secretJson = "";
|
||||
try {
|
||||
secretJson = mapper.writeValueAsString(secret);
|
||||
} catch (JsonProcessingException e) {
|
||||
e.printStackTrace();
|
||||
fail("Serialization failed");
|
||||
}
|
||||
String secretJson = assertDoesNotThrow(() -> mapper.writeValueAsString(secret), "Serialization failed");
|
||||
/* 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;
|
||||
try {
|
||||
secret2 = mapper.readValue(secretJson, AppRoleSecret.class);
|
||||
assertThat(secret.getId(), is(secret2.getId()));
|
||||
assertThat(secret.getMetadata(), is(secret2.getMetadata()));
|
||||
assertThat(secret.getCidrList(), is(secret2.getCidrList()));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
fail("Deserialization failed");
|
||||
}
|
||||
AppRoleSecret secret2 = assertDoesNotThrow(
|
||||
() -> mapper.readValue(secretJson2, AppRoleSecret.class),
|
||||
"Deserialization failed"
|
||||
);
|
||||
assertThat(secret.getId(), is(secret2.getId()));
|
||||
assertThat(secret.getMetadata(), is(secret2.getMetadata()));
|
||||
assertThat(secret.getCidrList(), is(secret2.getCidrList()));
|
||||
|
||||
/* Test fields, that should not be written to JSON */
|
||||
setPrivateField(secret, "accessor", "TEST_ACCESSOR");
|
||||
@ -154,45 +143,33 @@ public class AppRoleSecretTest {
|
||||
assumeTrue(secret.getNumUses() == 678);
|
||||
setPrivateField(secret, "ttl", 12345);
|
||||
assumeTrue(secret.getTtl() == 12345);
|
||||
try {
|
||||
secretJson = mapper.writeValueAsString(secret);
|
||||
} catch (JsonProcessingException e) {
|
||||
e.printStackTrace();
|
||||
fail("Serialization failed");
|
||||
}
|
||||
try {
|
||||
secret2 = mapper.readValue(commaSeparatedToList(secretJson), AppRoleSecret.class);
|
||||
assertThat(secret.getId(), is(secret2.getId()));
|
||||
assertThat(secret.getMetadata(), is(secret2.getMetadata()));
|
||||
assertThat(secret.getCidrList(), is(secret2.getCidrList()));
|
||||
assertThat(secret2.getAccessor(), is(nullValue()));
|
||||
assertThat(secret2.getCreationTime(), is(nullValue()));
|
||||
assertThat(secret2.getExpirationTime(), 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");
|
||||
}
|
||||
String secretJson3 = assertDoesNotThrow(() -> mapper.writeValueAsString(secret), "Serialization failed");
|
||||
secret2 = assertDoesNotThrow(
|
||||
() -> mapper.readValue(commaSeparatedToList(secretJson3), AppRoleSecret.class),
|
||||
"Deserialization failed"
|
||||
);
|
||||
assertThat(secret.getId(), is(secret2.getId()));
|
||||
assertThat(secret.getMetadata(), is(secret2.getMetadata()));
|
||||
assertThat(secret.getCidrList(), is(secret2.getCidrList()));
|
||||
assertThat(secret2.getAccessor(), is(nullValue()));
|
||||
assertThat(secret2.getCreationTime(), is(nullValue()));
|
||||
assertThat(secret2.getExpirationTime(), is(nullValue()));
|
||||
assertThat(secret2.getLastUpdatedTime(), is(nullValue()));
|
||||
assertThat(secret2.getNumUses(), is(nullValue()));
|
||||
assertThat(secret2.getTtl(), is(nullValue()));
|
||||
|
||||
/* 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\"," +
|
||||
"\"creation_time\":\"TEST_CREATION\",\"expiration_time\":\"TEST_EXPIRATION\"," +
|
||||
"\"last_updated_time\":\"TEST_LASTUPDATE\",\"secret_id_num_uses\":678,\"secret_id_ttl\":12345}";
|
||||
try {
|
||||
secret2 = mapper.readValue(secretJson, AppRoleSecret.class);
|
||||
assertThat(secret2.getAccessor(), is("TEST_ACCESSOR"));
|
||||
assertThat(secret2.getCreationTime(), is("TEST_CREATION"));
|
||||
assertThat(secret2.getExpirationTime(), is("TEST_EXPIRATION"));
|
||||
assertThat(secret2.getLastUpdatedTime(), is("TEST_LASTUPDATE"));
|
||||
assertThat(secret2.getNumUses(), is(678));
|
||||
assertThat(secret2.getTtl(), is(12345));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
fail("Deserialization failed");
|
||||
}
|
||||
secret2 = assertDoesNotThrow(() -> mapper.readValue(secretJson4, AppRoleSecret.class), "Deserialization failed");
|
||||
assertThat(secret2.getAccessor(), is("TEST_ACCESSOR"));
|
||||
assertThat(secret2.getCreationTime(), is("TEST_CREATION"));
|
||||
assertThat(secret2.getExpirationTime(), is("TEST_EXPIRATION"));
|
||||
assertThat(secret2.getLastUpdatedTime(), is("TEST_LASTUPDATE"));
|
||||
assertThat(secret2.getNumUses(), is(678));
|
||||
assertThat(secret2.getTtl(), is(12345));
|
||||
|
||||
}
|
||||
|
||||
|
@ -27,13 +27,13 @@ import static org.hamcrest.Matchers.is;
|
||||
* @author Stefan Kalscheuer
|
||||
* @since 0.4.0
|
||||
*/
|
||||
public class AuthBackendTest {
|
||||
class AuthBackendTest {
|
||||
|
||||
/**
|
||||
* Test forType() method.
|
||||
*/
|
||||
@Test
|
||||
public void forTypeTest() {
|
||||
void forTypeTest() {
|
||||
assertThat(AuthBackend.forType("token"), is(AuthBackend.TOKEN));
|
||||
assertThat(AuthBackend.forType("app-id"), is(AuthBackend.APPID));
|
||||
assertThat(AuthBackend.forType("userpass"), is(AuthBackend.USERPASS));
|
||||
|
@ -35,7 +35,7 @@ import static org.hamcrest.Matchers.*;
|
||||
* @author Stefan Kalscheuer
|
||||
* @since 0.4.0
|
||||
*/
|
||||
public class TokenBuilderTest {
|
||||
class TokenBuilderTest {
|
||||
private static final String ID = "test-id";
|
||||
private static final String DISPLAY_NAME = "display-name";
|
||||
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\"}";
|
||||
|
||||
@BeforeAll
|
||||
public static void init() {
|
||||
static void init() {
|
||||
POLICIES.add(POLICY);
|
||||
META.put(META_KEY, META_VALUE);
|
||||
}
|
||||
@ -68,7 +68,7 @@ public class TokenBuilderTest {
|
||||
* Build token without any parameters.
|
||||
*/
|
||||
@Test
|
||||
public void buildDefaultTest() throws JsonProcessingException {
|
||||
void buildDefaultTest() throws JsonProcessingException {
|
||||
Token token = Token.builder().build();
|
||||
assertThat(token.getId(), is(nullValue()));
|
||||
assertThat(token.getType(), is(nullValue()));
|
||||
@ -92,7 +92,7 @@ public class TokenBuilderTest {
|
||||
* Build token without any parameters.
|
||||
*/
|
||||
@Test
|
||||
public void legacyBuildDefaultTest() throws JsonProcessingException {
|
||||
void legacyBuildDefaultTest() throws JsonProcessingException {
|
||||
Token token = new TokenBuilder().build();
|
||||
assertThat(token.getId(), is(nullValue()));
|
||||
assertThat(token.getType(), is(nullValue()));
|
||||
@ -113,7 +113,7 @@ public class TokenBuilderTest {
|
||||
* Build token without all parameters set.
|
||||
*/
|
||||
@Test
|
||||
public void buildFullTest() throws JsonProcessingException {
|
||||
void buildFullTest() throws JsonProcessingException {
|
||||
Token token = Token.builder()
|
||||
.withId(ID)
|
||||
.withType(Token.Type.SERVICE)
|
||||
@ -150,7 +150,7 @@ public class TokenBuilderTest {
|
||||
* Build token without all parameters set.
|
||||
*/
|
||||
@Test
|
||||
public void legacyBuildFullTest() throws JsonProcessingException {
|
||||
void legacyBuildFullTest() throws JsonProcessingException {
|
||||
Token token = new TokenBuilder()
|
||||
.withId(ID)
|
||||
.withType(Token.Type.SERVICE)
|
||||
@ -182,7 +182,7 @@ public class TokenBuilderTest {
|
||||
* Test convenience methods
|
||||
*/
|
||||
@Test
|
||||
public void convenienceMethodsTest() {
|
||||
void convenienceMethodsTest() {
|
||||
/* Parent */
|
||||
Token token = Token.builder().asOrphan().build();
|
||||
assertThat(token.getNoParent(), is(true));
|
||||
@ -230,7 +230,7 @@ public class TokenBuilderTest {
|
||||
* Test convenience methods
|
||||
*/
|
||||
@Test
|
||||
public void legacyConvenienceMethodsTest() {
|
||||
void legacyConvenienceMethodsTest() {
|
||||
/* Parent */
|
||||
Token token = new TokenBuilder().asOrphan().build();
|
||||
assertThat(token.getNoParent(), is(true));
|
||||
|
@ -32,7 +32,7 @@ import static org.hamcrest.Matchers.*;
|
||||
* @author Stefan Kalscheuer
|
||||
* @since 0.9
|
||||
*/
|
||||
public class TokenRoleBuilderTest {
|
||||
class TokenRoleBuilderTest {
|
||||
private static final String NAME = "test-role";
|
||||
private static final String ALLOWED_POLICY_1 = "apol-1";
|
||||
private static final String ALLOWED_POLICY_2 = "apol-2";
|
||||
@ -78,7 +78,7 @@ public class TokenRoleBuilderTest {
|
||||
* Build token without any parameters.
|
||||
*/
|
||||
@Test
|
||||
public void buildDefaultTest() throws JsonProcessingException {
|
||||
void buildDefaultTest() throws JsonProcessingException {
|
||||
TokenRole role = TokenRole.builder().build();
|
||||
assertThat(role.getAllowedPolicies(), is(nullValue()));
|
||||
assertThat(role.getDisallowedPolicies(), is(nullValue()));
|
||||
@ -100,7 +100,7 @@ public class TokenRoleBuilderTest {
|
||||
* Build token without all parameters NULL.
|
||||
*/
|
||||
@Test
|
||||
public void buildNullTest() throws JsonProcessingException {
|
||||
void buildNullTest() throws JsonProcessingException {
|
||||
TokenRole role = TokenRole.builder()
|
||||
.forName(null)
|
||||
.withAllowedPolicies(null)
|
||||
@ -141,7 +141,7 @@ public class TokenRoleBuilderTest {
|
||||
* Build token without all parameters set.
|
||||
*/
|
||||
@Test
|
||||
public void buildFullTest() throws JsonProcessingException {
|
||||
void buildFullTest() throws JsonProcessingException {
|
||||
TokenRole role = TokenRole.builder()
|
||||
.forName(NAME)
|
||||
.withAllowedPolicies(ALLOWED_POLICIES)
|
||||
|
@ -21,13 +21,13 @@ import de.stklcode.jvault.connector.exception.InvalidResponseException;
|
||||
import de.stklcode.jvault.connector.model.AppRole;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
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.
|
||||
@ -35,7 +35,7 @@ import static org.junit.jupiter.api.Assertions.fail;
|
||||
* @author Stefan Kalscheuer
|
||||
* @since 0.6.2
|
||||
*/
|
||||
public class AppRoleResponseTest {
|
||||
class AppRoleResponseTest {
|
||||
private static final Integer ROLE_TOKEN_TTL = 1200;
|
||||
private static final Integer ROLE_TOKEN_MAX_TTL = 1800;
|
||||
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
|
||||
public void getDataRoundtrip() {
|
||||
void getDataRoundtrip() {
|
||||
// Create empty Object.
|
||||
AppRoleResponse res = new AppRoleResponse();
|
||||
assertThat("Initial data should be empty", res.getRole(), is(nullValue()));
|
||||
|
||||
// Parsing invalid auth data map should fail.
|
||||
try {
|
||||
res.setData(INVALID_DATA);
|
||||
fail("Parsing invalid data succeeded");
|
||||
} catch (Exception e) {
|
||||
assertThat(e, is(instanceOf(InvalidResponseException.class)));
|
||||
}
|
||||
assertThrows(
|
||||
InvalidResponseException.class,
|
||||
() -> res.setData(INVALID_DATA),
|
||||
"Parsing invalid data succeeded"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test creation from JSON value as returned by Vault (JSON example copied from Vault documentation).
|
||||
*/
|
||||
@Test
|
||||
public void jsonRoundtrip() {
|
||||
try {
|
||||
AppRoleResponse res = new ObjectMapper().readValue(RES_JSON, AppRoleResponse.class);
|
||||
assertThat("Parsed response is NULL", res, is(notNullValue()));
|
||||
// Extract role data.
|
||||
AppRole role = res.getRole();
|
||||
assertThat("Role data is NULL", role, is(notNullValue()));
|
||||
assertThat("Incorrect token TTL", role.getTokenTtl(), is(ROLE_TOKEN_TTL));
|
||||
assertThat("Incorrect token max TTL", role.getTokenMaxTtl(), is(ROLE_TOKEN_MAX_TTL));
|
||||
assertThat("Incorrect secret ID TTL", role.getSecretIdTtl(), is(ROLE_SECRET_TTL));
|
||||
assertThat("Incorrect secret ID umber of uses", role.getSecretIdNumUses(), is(ROLE_SECRET_NUM_USES));
|
||||
assertThat("Incorrect number of policies", role.getTokenPolicies(), hasSize(1));
|
||||
assertThat("Incorrect role policies", role.getTokenPolicies(), contains(ROLE_POLICY));
|
||||
assertThat("Incorrect number of policies", role.getPolicies(), hasSize(1));
|
||||
assertThat("Incorrect role policies", role.getPolicies(), contains(ROLE_POLICY));
|
||||
assertThat("Incorrect role period", role.getTokenPeriod(), is(ROLE_PERIOD));
|
||||
assertThat("Incorrect role period", role.getPeriod(), is(ROLE_PERIOD));
|
||||
assertThat("Incorrect role bind secret ID flag", role.getBindSecretId(), is(ROLE_BIND_SECRET));
|
||||
assertThat("Incorrect bound CIDR list", role.getTokenBoundCidrs(), is(nullValue()));
|
||||
assertThat("Incorrect bound CIDR list string", role.getTokenBoundCidrsString(), is(emptyString()));
|
||||
} catch (IOException e) {
|
||||
fail("AuthResponse deserialization failed: " + e.getMessage());
|
||||
}
|
||||
void jsonRoundtrip() {
|
||||
AppRoleResponse res = assertDoesNotThrow(
|
||||
() -> new ObjectMapper().readValue(RES_JSON, AppRoleResponse.class),
|
||||
"AuthResponse deserialization failed."
|
||||
);
|
||||
assertThat("Parsed response is NULL", res, is(notNullValue()));
|
||||
// Extract role data.
|
||||
AppRole role = res.getRole();
|
||||
assertThat("Role data is NULL", role, is(notNullValue()));
|
||||
assertThat("Incorrect token TTL", role.getTokenTtl(), is(ROLE_TOKEN_TTL));
|
||||
assertThat("Incorrect token max TTL", role.getTokenMaxTtl(), is(ROLE_TOKEN_MAX_TTL));
|
||||
assertThat("Incorrect secret ID TTL", role.getSecretIdTtl(), is(ROLE_SECRET_TTL));
|
||||
assertThat("Incorrect secret ID umber of uses", role.getSecretIdNumUses(), is(ROLE_SECRET_NUM_USES));
|
||||
assertThat("Incorrect number of policies", role.getTokenPolicies(), hasSize(1));
|
||||
assertThat("Incorrect role policies", role.getTokenPolicies(), contains(ROLE_POLICY));
|
||||
assertThat("Incorrect number of policies", role.getPolicies(), hasSize(1));
|
||||
assertThat("Incorrect role policies", role.getPolicies(), contains(ROLE_POLICY));
|
||||
assertThat("Incorrect role period", role.getTokenPeriod(), is(ROLE_PERIOD));
|
||||
assertThat("Incorrect role period", role.getPeriod(), is(ROLE_PERIOD));
|
||||
assertThat("Incorrect role bind secret ID flag", role.getBindSecretId(), is(ROLE_BIND_SECRET));
|
||||
assertThat("Incorrect bound CIDR list", role.getTokenBoundCidrs(), is(nullValue()));
|
||||
assertThat("Incorrect bound CIDR list string", role.getTokenBoundCidrsString(), is(emptyString()));
|
||||
}
|
||||
}
|
||||
|
@ -22,13 +22,13 @@ import de.stklcode.jvault.connector.model.AuthBackend;
|
||||
import de.stklcode.jvault.connector.model.response.embedded.AuthMethod;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
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.
|
||||
@ -36,7 +36,7 @@ import static org.junit.jupiter.api.Assertions.fail;
|
||||
* @author Stefan Kalscheuer
|
||||
* @since 0.6.2
|
||||
*/
|
||||
public class AuthMethodsResponseTest {
|
||||
class AuthMethodsResponseTest {
|
||||
private static final String GH_PATH = "github/";
|
||||
private static final String GH_TYPE = "github";
|
||||
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
|
||||
public void getDataRoundtrip() {
|
||||
void getDataRoundtrip() {
|
||||
// Create empty Object.
|
||||
AuthMethodsResponse res = new AuthMethodsResponse();
|
||||
assertThat("Initial method map should be empty", res.getSupportedMethods(), is(anEmptyMap()));
|
||||
|
||||
// Parsing invalid data map should fail.
|
||||
try {
|
||||
res.setData(INVALID_DATA);
|
||||
fail("Parsing invalid data succeeded");
|
||||
} catch (Exception e) {
|
||||
assertThat(e, is(instanceOf(InvalidResponseException.class)));
|
||||
}
|
||||
assertThrows(
|
||||
InvalidResponseException.class,
|
||||
() -> res.setData(INVALID_DATA),
|
||||
"Parsing invalid data succeeded"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test creation from JSON value as returned by Vault (JSON example copied from Vault documentation).
|
||||
*/
|
||||
@Test
|
||||
public void jsonRoundtrip() {
|
||||
try {
|
||||
AuthMethodsResponse res = new ObjectMapper().readValue(RES_JSON, AuthMethodsResponse.class);
|
||||
assertThat("Parsed response is NULL", res, is(notNullValue()));
|
||||
// Extract auth data.
|
||||
Map<String, AuthMethod> supported = res.getSupportedMethods();
|
||||
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));
|
||||
void jsonRoundtrip() {
|
||||
AuthMethodsResponse res = assertDoesNotThrow(
|
||||
() -> new ObjectMapper().readValue(RES_JSON, AuthMethodsResponse.class),
|
||||
"AuthResponse deserialization failed"
|
||||
);
|
||||
assertThat("Parsed response is NULL", res, is(notNullValue()));
|
||||
// Extract auth data.
|
||||
Map<String, AuthMethod> supported = res.getSupportedMethods();
|
||||
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.
|
||||
AuthMethod method = supported.get(GH_PATH);
|
||||
assertThat("Incorrect raw type for GitHub", method.getRawType(), is(GH_TYPE));
|
||||
assertThat("Incorrect parsed type for GitHub", method.getType(), is(AuthBackend.GITHUB));
|
||||
assertThat("Incorrect description for GitHub", method.getDescription(), is(GH_DESCR));
|
||||
assertThat("Unexpected config for GitHub", method.getConfig(), is(nullValue()));
|
||||
// Verify first method.
|
||||
AuthMethod method = supported.get(GH_PATH);
|
||||
assertThat("Incorrect raw type for GitHub", method.getRawType(), is(GH_TYPE));
|
||||
assertThat("Incorrect parsed type for GitHub", method.getType(), is(AuthBackend.GITHUB));
|
||||
assertThat("Incorrect description for GitHub", method.getDescription(), is(GH_DESCR));
|
||||
assertThat("Unexpected config for GitHub", method.getConfig(), is(nullValue()));
|
||||
|
||||
// Verify first method.
|
||||
method = supported.get(TK_PATH);
|
||||
assertThat("Incorrect raw type for Token", method.getRawType(), is(TK_TYPE));
|
||||
assertThat("Incorrect parsed type for Token", method.getType(), is(AuthBackend.TOKEN));
|
||||
assertThat("Incorrect description for Token", method.getDescription(), is(TK_DESCR));
|
||||
assertThat("Missing config for Token", method.getConfig(), is(notNullValue()));
|
||||
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 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());
|
||||
}
|
||||
// Verify first method.
|
||||
method = supported.get(TK_PATH);
|
||||
assertThat("Incorrect raw type for Token", method.getRawType(), is(TK_TYPE));
|
||||
assertThat("Incorrect parsed type for Token", method.getType(), is(AuthBackend.TOKEN));
|
||||
assertThat("Incorrect description for Token", method.getDescription(), is(TK_DESCR));
|
||||
assertThat("Missing config for Token", method.getConfig(), is(notNullValue()));
|
||||
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 max lease TTL config", method.getConfig().get("max_lease_ttl"), is(TK_MAX_LEASE_TTL.toString()));
|
||||
}
|
||||
|
||||
private static class Dummy {
|
||||
|
@ -21,13 +21,13 @@ import de.stklcode.jvault.connector.exception.InvalidResponseException;
|
||||
import de.stklcode.jvault.connector.model.response.embedded.AuthData;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
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.
|
||||
@ -35,7 +35,7 @@ import static org.junit.jupiter.api.Assertions.fail;
|
||||
* @author Stefan Kalscheuer
|
||||
* @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_CLIENT_TOKEN = "ABCD";
|
||||
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
|
||||
public void getDataRoundtrip() {
|
||||
void getDataRoundtrip() {
|
||||
// Create empty Object.
|
||||
AuthResponse res = new AuthResponse();
|
||||
assertThat("Initial data should be empty", res.getData(), is(nullValue()));
|
||||
|
||||
// Parsing invalid auth data map should fail.
|
||||
try {
|
||||
res.setAuth(INVALID_AUTH_DATA);
|
||||
fail("Parsing invalid auth data succeeded");
|
||||
} catch (Exception e) {
|
||||
assertThat(e, is(instanceOf(InvalidResponseException.class)));
|
||||
}
|
||||
assertThrows(
|
||||
InvalidResponseException.class,
|
||||
() -> res.setAuth(INVALID_AUTH_DATA),
|
||||
"Parsing invalid auth data succeeded"
|
||||
);
|
||||
|
||||
// Data method should be agnostic.
|
||||
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
|
||||
public void jsonRoundtrip() {
|
||||
try {
|
||||
AuthResponse res = new ObjectMapper().readValue(RES_JSON, AuthResponse.class);
|
||||
void jsonRoundtrip() {
|
||||
AuthResponse res = assertDoesNotThrow(
|
||||
() -> new ObjectMapper().readValue(RES_JSON, AuthResponse.class),
|
||||
"AuthResponse deserialization failed."
|
||||
);
|
||||
assertThat("Parsed response is NULL", res, is(notNullValue()));
|
||||
// Extract auth data.
|
||||
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 auth metadata size", data.getMetadata().entrySet(), hasSize(1));
|
||||
assertThat("Incorrect auth metadata", data.getMetadata().get(AUTH_META_KEY), is(AUTH_META_VALUE));
|
||||
|
||||
} catch (IOException e) {
|
||||
fail("AuthResponse deserialization failed: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ import static org.junit.jupiter.api.Assertions.fail;
|
||||
* @author Stefan Kalscheuer
|
||||
* @since 0.8
|
||||
*/
|
||||
public class CredentialsResponseTest {
|
||||
class CredentialsResponseTest {
|
||||
private static final Map<String, Object> DATA = new HashMap<>();
|
||||
private static final String VAL_USER = "testUserName";
|
||||
private static final String VAL_PASS = "5up3r5ecr3tP455";
|
||||
@ -52,7 +52,7 @@ public class CredentialsResponseTest {
|
||||
*/
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void getCredentialsTest() throws InvalidResponseException {
|
||||
void getCredentialsTest() throws InvalidResponseException {
|
||||
// Create empty Object.
|
||||
CredentialsResponse res = new CredentialsResponse();
|
||||
assertThat("Username not present in data map should not return anything", res.getUsername(), is(nullValue()));
|
||||
|
@ -19,12 +19,10 @@ package de.stklcode.jvault.connector.model.response;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
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.
|
||||
@ -32,7 +30,7 @@ import static org.junit.jupiter.api.Assertions.fail;
|
||||
* @author Stefan Kalscheuer
|
||||
* @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_NAME = "vault-cluster-5515c810";
|
||||
private static final String VERSION = "0.9.2";
|
||||
@ -56,26 +54,26 @@ public class HealthResponseTest {
|
||||
" \"replication_dr_mode\": \"" + REPL_DR_MODE + "\",\n" +
|
||||
" \"performance_standby\": " + PERF_STANDBY + "\n" +
|
||||
"}";
|
||||
|
||||
/**
|
||||
* Test creation from JSON value as returned by Vault (JSON example copied from Vault documentation).
|
||||
*/
|
||||
@Test
|
||||
public void jsonRoundtrip() {
|
||||
try {
|
||||
HealthResponse res = new ObjectMapper().readValue(RES_JSON, HealthResponse.class);
|
||||
assertThat("Parsed response is NULL", res, is(notNullValue()));
|
||||
assertThat("Incorrect cluster ID", res.getClusterID(), is(CLUSTER_ID));
|
||||
assertThat("Incorrect cluster name", res.getClusterName(), is(CLUSTER_NAME));
|
||||
assertThat("Incorrect version", res.getVersion(), is(VERSION));
|
||||
assertThat("Incorrect server time", res.getServerTimeUTC(), is(SERVER_TIME_UTC));
|
||||
assertThat("Incorrect standby state", res.isStandby(), is(STANDBY));
|
||||
assertThat("Incorrect seal state", res.isSealed(), is(SEALED));
|
||||
assertThat("Incorrect initialization state", res.isInitialized(), is(INITIALIZED));
|
||||
assertThat("Incorrect performance standby state", res.isPerformanceStandby(), is(PERF_STANDBY));
|
||||
assertThat("Incorrect replication perf mode", res.getReplicationPerfMode(), is(REPL_PERF_MODE));
|
||||
assertThat("Incorrect replication DR mode", res.getReplicationDrMode(), is(REPL_DR_MODE));
|
||||
} catch (IOException e) {
|
||||
fail("Health deserialization failed: " + e.getMessage());
|
||||
}
|
||||
void jsonRoundtrip() {
|
||||
HealthResponse res = assertDoesNotThrow(
|
||||
() -> new ObjectMapper().readValue(RES_JSON, HealthResponse.class),
|
||||
"Health deserialization failed."
|
||||
);
|
||||
assertThat("Parsed response is NULL", res, is(notNullValue()));
|
||||
assertThat("Incorrect cluster ID", res.getClusterID(), is(CLUSTER_ID));
|
||||
assertThat("Incorrect cluster name", res.getClusterName(), is(CLUSTER_NAME));
|
||||
assertThat("Incorrect version", res.getVersion(), is(VERSION));
|
||||
assertThat("Incorrect server time", res.getServerTimeUTC(), is(SERVER_TIME_UTC));
|
||||
assertThat("Incorrect standby state", res.isStandby(), is(STANDBY));
|
||||
assertThat("Incorrect seal state", res.isSealed(), is(SEALED));
|
||||
assertThat("Incorrect initialization state", res.isInitialized(), is(INITIALIZED));
|
||||
assertThat("Incorrect performance standby state", res.isPerformanceStandby(), is(PERF_STANDBY));
|
||||
assertThat("Incorrect replication perf mode", res.getReplicationPerfMode(), is(REPL_PERF_MODE));
|
||||
assertThat("Incorrect replication DR mode", res.getReplicationDrMode(), is(REPL_DR_MODE));
|
||||
}
|
||||
}
|
||||
|
@ -17,16 +17,12 @@
|
||||
package de.stklcode.jvault.connector.model.response;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import de.stklcode.jvault.connector.exception.InvalidResponseException;
|
||||
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.Matchers.*;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||
|
||||
/**
|
||||
* JUnit Test for {@link MetadataResponse} model.
|
||||
@ -34,7 +30,7 @@ import static org.junit.jupiter.api.Assertions.fail;
|
||||
* @author Stefan Kalscheuer
|
||||
* @since 0.8
|
||||
*/
|
||||
public class MetadataResponseTest {
|
||||
class MetadataResponseTest {
|
||||
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 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
|
||||
public void jsonRoundtrip() {
|
||||
try {
|
||||
MetadataResponse res = new ObjectMapper().readValue(META_JSON, MetadataResponse.class);
|
||||
assertThat("Parsed response is NULL", res, is(notNullValue()));
|
||||
assertThat("Parsed metadata is NULL", res.getMetadata(), is(notNullValue()));
|
||||
assertThat("Incorrect created time", res.getMetadata().getCreatedTimeString(), is(V1_TIME));
|
||||
assertThat("Parting created time failed", res.getMetadata().getCreatedTime(), is(notNullValue()));
|
||||
assertThat("Incorrect current version", res.getMetadata().getCurrentVersion(), is(CURRENT_VERSION));
|
||||
assertThat("Incorrect max versions", res.getMetadata().getMaxVersions(), is(MAX_VERSIONS));
|
||||
assertThat("Incorrect oldest version", res.getMetadata().getOldestVersion(), is(OLDEST_VERSION));
|
||||
assertThat("Incorrect updated time", res.getMetadata().getUpdatedTimeString(), is(V3_TIME));
|
||||
assertThat("Parting updated time failed", res.getMetadata().getUpdatedTime(), is(notNullValue()));
|
||||
assertThat("Incorrect number of versions", res.getMetadata().getVersions().size(), is(3));
|
||||
assertThat("Incorrect version 1 delete time", res.getMetadata().getVersions().get(1).getDeletionTimeString(), is(V2_TIME));
|
||||
assertThat("Parsing version delete time failed", res.getMetadata().getVersions().get(1).getDeletionTime(), is(notNullValue()));
|
||||
assertThat("Incorrect version 1 destroyed state", res.getMetadata().getVersions().get(1).isDestroyed(), is(true));
|
||||
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()));
|
||||
assertThat("Incorrect version 3 destroyed state", res.getMetadata().getVersions().get(3).isDestroyed(), is(false));
|
||||
|
||||
} catch (IOException e) {
|
||||
fail("MetadataResponse deserialization failed: " + e.getMessage());
|
||||
}
|
||||
void jsonRoundtrip() {
|
||||
MetadataResponse res = assertDoesNotThrow(
|
||||
() -> new ObjectMapper().readValue(META_JSON, MetadataResponse.class),
|
||||
"MetadataResponse deserialization failed."
|
||||
);
|
||||
assertThat("Parsed response is NULL", res, is(notNullValue()));
|
||||
assertThat("Parsed metadata is NULL", res.getMetadata(), is(notNullValue()));
|
||||
assertThat("Incorrect created time", res.getMetadata().getCreatedTimeString(), is(V1_TIME));
|
||||
assertThat("Parting created time failed", res.getMetadata().getCreatedTime(), is(notNullValue()));
|
||||
assertThat("Incorrect current version", res.getMetadata().getCurrentVersion(), is(CURRENT_VERSION));
|
||||
assertThat("Incorrect max versions", res.getMetadata().getMaxVersions(), is(MAX_VERSIONS));
|
||||
assertThat("Incorrect oldest version", res.getMetadata().getOldestVersion(), is(OLDEST_VERSION));
|
||||
assertThat("Incorrect updated time", res.getMetadata().getUpdatedTimeString(), is(V3_TIME));
|
||||
assertThat("Parting updated time failed", res.getMetadata().getUpdatedTime(), is(notNullValue()));
|
||||
assertThat("Incorrect number of versions", res.getMetadata().getVersions().size(), is(3));
|
||||
assertThat("Incorrect version 1 delete time", res.getMetadata().getVersions().get(1).getDeletionTimeString(), is(V2_TIME));
|
||||
assertThat("Parsing version delete time failed", res.getMetadata().getVersions().get(1).getDeletionTime(), is(notNullValue()));
|
||||
assertThat("Incorrect version 1 destroyed state", res.getMetadata().getVersions().get(1).isDestroyed(), is(true));
|
||||
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()));
|
||||
assertThat("Incorrect version 3 destroyed state", res.getMetadata().getVersions().get(3).isDestroyed(), is(false));
|
||||
}
|
||||
}
|
||||
|
@ -19,11 +19,9 @@ package de.stklcode.jvault.connector.model.response;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
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.
|
||||
@ -31,7 +29,7 @@ import static org.junit.jupiter.api.Assertions.fail;
|
||||
* @author Stefan Kalscheuer
|
||||
* @since 0.8
|
||||
*/
|
||||
public class SealResponseTest {
|
||||
class SealResponseTest {
|
||||
private static final String TYPE = "shamir";
|
||||
private static final Integer THRESHOLD = 3;
|
||||
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
|
||||
public void jsonRoundtripSealed() {
|
||||
void jsonRoundtripSealed() {
|
||||
// First test sealed Vault's response.
|
||||
try {
|
||||
SealResponse res = new ObjectMapper().readValue(RES_SEALED, SealResponse.class);
|
||||
assertThat("Parsed response is NULL", res, is(notNullValue()));
|
||||
assertThat("Incorrect seal type", res.getType(), is(TYPE));
|
||||
assertThat("Incorrect seal status", res.isSealed(), is(true));
|
||||
assertThat("Incorrect initialization status", res.isInitialized(), is(true));
|
||||
assertThat("Incorrect threshold", res.getThreshold(), is(THRESHOLD));
|
||||
assertThat("Incorrect number of shares", res.getNumberOfShares(), is(SHARES));
|
||||
assertThat("Incorrect progress", res.getProgress(), is(PROGRESS_SEALED));
|
||||
assertThat("Nonce not empty", res.getNonce(), is(""));
|
||||
assertThat("Incorrect version", res.getVersion(), is(VERSION));
|
||||
// And the fields, that should not be filled.
|
||||
assertThat("Cluster name should not be populated", res.getClusterName(), is(nullValue()));
|
||||
assertThat("Cluster ID should not be populated", res.getClusterId(), is(nullValue()));
|
||||
} catch (IOException e) {
|
||||
fail("TokenResponse deserialization failed: " + e.getMessage());
|
||||
}
|
||||
SealResponse res = assertDoesNotThrow(
|
||||
() -> new ObjectMapper().readValue(RES_SEALED, SealResponse.class),
|
||||
"TokenResponse deserialization failed."
|
||||
);
|
||||
assertThat("Parsed response is NULL", res, is(notNullValue()));
|
||||
assertThat("Incorrect seal type", res.getType(), is(TYPE));
|
||||
assertThat("Incorrect seal status", res.isSealed(), is(true));
|
||||
assertThat("Incorrect initialization status", res.isInitialized(), is(true));
|
||||
assertThat("Incorrect threshold", res.getThreshold(), is(THRESHOLD));
|
||||
assertThat("Incorrect number of shares", res.getNumberOfShares(), is(SHARES));
|
||||
assertThat("Incorrect progress", res.getProgress(), is(PROGRESS_SEALED));
|
||||
assertThat("Nonce not empty", res.getNonce(), is(""));
|
||||
assertThat("Incorrect version", res.getVersion(), is(VERSION));
|
||||
// And the fields, that should not be filled.
|
||||
assertThat("Cluster name should not be populated", res.getClusterName(), is(nullValue()));
|
||||
assertThat("Cluster ID should not be populated", res.getClusterId(), is(nullValue()));
|
||||
|
||||
|
||||
// Not test unsealed Vault's response.
|
||||
try {
|
||||
SealResponse res = new ObjectMapper().readValue(RES_UNSEALED, SealResponse.class);
|
||||
assertThat("Parsed response is NULL", res, is(notNullValue()));
|
||||
assertThat("Incorrect seal type", res.getType(), is(TYPE));
|
||||
assertThat("Incorrect seal status", res.isSealed(), is(false));
|
||||
assertThat("Incorrect initialization status", res.isInitialized(), is(true));
|
||||
assertThat("Incorrect threshold", res.getThreshold(), is(THRESHOLD));
|
||||
assertThat("Incorrect number of shares", res.getNumberOfShares(), is(SHARES));
|
||||
assertThat("Incorrect progress", res.getProgress(), is(PROGRESS_UNSEALED));
|
||||
assertThat("Incorrect nonce", res.getNonce(), is(NONCE));
|
||||
assertThat("Incorrect version", res.getVersion(), is(VERSION));
|
||||
assertThat("Incorrect cluster name", res.getClusterName(), is(CLUSTER_NAME));
|
||||
assertThat("Incorrect cluster ID", res.getClusterId(), is(CLUSTER_ID));
|
||||
} catch (IOException e) {
|
||||
fail("TokenResponse deserialization failed: " + e.getMessage());
|
||||
}
|
||||
res = assertDoesNotThrow(
|
||||
() -> new ObjectMapper().readValue(RES_UNSEALED, SealResponse.class),
|
||||
"TokenResponse deserialization failed."
|
||||
);
|
||||
assertThat("Parsed response is NULL", res, is(notNullValue()));
|
||||
assertThat("Incorrect seal type", res.getType(), is(TYPE));
|
||||
assertThat("Incorrect seal status", res.isSealed(), is(false));
|
||||
assertThat("Incorrect initialization status", res.isInitialized(), is(true));
|
||||
assertThat("Incorrect threshold", res.getThreshold(), is(THRESHOLD));
|
||||
assertThat("Incorrect number of shares", res.getNumberOfShares(), is(SHARES));
|
||||
assertThat("Incorrect progress", res.getProgress(), is(PROGRESS_UNSEALED));
|
||||
assertThat("Incorrect nonce", res.getNonce(), is(NONCE));
|
||||
assertThat("Incorrect version", res.getVersion(), is(VERSION));
|
||||
assertThat("Incorrect cluster name", res.getClusterName(), is(CLUSTER_NAME));
|
||||
assertThat("Incorrect cluster ID", res.getClusterId(), is(CLUSTER_ID));
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ import java.util.Map;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
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.
|
||||
@ -34,7 +34,7 @@ import static org.junit.jupiter.api.Assertions.fail;
|
||||
* @author Stefan Kalscheuer
|
||||
* @since 0.8
|
||||
*/
|
||||
public class SecretListResponseTest {
|
||||
class SecretListResponseTest {
|
||||
private static final Map<String, Object> DATA = new HashMap<>();
|
||||
private static final String KEY1 = "key1";
|
||||
private static final String KEY2 = "key-2";
|
||||
@ -50,20 +50,19 @@ public class SecretListResponseTest {
|
||||
* @throws InvalidResponseException Should not occur
|
||||
*/
|
||||
@Test
|
||||
public void getKeysTest() throws InvalidResponseException {
|
||||
void getKeysTest() throws InvalidResponseException {
|
||||
// Create empty Object.
|
||||
SecretListResponse res = new SecretListResponse();
|
||||
assertThat("Keys should be null without initialization", res.getKeys(), is(nullValue()));
|
||||
|
||||
// Provoke internal ClassCastException.
|
||||
try {
|
||||
Map<String, Object> invalidData = new HashMap<>();
|
||||
invalidData.put("keys", "some string");
|
||||
res.setData(invalidData);
|
||||
fail("Setting incorrect class succeeded");
|
||||
} catch (Exception e) {
|
||||
assertThat("Unexpected exception type", e, instanceOf(InvalidResponseException.class));
|
||||
}
|
||||
Map<String, Object> invalidData = new HashMap<>();
|
||||
invalidData.put("keys", "some string");
|
||||
assertThrows(
|
||||
InvalidResponseException.class,
|
||||
() -> res.setData(invalidData),
|
||||
"Setting incorrect class succeeded"
|
||||
);
|
||||
|
||||
// Fill correct data.
|
||||
res.setData(DATA);
|
||||
|
@ -20,14 +20,14 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import de.stklcode.jvault.connector.exception.InvalidResponseException;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
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.
|
||||
@ -35,7 +35,7 @@ import static org.junit.jupiter.api.Assertions.fail;
|
||||
* @author Stefan Kalscheuer
|
||||
* @since 0.6.2
|
||||
*/
|
||||
public class SecretResponseTest {
|
||||
class SecretResponseTest {
|
||||
private static final Map<String, Object> DATA = new HashMap<>();
|
||||
private static final String KEY_UNKNOWN = "unknown";
|
||||
private static final String KEY_STRING = "test1";
|
||||
@ -120,7 +120,7 @@ public class SecretResponseTest {
|
||||
*/
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void getDataRoundtrip() throws InvalidResponseException {
|
||||
void getDataRoundtrip() throws InvalidResponseException {
|
||||
// Create empty Object.
|
||||
SecretResponse res = new SecretResponse();
|
||||
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()));
|
||||
|
||||
// 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 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()));
|
||||
|
||||
// Requesting invalid class should result in Exception.
|
||||
try {
|
||||
res.get(KEY_LIST, Double.class);
|
||||
fail("JSON parsing to incorrect type succeeded.");
|
||||
} catch (Exception e) {
|
||||
assertThat(e, is(instanceOf(InvalidResponseException.class)));
|
||||
}
|
||||
assertThrows(
|
||||
InvalidResponseException.class,
|
||||
() -> res.get(KEY_LIST, Double.class),
|
||||
"JSON parsing to incorrect type succeeded."
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test creation from JSON value as returned by Vault (JSON example copied from Vault documentation).
|
||||
*/
|
||||
@Test
|
||||
public void jsonRoundtrip() {
|
||||
try {
|
||||
assertSecretData(new ObjectMapper().readValue(SECRET_JSON, SecretResponse.class));
|
||||
} catch (IOException e) {
|
||||
fail("SecretResponse deserialization failed: " + e.getMessage());
|
||||
}
|
||||
void jsonRoundtrip() {
|
||||
SecretResponse res = assertDoesNotThrow(
|
||||
() -> new ObjectMapper().readValue(SECRET_JSON, SecretResponse.class),
|
||||
"SecretResponse deserialization failed."
|
||||
);
|
||||
assertSecretData(res);
|
||||
|
||||
// KV v2 secret.
|
||||
try {
|
||||
SecretResponse res = new ObjectMapper().readValue(SECRET_JSON_V2, SecretResponse.class);
|
||||
assertSecretData(res);
|
||||
assertThat("SecretResponse does not contain metadata", res.getMetadata(), is(notNullValue()));
|
||||
assertThat("Incorrect creation date string", res.getMetadata().getCreatedTimeString(), is(SECRET_META_CREATED));
|
||||
assertThat("Creation date parsing failed", res.getMetadata().getCreatedTime(), is(notNullValue()));
|
||||
assertThat("Incorrect deletion date string", res.getMetadata().getDeletionTimeString(), is(emptyString()));
|
||||
assertThat("Incorrect deletion date", res.getMetadata().getDeletionTime(), is(nullValue()));
|
||||
assertThat("Secret destroyed when not expected", res.getMetadata().isDestroyed(), is(false));
|
||||
assertThat("Incorrect secret version", res.getMetadata().getVersion(), is(1));
|
||||
} catch (IOException e) {
|
||||
fail("SecretResponse deserialization failed: " + e.getMessage());
|
||||
}
|
||||
res = assertDoesNotThrow(
|
||||
() -> new ObjectMapper().readValue(SECRET_JSON_V2, SecretResponse.class),
|
||||
"SecretResponse deserialization failed."
|
||||
);
|
||||
assertSecretData(res);
|
||||
assertThat("SecretResponse does not contain metadata", res.getMetadata(), is(notNullValue()));
|
||||
assertThat("Incorrect creation date string", res.getMetadata().getCreatedTimeString(), is(SECRET_META_CREATED));
|
||||
assertThat("Creation date parsing failed", res.getMetadata().getCreatedTime(), is(notNullValue()));
|
||||
assertThat("Incorrect deletion date string", res.getMetadata().getDeletionTimeString(), is(emptyString()));
|
||||
assertThat("Incorrect deletion date", res.getMetadata().getDeletionTime(), is(nullValue()));
|
||||
assertThat("Secret destroyed when not expected", res.getMetadata().isDestroyed(), is(false));
|
||||
assertThat("Incorrect secret version", res.getMetadata().getVersion(), is(1));
|
||||
|
||||
// Deleted KV v2 secret.
|
||||
try {
|
||||
SecretResponse res = new ObjectMapper().readValue(SECRET_JSON_V2_2, SecretResponse.class);
|
||||
assertSecretData(res);
|
||||
assertThat("SecretResponse does not contain metadata", res.getMetadata(), is(notNullValue()));
|
||||
assertThat("Incorrect creation date string", res.getMetadata().getCreatedTimeString(), is(SECRET_META_CREATED));
|
||||
assertThat("Creation date parsing failed", res.getMetadata().getCreatedTime(), is(notNullValue()));
|
||||
assertThat("Incorrect deletion date string", res.getMetadata().getDeletionTimeString(), is(SECRET_META_DELETED));
|
||||
assertThat("Incorrect deletion date", res.getMetadata().getDeletionTime(), is(notNullValue()));
|
||||
assertThat("Secret destroyed when not expected", res.getMetadata().isDestroyed(), is(true));
|
||||
assertThat("Incorrect secret version", res.getMetadata().getVersion(), is(2));
|
||||
} catch (IOException e) {
|
||||
fail("SecretResponse deserialization failed: " + e.getMessage());
|
||||
}
|
||||
res = assertDoesNotThrow(
|
||||
() -> new ObjectMapper().readValue(SECRET_JSON_V2_2, SecretResponse.class),
|
||||
"SecretResponse deserialization failed."
|
||||
);
|
||||
assertSecretData(res);
|
||||
assertThat("SecretResponse does not contain metadata", res.getMetadata(), is(notNullValue()));
|
||||
assertThat("Incorrect creation date string", res.getMetadata().getCreatedTimeString(), is(SECRET_META_CREATED));
|
||||
assertThat("Creation date parsing failed", res.getMetadata().getCreatedTime(), is(notNullValue()));
|
||||
assertThat("Incorrect deletion date string", res.getMetadata().getDeletionTimeString(), is(SECRET_META_DELETED));
|
||||
assertThat("Incorrect deletion date", res.getMetadata().getDeletionTime(), is(notNullValue()));
|
||||
assertThat("Secret destroyed when not expected", res.getMetadata().isDestroyed(), is(true));
|
||||
assertThat("Incorrect secret version", res.getMetadata().getVersion(), is(2));
|
||||
}
|
||||
|
||||
private void assertSecretData(SecretResponse res) {
|
||||
|
@ -19,12 +19,10 @@ package de.stklcode.jvault.connector.model.response;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
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.
|
||||
@ -32,7 +30,7 @@ import static org.junit.jupiter.api.Assertions.fail;
|
||||
* @author Stefan Kalscheuer
|
||||
* @since 0.8
|
||||
*/
|
||||
public class SecretVersionResponseTest {
|
||||
class SecretVersionResponseTest {
|
||||
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 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
|
||||
public void jsonRoundtrip() {
|
||||
try {
|
||||
SecretVersionResponse res = new ObjectMapper().readValue(META_JSON, SecretVersionResponse.class);
|
||||
assertThat("Parsed response is NULL", res, is(notNullValue()));
|
||||
assertThat("Parsed metadata is NULL", res.getMetadata(), is(notNullValue()));
|
||||
assertThat("Incorrect created time", res.getMetadata().getCreatedTimeString(), is(CREATION_TIME));
|
||||
assertThat("Incorrect deletion time", res.getMetadata().getDeletionTimeString(), is(DELETION_TIME));
|
||||
assertThat("Incorrect destroyed state", res.getMetadata().isDestroyed(), is(false));
|
||||
assertThat("Incorrect version", res.getMetadata().getVersion(), is(VERSION));
|
||||
} catch (IOException e) {
|
||||
fail("SecretVersionResponse deserialization failed: " + e.getMessage());
|
||||
}
|
||||
void jsonRoundtrip() {
|
||||
SecretVersionResponse res = assertDoesNotThrow(
|
||||
() -> new ObjectMapper().readValue(META_JSON, SecretVersionResponse.class),
|
||||
"SecretVersionResponse deserialization failed"
|
||||
);
|
||||
assertThat("Parsed response is NULL", res, is(notNullValue()));
|
||||
assertThat("Parsed metadata is NULL", res.getMetadata(), is(notNullValue()));
|
||||
assertThat("Incorrect created time", res.getMetadata().getCreatedTimeString(), is(CREATION_TIME));
|
||||
assertThat("Incorrect deletion time", res.getMetadata().getDeletionTimeString(), is(DELETION_TIME));
|
||||
assertThat("Incorrect destroyed state", res.getMetadata().isDestroyed(), is(false));
|
||||
assertThat("Incorrect version", res.getMetadata().getVersion(), is(VERSION));
|
||||
}
|
||||
}
|
||||
|
@ -21,14 +21,14 @@ import de.stklcode.jvault.connector.exception.InvalidResponseException;
|
||||
import de.stklcode.jvault.connector.model.response.embedded.TokenData;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
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.
|
||||
@ -36,7 +36,7 @@ import static org.junit.jupiter.api.Assertions.fail;
|
||||
* @author Stefan Kalscheuer
|
||||
* @since 0.6.2
|
||||
*/
|
||||
public class TokenResponseTest {
|
||||
class TokenResponseTest {
|
||||
private static final Integer TOKEN_CREATION_TIME = 1457533232;
|
||||
private static final Integer TOKEN_TTL = 2764800;
|
||||
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
|
||||
public void getDataRoundtrip() {
|
||||
void getDataRoundtrip() {
|
||||
// Create empty Object.
|
||||
TokenResponse res = new TokenResponse();
|
||||
assertThat("Initial data should be empty", res.getData(), is(nullValue()));
|
||||
|
||||
// Parsing invalid data map should fail.
|
||||
try {
|
||||
res.setData(INVALID_TOKEN_DATA);
|
||||
fail("Parsing invalid token data succeeded");
|
||||
} catch (Exception e) {
|
||||
assertThat(e, is(instanceOf(InvalidResponseException.class)));
|
||||
}
|
||||
assertThrows(
|
||||
InvalidResponseException.class,
|
||||
() -> res.setData(INVALID_TOKEN_DATA),
|
||||
"Parsing invalid token data succeeded"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test creation from JSON value as returned by Vault (JSON example copied from Vault documentation).
|
||||
*/
|
||||
@Test
|
||||
public void jsonRoundtrip() {
|
||||
try {
|
||||
TokenResponse res = new ObjectMapper().readValue(RES_JSON, TokenResponse.class);
|
||||
assertThat("Parsed response is NULL", res, is(notNullValue()));
|
||||
assertThat("Incorrect lease duration", res.getLeaseDuration(), is(RES_LEASE_DURATION));
|
||||
assertThat("Incorrect response renewable flag", res.isRenewable(), is(RES_RENEWABLE));
|
||||
assertThat("Incorrect response lease duration", res.getLeaseDuration(), is(RES_LEASE_DURATION));
|
||||
// Extract token data.
|
||||
TokenData data = res.getData();
|
||||
assertThat("Token data is NULL", data, is(notNullValue()));
|
||||
assertThat("Incorrect token accessor", data.getAccessor(), is(TOKEN_ACCESSOR));
|
||||
assertThat("Incorrect token creation time", data.getCreationTime(), is(TOKEN_CREATION_TIME));
|
||||
assertThat("Incorrect token creation TTL", data.getCreationTtl(), is(TOKEN_TTL));
|
||||
assertThat("Incorrect token display name", data.getName(), is(TOKEN_DISPLAY_NAME));
|
||||
assertThat("Incorrect token entity ID", data.getEntityId(), is(TOKEN_ENTITY_ID));
|
||||
assertThat("Incorrect token expire time", data.getExpireTimeString(), is(TOKEN_EXPIRE_TIME));
|
||||
assertThat("Incorrect parsed token expire time", data.getExpireTime(), is(ZonedDateTime.parse(TOKEN_EXPIRE_TIME)));
|
||||
assertThat("Incorrect token explicit max TTL", data.getExplicitMaxTtl(), is(TOKEN_EXPLICIT_MAX_TTL));
|
||||
assertThat("Incorrect token ID", data.getId(), is(TOKEN_ID));
|
||||
assertThat("Incorrect token issue time", data.getIssueTimeString(), is(TOKEN_ISSUE_TIME));
|
||||
assertThat("Incorrect parsed token issue time", data.getIssueTime(), is(ZonedDateTime.parse(TOKEN_ISSUE_TIME)));
|
||||
assertThat("Incorrect token metadata size", data.getMeta().entrySet(), hasSize(1));
|
||||
assertThat("Incorrect token metadata", data.getMeta().get(TOKEN_META_KEY), is(TOKEN_META_VALUE));
|
||||
assertThat("Incorrect token number of uses", data.getNumUses(), is(TOKEN_NUM_USES));
|
||||
assertThat("Incorrect token orphan flag", data.isOrphan(), is(TOKEN_ORPHAN));
|
||||
assertThat("Incorrect token path", data.getPath(), is(TOKEN_PATH));
|
||||
assertThat("Incorrect number of token policies", data.getPolicies(), hasSize(2));
|
||||
assertThat("Incorrect token policies", data.getPolicies(), contains(TOKEN_POLICY_1, TOKEN_POLICY_2));
|
||||
assertThat("Incorrect token renewable flag", data.isRenewable(), is(TOKEN_RENEWABLE));
|
||||
assertThat("Incorrect token TTL", data.getTtl(), is(RES_TTL));
|
||||
assertThat("Incorrect token type", data.getType(), is(TOKEN_TYPE));
|
||||
} catch (IOException e) {
|
||||
fail("TokenResponse deserialization failed: " + e.getMessage());
|
||||
}
|
||||
void jsonRoundtrip() {
|
||||
TokenResponse res = assertDoesNotThrow(
|
||||
() -> new ObjectMapper().readValue(RES_JSON, TokenResponse.class),
|
||||
"TokenResponse deserialization failed."
|
||||
);
|
||||
assertThat("Parsed response is NULL", res, is(notNullValue()));
|
||||
assertThat("Incorrect lease duration", res.getLeaseDuration(), is(RES_LEASE_DURATION));
|
||||
assertThat("Incorrect response renewable flag", res.isRenewable(), is(RES_RENEWABLE));
|
||||
assertThat("Incorrect response lease duration", res.getLeaseDuration(), is(RES_LEASE_DURATION));
|
||||
// Extract token data.
|
||||
TokenData data = res.getData();
|
||||
assertThat("Token data is NULL", data, is(notNullValue()));
|
||||
assertThat("Incorrect token accessor", data.getAccessor(), is(TOKEN_ACCESSOR));
|
||||
assertThat("Incorrect token creation time", data.getCreationTime(), is(TOKEN_CREATION_TIME));
|
||||
assertThat("Incorrect token creation TTL", data.getCreationTtl(), is(TOKEN_TTL));
|
||||
assertThat("Incorrect token display name", data.getName(), is(TOKEN_DISPLAY_NAME));
|
||||
assertThat("Incorrect token entity ID", data.getEntityId(), is(TOKEN_ENTITY_ID));
|
||||
assertThat("Incorrect token expire time", data.getExpireTimeString(), is(TOKEN_EXPIRE_TIME));
|
||||
assertThat("Incorrect parsed token expire time", data.getExpireTime(), is(ZonedDateTime.parse(TOKEN_EXPIRE_TIME)));
|
||||
assertThat("Incorrect token explicit max TTL", data.getExplicitMaxTtl(), is(TOKEN_EXPLICIT_MAX_TTL));
|
||||
assertThat("Incorrect token ID", data.getId(), is(TOKEN_ID));
|
||||
assertThat("Incorrect token issue time", data.getIssueTimeString(), is(TOKEN_ISSUE_TIME));
|
||||
assertThat("Incorrect parsed token issue time", data.getIssueTime(), is(ZonedDateTime.parse(TOKEN_ISSUE_TIME)));
|
||||
assertThat("Incorrect token metadata size", data.getMeta().entrySet(), hasSize(1));
|
||||
assertThat("Incorrect token metadata", data.getMeta().get(TOKEN_META_KEY), is(TOKEN_META_VALUE));
|
||||
assertThat("Incorrect token number of uses", data.getNumUses(), is(TOKEN_NUM_USES));
|
||||
assertThat("Incorrect token orphan flag", data.isOrphan(), is(TOKEN_ORPHAN));
|
||||
assertThat("Incorrect token path", data.getPath(), is(TOKEN_PATH));
|
||||
assertThat("Incorrect number of token policies", data.getPolicies(), hasSize(2));
|
||||
assertThat("Incorrect token policies", data.getPolicies(), contains(TOKEN_POLICY_1, TOKEN_POLICY_2));
|
||||
assertThat("Incorrect token renewable flag", data.isRenewable(), is(TOKEN_RENEWABLE));
|
||||
assertThat("Incorrect token TTL", data.getTtl(), is(RES_TTL));
|
||||
assertThat("Incorrect token type", data.getType(), is(TOKEN_TYPE));
|
||||
}
|
||||
}
|
||||
|
@ -1,51 +0,0 @@
|
||||
/*
|
||||
* 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.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);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user