15 Commits

Author SHA1 Message Date
50d485fab8 clean up unused imports
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-02 11:27:24 +02:00
5b508374d9 prepare release 0.9.3
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-02 11:16:04 +02:00
fbc61e065f fix argline for JDK 1.8 unit tests
All checks were successful
continuous-integration/drone/push Build is passing
2021-03-29 21:13:34 +02:00
56a52cb22a fix argline for JDK 16 unit tests
All checks were successful
continuous-integration/drone/push Build is passing
2021-03-29 20:50:16 +02:00
c43ec190ca use SystemLambda instead of custom environment mocks 2021-03-29 20:49:44 +02:00
639d0e3c5b Jackson 2.12.2, test against Vault 1.7.0
All checks were successful
continuous-integration/drone/push Build is passing
2021-03-29 18:56:24 +02:00
8e97f3c1dd build with JDK 16, test against Vault 1.6.3
All checks were successful
continuous-integration/drone/push Build is passing
2021-03-20 12:13:19 +01:00
c04d940a80 test: close static mocks
All checks were successful
continuous-integration/drone/push Build is passing
2021-02-28 13:03:25 +01:00
76a5ea4fe9 test: use assertThrows instead of try-catch blocks
All checks were successful
continuous-integration/drone/push Build is passing
2021-02-28 12:59:06 +01:00
2b0f458da3 use pre-sized maps for fixed-size payloads
All checks were successful
continuous-integration/drone/push Build is passing
2021-02-28 10:52:36 +01:00
63278c09c8 constructors of abstract VaultConnectorException protected
All checks were successful
continuous-integration/drone/push Build is passing
2021-01-24 14:57:14 +01:00
600f3d0d0f test classes package-private; use mockStatic()
All checks were successful
continuous-integration/drone/push Build is passing
2021-01-24 14:52:48 +01:00
1a19eaa87d release 0.9.2
All checks were successful
continuous-integration/drone/push Build is passing
2021-01-24 12:26:29 +01:00
a2dde38348 Jackson 2.12.1
All checks were successful
continuous-integration/drone/push Build is passing
2021-01-24 12:24:09 +01:00
dfb6d0a37c only initialize trust managers if CA certificate is provided (#43)
All checks were successful
continuous-integration/drone/push Build is passing
2021-01-24 12:20:45 +01:00
34 changed files with 1265 additions and 1660 deletions

View File

@ -25,12 +25,12 @@ steps:
- name: unit-integration-tests - name: unit-integration-tests
image: maven:3-jdk-11 image: maven:3-jdk-11
environment: environment:
VAULT_VERSION: 1.6.1 VAULT_VERSION: 1.7.0
commands: 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 -o vault_1.7.0_linux_amd64.zip https://releases.hashicorp.com/vault/1.7.0/vault_1.7.0_linux_amd64.zip
- curl -s https://releases.hashicorp.com/vault/1.6.1/vault_1.6.1_SHA256SUMS | grep linux_amd64 | sha256sum -c - curl -s https://releases.hashicorp.com/vault/1.7.0/vault_1.7.0_SHA256SUMS | grep linux_amd64 | sha256sum -c
- unzip vault_1.6.1_linux_amd64.zip - unzip vault_1.7.0_linux_amd64.zip
- rm vault_1.6.1_linux_amd64.zip - rm vault_1.7.0_linux_amd64.zip
- mv vault /bin/ - mv vault /bin/
- mvn -B resources:testResources compiler:testCompile surefire:test - mvn -B resources:testResources compiler:testCompile surefire:test
when: when:

View File

@ -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=" 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: env:
- PATH=$PATH:. VAULT_VERSION=1.6.1 ANALYSIS=false - PATH=$PATH:. VAULT_VERSION=1.7.0 ANALYSIS=false
cache: cache:
directories: directories:
@ -18,8 +18,8 @@ jobs:
include: include:
- jdk: openjdk8 - jdk: openjdk8
- jdk: openjdk11 - jdk: openjdk11
env: PATH=$PATH:. VAULT_VERSION=1.6.1 ANALYSIS=true env: PATH=$PATH:. VAULT_VERSION=1.7.0 ANALYSIS=true
- jdk: openjdk15 - jdk: openjdk16
before_script: before_script:
- | - |

View File

@ -1,3 +1,21 @@
## 0.9.3 (2021-04-02)
### Improvements
* Use pre-sized map objects for fixed-size payloads
* Minor dependency updates
* Unit test adjustments for JDK 16 build environments
### Test
* Tested against Vault 1.7.0
## 0.9.2 (2021-01-24)
### Fixes
* Only initialize custom trust managers, if CA certificate is actually provided (#43)
### Improvements
* Minor dependency updates
## 0.9.1 (2021-01-03) ## 0.9.1 (2021-01-03)
### Improvements ### Improvements

View File

@ -32,7 +32,7 @@ Java Vault Connector is a connector library for [Vault](https://www.vaultproject
* SQL secret handling * SQL secret handling
* KV v1 and v2 support * KV v1 and v2 support
* Connector Factory with builder pattern * Connector Factory with builder pattern
* Tested against Vault 1.6.1 * Tested against Vault 1.7.0
## Maven Artifact ## Maven Artifact
@ -40,7 +40,7 @@ Java Vault Connector is a connector library for [Vault](https://www.vaultproject
<dependency> <dependency>
<groupId>de.stklcode.jvault</groupId> <groupId>de.stklcode.jvault</groupId>
<artifactId>jvault-connector</artifactId> <artifactId>jvault-connector</artifactId>
<version>0.9.1</version> <version>0.9.3</version>
</dependency> </dependency>
``` ```
@ -86,20 +86,20 @@ vault.authAppRole("01234567-89ab-cdef-0123-456789abcdef", "fedcba98-7654-3210-fe
```java ```java
// Retrieve secret (prefix "secret/" assumed, use read() to read arbitrary paths) // Retrieve secret (prefix "secret/" assumed, use read() to read arbitrary paths)
String secret = vault.readSecret("some/secret/key").get("value", String.class); String secret = vault.read("secret/some/key").get("value", String.class);
// Complex secret. // Complex secret.
Map<String, Object> secretData = vault.readSecret("another/secret/key").getData(); Map<String, Object> secretData = vault.read("secret/another/key").getData();
// Write simple secret. // Write simple secret.
vault.writeSecret("new/secret/key", "secret value"); vault.write("secret/new/key", "secret value");
// Write complex data to arbitraty path. // Write complex data.
Map<String, Object> map = ...; Map<String, Object> map = ...;
vault.write("any/path/to/write", map); vault.write("path/to/write", map);
// Delete secret. // Delete secret.
vault.delete("any/path/to/write"); vault.delete("path/to/delete");
``` ```
### Token and role creation ### Token and role creation

46
pom.xml
View File

@ -4,7 +4,7 @@
<groupId>de.stklcode.jvault</groupId> <groupId>de.stklcode.jvault</groupId>
<artifactId>jvault-connector</artifactId> <artifactId>jvault-connector</artifactId>
<version>0.9.1</version> <version>0.9.3</version>
<packaging>jar</packaging> <packaging>jar</packaging>
@ -23,6 +23,7 @@
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<argLine></argLine>
</properties> </properties>
<developers> <developers>
@ -96,6 +97,7 @@
<version>2.22.2</version> <version>2.22.2</version>
<configuration> <configuration>
<reuseForks>false</reuseForks> <reuseForks>false</reuseForks>
<argLine>@{argLine} --illegal-access=permit</argLine>
</configuration> </configuration>
</plugin> </plugin>
</plugins> </plugins>
@ -111,13 +113,13 @@
<dependency> <dependency>
<groupId>com.fasterxml.jackson.core</groupId> <groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId> <artifactId>jackson-databind</artifactId>
<version>2.12.0</version> <version>2.12.2</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.junit.jupiter</groupId> <groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId> <artifactId>junit-jupiter</artifactId>
<version>5.7.0</version> <version>5.7.1</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
@ -129,13 +131,19 @@
<dependency> <dependency>
<groupId>org.mockito</groupId> <groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId> <artifactId>mockito-core</artifactId>
<version>3.6.28</version> <version>3.8.0</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.mockito</groupId> <groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId> <artifactId>mockito-inline</artifactId>
<version>3.6.28</version> <version>3.8.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.stefanbirkner</groupId>
<artifactId>system-lambda</artifactId>
<version>1.2.0</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
@ -151,7 +159,7 @@
<dependency> <dependency>
<groupId>org.sonarsource.scanner.maven</groupId> <groupId>org.sonarsource.scanner.maven</groupId>
<artifactId>sonar-maven-plugin</artifactId> <artifactId>sonar-maven-plugin</artifactId>
<version>3.7.0.1746</version> <version>3.8.0.2131</version>
</dependency> </dependency>
</dependencies> </dependencies>
</dependencyManagement> </dependencyManagement>
@ -286,7 +294,7 @@
<plugin> <plugin>
<groupId>org.owasp</groupId> <groupId>org.owasp</groupId>
<artifactId>dependency-check-maven</artifactId> <artifactId>dependency-check-maven</artifactId>
<version>6.0.4</version> <version>6.1.5</version>
<executions> <executions>
<execution> <execution>
<goals> <goals>
@ -299,6 +307,26 @@
</build> </build>
</profile> </profile>
<profile>
<id>jdk1.8</id>
<activation>
<jdk>1.8</jdk>
</activation>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>@{argLine}</argLine>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</profile>
<profile> <profile>
<id>sonatype</id> <id>sonatype</id>
<distributionManagement> <distributionManagement>
@ -317,11 +345,11 @@
<id>local</id> <id>local</id>
<distributionManagement> <distributionManagement>
<repository> <repository>
<id>local</id> <id>stklcode</id>
<url>${dist.repo.local}</url> <url>${dist.repo.local}</url>
</repository> </repository>
<snapshotRepository> <snapshotRepository>
<id>local</id> <id>stklcode</id>
<url>${dist.repo.local.snapshot}</url> <url>${dist.repo.local.snapshot}</url>
</snapshotRepository> </snapshotRepository>
</distributionManagement> </distributionManagement>

View File

@ -30,6 +30,9 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static java.util.Collections.emptyMap;
import static java.util.Collections.singletonMap;
/** /**
* Vault Connector implementation using Vault's HTTP API. * Vault Connector implementation using Vault's HTTP API.
* *
@ -222,17 +225,17 @@ public class HTTPVaultConnector implements VaultConnector {
@Override @Override
public final SealResponse sealStatus() throws VaultConnectorException { public final SealResponse sealStatus() throws VaultConnectorException {
return request.get(PATH_SEAL_STATUS, new HashMap<>(), token, SealResponse.class); return request.get(PATH_SEAL_STATUS, emptyMap(), token, SealResponse.class);
} }
@Override @Override
public final void seal() throws VaultConnectorException { public final void seal() throws VaultConnectorException {
request.put(PATH_SEAL, new HashMap<>(), token); request.put(PATH_SEAL, emptyMap(), token);
} }
@Override @Override
public final SealResponse unseal(final String key, final Boolean reset) throws VaultConnectorException { public final SealResponse unseal(final String key, final Boolean reset) throws VaultConnectorException {
Map<String, String> param = new HashMap<>(); Map<String, String> param = new HashMap<>(2, 1);
param.put("key", key); param.put("key", key);
if (reset != null) { if (reset != null) {
param.put("reset", reset.toString()); param.put("reset", reset.toString());
@ -244,7 +247,7 @@ public class HTTPVaultConnector implements VaultConnector {
@Override @Override
public HealthResponse getHealth() throws VaultConnectorException { public HealthResponse getHealth() throws VaultConnectorException {
/* Force status code to be 200, so we don't need to modify the request sequence. */ /* Force status code to be 200, so we don't need to modify the request sequence. */
Map<String, String> param = new HashMap<>(); Map<String, String> param = new HashMap<>(3, 1);
param.put("standbycode", "200"); // Default: 429. param.put("standbycode", "200"); // Default: 429.
param.put("sealedcode", "200"); // Default: 503. param.put("sealedcode", "200"); // Default: 503.
param.put("uninitcode", "200"); // Default: 501. param.put("uninitcode", "200"); // Default: 501.
@ -260,7 +263,7 @@ public class HTTPVaultConnector implements VaultConnector {
@Override @Override
public final List<AuthBackend> getAuthBackends() throws VaultConnectorException { public final List<AuthBackend> getAuthBackends() throws VaultConnectorException {
/* Issue request and parse response */ /* Issue request and parse response */
AuthMethodsResponse amr = request.get(PATH_AUTH, new HashMap<>(), token, AuthMethodsResponse.class); AuthMethodsResponse amr = request.get(PATH_AUTH, emptyMap(), token, AuthMethodsResponse.class);
return amr.getSupportedMethods().values().stream().map(AuthMethod::getType).collect(Collectors.toList()); return amr.getSupportedMethods().values().stream().map(AuthMethod::getType).collect(Collectors.toList());
} }
@ -270,7 +273,7 @@ public class HTTPVaultConnector implements VaultConnector {
/* set token */ /* set token */
this.token = token; this.token = token;
this.tokenTTL = 0; this.tokenTTL = 0;
TokenResponse res = request.post(PATH_TOKEN + PATH_LOOKUP, new HashMap<>(), token, TokenResponse.class); TokenResponse res = request.post(PATH_TOKEN + PATH_LOOKUP, emptyMap(), token, TokenResponse.class);
authorized = true; authorized = true;
return res; return res;
@ -279,15 +282,14 @@ public class HTTPVaultConnector implements VaultConnector {
@Override @Override
public final AuthResponse authUserPass(final String username, final String password) public final AuthResponse authUserPass(final String username, final String password)
throws VaultConnectorException { throws VaultConnectorException {
final Map<String, String> payload = new HashMap<>(); final Map<String, String> payload = singletonMap("password", password);
payload.put("password", password);
return queryAuth(PATH_AUTH_USERPASS + username, payload); return queryAuth(PATH_AUTH_USERPASS + username, payload);
} }
@Override @Override
@Deprecated @Deprecated
public final AuthResponse authAppId(final String appID, final String userID) throws VaultConnectorException { public final AuthResponse authAppId(final String appID, final String userID) throws VaultConnectorException {
final Map<String, String> payload = new HashMap<>(); final Map<String, String> payload = new HashMap<>(2, 1);
payload.put("app_id", appID); payload.put("app_id", appID);
payload.put("user_id", userID); payload.put("user_id", userID);
return queryAuth(PATH_AUTH_APPID + "login", payload); return queryAuth(PATH_AUTH_APPID + "login", payload);
@ -295,7 +297,7 @@ public class HTTPVaultConnector implements VaultConnector {
@Override @Override
public final AuthResponse authAppRole(final String roleID, final String secretID) throws VaultConnectorException { public final AuthResponse authAppRole(final String roleID, final String secretID) throws VaultConnectorException {
final Map<String, String> payload = new HashMap<>(); final Map<String, String> payload = new HashMap<>(2, 1);
payload.put("role_id", roleID); payload.put("role_id", roleID);
if (secretID != null) { if (secretID != null) {
payload.put("secret_id", secretID); payload.put("secret_id", secretID);
@ -328,7 +330,7 @@ public class HTTPVaultConnector implements VaultConnector {
public final boolean registerAppId(final String appID, final String policy, final String displayName) public final boolean registerAppId(final String appID, final String policy, final String displayName)
throws VaultConnectorException { throws VaultConnectorException {
requireAuth(); requireAuth();
Map<String, String> payload = new HashMap<>(); Map<String, String> payload = new HashMap<>(2, 1);
payload.put("value", policy); payload.put("value", policy);
payload.put("display_name", displayName); payload.put("display_name", displayName);
@ -342,11 +344,13 @@ public class HTTPVaultConnector implements VaultConnector {
@Deprecated @Deprecated
public final boolean registerUserId(final String appID, final String userID) throws VaultConnectorException { public final boolean registerUserId(final String appID, final String userID) throws VaultConnectorException {
requireAuth(); requireAuth();
Map<String, String> payload = new HashMap<>();
payload.put("value", appID);
/* Issue request and expect code 204 with empty response */ /* Issue request and expect code 204 with empty response */
request.postWithoutResponse(PATH_AUTH_APPID + "map/user-id/" + userID, payload, token); request.postWithoutResponse(
PATH_AUTH_APPID + "map/user-id/" + userID,
singletonMap("value", appID),
token
);
return true; return true;
} }
@ -366,7 +370,12 @@ public class HTTPVaultConnector implements VaultConnector {
public final AppRoleResponse lookupAppRole(final String roleName) throws VaultConnectorException { public final AppRoleResponse lookupAppRole(final String roleName) throws VaultConnectorException {
requireAuth(); requireAuth();
/* Request HTTP response and parse Secret */ /* Request HTTP response and parse Secret */
return request.get(String.format(PATH_AUTH_APPROLE_ROLE, roleName, ""), new HashMap<>(), token, AppRoleResponse.class); return request.get(
String.format(PATH_AUTH_APPROLE_ROLE, roleName, ""),
emptyMap(),
token,
AppRoleResponse.class
);
} }
@Override @Override
@ -385,7 +394,7 @@ public class HTTPVaultConnector implements VaultConnector {
/* Issue request, parse response and extract Role ID */ /* Issue request, parse response and extract Role ID */
return request.get( return request.get(
String.format(PATH_AUTH_APPROLE_ROLE, roleName, "/role-id"), String.format(PATH_AUTH_APPROLE_ROLE, roleName, "/role-id"),
new HashMap<>(), emptyMap(),
token, token,
RawDataResponse.class RawDataResponse.class
).getData().get("role_id").toString(); ).getData().get("role_id").toString();
@ -394,12 +403,13 @@ public class HTTPVaultConnector implements VaultConnector {
@Override @Override
public final boolean setAppRoleID(final String roleName, final String roleID) throws VaultConnectorException { public final boolean setAppRoleID(final String roleName, final String roleID) throws VaultConnectorException {
requireAuth(); requireAuth();
/* Request HTTP response and parse Secret */
Map<String, String> payload = new HashMap<>();
payload.put("role_id", roleID);
/* Issue request and expect code 204 with empty response */ /* Issue request and expect code 204 with empty response */
request.postWithoutResponse(String.format(PATH_AUTH_APPROLE_ROLE, roleName, "/role-id"), payload, token); request.postWithoutResponse(
String.format(PATH_AUTH_APPROLE_ROLE, roleName, "/role-id"),
singletonMap("role_id", roleID),
token
);
return true; return true;
} }
@ -457,7 +467,13 @@ public class HTTPVaultConnector implements VaultConnector {
public final List<String> listAppRoles() throws VaultConnectorException { public final List<String> listAppRoles() throws VaultConnectorException {
requireAuth(); requireAuth();
SecretListResponse secrets = request.get(PATH_AUTH_APPROLE + "role?list=true", new HashMap<>(), token, SecretListResponse.class); SecretListResponse secrets = request.get(
PATH_AUTH_APPROLE + "role?list=true",
emptyMap(),
token,
SecretListResponse.class
);
return secrets.getKeys(); return secrets.getKeys();
} }
@ -467,7 +483,7 @@ public class HTTPVaultConnector implements VaultConnector {
SecretListResponse secrets = request.get( SecretListResponse secrets = request.get(
String.format(PATH_AUTH_APPROLE_ROLE, roleName, "/secret-id?list=true"), String.format(PATH_AUTH_APPROLE_ROLE, roleName, "/secret-id?list=true"),
new HashMap<>(), emptyMap(),
token, token,
SecretListResponse.class SecretListResponse.class
); );
@ -479,14 +495,14 @@ public class HTTPVaultConnector implements VaultConnector {
public final SecretResponse read(final String key) throws VaultConnectorException { public final SecretResponse read(final String key) throws VaultConnectorException {
requireAuth(); requireAuth();
/* Issue request and parse secret response */ /* Issue request and parse secret response */
return request.get(key, new HashMap<>(), token, SecretResponse.class); return request.get(key, emptyMap(), token, SecretResponse.class);
} }
@Override @Override
public final SecretResponse readSecretVersion(final String mount, final String key, final Integer version) throws VaultConnectorException { public final SecretResponse readSecretVersion(final String mount, final String key, final Integer version) throws VaultConnectorException {
requireAuth(); requireAuth();
/* Request HTTP response and parse secret metadata */ /* Request HTTP response and parse secret metadata */
Map<String, String> args = new HashMap<>(); Map<String, String> args = new HashMap<>(1, 1);
if (version != null) { if (version != null) {
args.put("version", version.toString()); args.put("version", version.toString());
} }
@ -499,14 +515,14 @@ public class HTTPVaultConnector implements VaultConnector {
requireAuth(); requireAuth();
/* Request HTTP response and parse secret metadata */ /* Request HTTP response and parse secret metadata */
return request.get(mount + PATH_METADATA + key, new HashMap<>(), token, MetadataResponse.class); return request.get(mount + PATH_METADATA + key, emptyMap(), token, MetadataResponse.class);
} }
@Override @Override
public void updateSecretMetadata(final String mount, final String key, final Integer maxVersions, final boolean casRequired) throws VaultConnectorException { public void updateSecretMetadata(final String mount, final String key, final Integer maxVersions, final boolean casRequired) throws VaultConnectorException {
requireAuth(); requireAuth();
Map<String, Object> payload = new HashMap<>(); Map<String, Object> payload = new HashMap<>(2, 1);
if (maxVersions != null) { if (maxVersions != null) {
payload.put("max_versions", maxVersions); payload.put("max_versions", maxVersions);
} }
@ -524,12 +540,12 @@ public class HTTPVaultConnector implements VaultConnector {
} }
// Add CAS value to options map if present. // Add CAS value to options map if present.
Map<String, Object> options = new HashMap<>(); Map<String, Object> options = new HashMap<>(1, 1);
if (cas != null) { if (cas != null) {
options.put("cas", cas); options.put("cas", cas);
} }
Map<String, Object> payload = new HashMap<>(); Map<String, Object> payload = new HashMap<>(2, 1);
payload.put("data", data); payload.put("data", data);
payload.put("options", options); payload.put("options", options);
@ -541,7 +557,7 @@ public class HTTPVaultConnector implements VaultConnector {
public final List<String> list(final String path) throws VaultConnectorException { public final List<String> list(final String path) throws VaultConnectorException {
requireAuth(); requireAuth();
SecretListResponse secrets = request.get(path + "/?list=true", new HashMap<>(), token, SecretListResponse.class); SecretListResponse secrets = request.get(path + "/?list=true", emptyMap(), token, SecretListResponse.class);
return secrets.getKeys(); return secrets.getKeys();
} }
@ -559,7 +575,7 @@ public class HTTPVaultConnector implements VaultConnector {
// If options are given, split payload in two parts. // If options are given, split payload in two parts.
if (options != null) { if (options != null) {
Map<String, Object> payloadMap = new HashMap<>(); Map<String, Object> payloadMap = new HashMap<>(2, 1);
payloadMap.put("data", data); payloadMap.put("data", data);
payloadMap.put("options", options); payloadMap.put("options", options);
payload = payloadMap; payload = payloadMap;
@ -616,8 +632,7 @@ public class HTTPVaultConnector implements VaultConnector {
requireAuth(); requireAuth();
/* Request HTTP response and expect empty result */ /* Request HTTP response and expect empty result */
Map<String, Object> payload = new HashMap<>(); Map<String, Object> payload = singletonMap("versions", versions);
payload.put("versions", versions);
/* Issue request and expect code 204 with empty response */ /* Issue request and expect code 204 with empty response */
request.postWithoutResponse(mount + pathPart + key, payload, token); request.postWithoutResponse(mount + pathPart + key, payload, token);
@ -628,14 +643,14 @@ public class HTTPVaultConnector implements VaultConnector {
requireAuth(); requireAuth();
/* Issue request and expect code 204 with empty response */ /* Issue request and expect code 204 with empty response */
request.putWithoutResponse(PATH_REVOKE + leaseID, new HashMap<>(), token); request.putWithoutResponse(PATH_REVOKE + leaseID, emptyMap(), token);
} }
@Override @Override
public final SecretResponse renew(final String leaseID, final Integer increment) throws VaultConnectorException { public final SecretResponse renew(final String leaseID, final Integer increment) throws VaultConnectorException {
requireAuth(); requireAuth();
Map<String, String> payload = new HashMap<>(); Map<String, String> payload = new HashMap<>(2, 1);
payload.put("lease_id", leaseID); payload.put("lease_id", leaseID);
if (increment != null) { if (increment != null) {
payload.put("increment", increment.toString()); payload.put("increment", increment.toString());
@ -694,9 +709,12 @@ public class HTTPVaultConnector implements VaultConnector {
requireAuth(); requireAuth();
/* Request HTTP response and parse Secret */ /* Request HTTP response and parse Secret */
Map<String, String> param = new HashMap<>(); return request.get(
param.put("token", token); PATH_TOKEN + PATH_LOOKUP,
return request.get(PATH_TOKEN + PATH_LOOKUP, param, token, TokenResponse.class); singletonMap("token", token),
token,
TokenResponse.class
);
} }
@Override @Override
@ -720,7 +738,7 @@ public class HTTPVaultConnector implements VaultConnector {
requireAuth(); requireAuth();
// Request HTTP response and parse response. // Request HTTP response and parse response.
return request.get(PATH_TOKEN + PATH_ROLES + "/" + name, new HashMap<>(), token, TokenRoleResponse.class); return request.get(PATH_TOKEN + PATH_ROLES + "/" + name, emptyMap(), token, TokenRoleResponse.class);
} }
@Override @Override

View File

@ -22,10 +22,7 @@ import de.stklcode.jvault.connector.model.*;
import de.stklcode.jvault.connector.model.response.*; import de.stklcode.jvault.connector.model.response.*;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/** /**
* Vault Connector interface. * Vault Connector interface.
@ -611,9 +608,7 @@ public interface VaultConnector extends AutoCloseable, Serializable {
* @since 0.5.0 * @since 0.5.0
*/ */
default void write(final String key, final String value) throws VaultConnectorException { default void write(final String key, final String value) throws VaultConnectorException {
Map<String, Object> param = new HashMap<>(); write(key, Collections.singletonMap("value", value));
param.put("value", value);
write(key, param);
} }
/** /**
@ -649,9 +644,7 @@ public interface VaultConnector extends AutoCloseable, Serializable {
* @throws VaultConnectorException on error * @throws VaultConnectorException on error
*/ */
default void writeSecret(final String key, final String value) throws VaultConnectorException { default void writeSecret(final String key, final String value) throws VaultConnectorException {
Map<String, Object> param = new HashMap<>(); writeSecret(key, Collections.singletonMap("value", value));
param.put("value", value);
writeSecret(key, param);
} }
/** /**

View File

@ -26,7 +26,7 @@ public abstract class VaultConnectorException extends Exception {
/** /**
* Constructs a new empty exception. * Constructs a new empty exception.
*/ */
public VaultConnectorException() { protected VaultConnectorException() {
} }
/** /**
@ -34,7 +34,7 @@ public abstract class VaultConnectorException extends Exception {
* *
* @param message the detail message * @param message the detail message
*/ */
public VaultConnectorException(final String message) { protected VaultConnectorException(final String message) {
super(message); super(message);
} }
@ -43,7 +43,7 @@ public abstract class VaultConnectorException extends Exception {
* *
* @param cause the cause * @param cause the cause
*/ */
public VaultConnectorException(final Throwable cause) { protected VaultConnectorException(final Throwable cause) {
super(cause); super(cause);
} }
@ -53,7 +53,7 @@ public abstract class VaultConnectorException extends Exception {
* @param message the detail message * @param message the detail message
* @param cause the cause * @param cause the cause
*/ */
public VaultConnectorException(final String message, final Throwable cause) { protected VaultConnectorException(final String message, final Throwable cause) {
super(message, cause); super(message, cause);
} }
} }

View File

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

View File

@ -40,7 +40,7 @@ public final class AppRoleResponse extends VaultDataResponse {
ObjectMapper mapper = new ObjectMapper(); ObjectMapper mapper = new ObjectMapper();
try { try {
/* null empty strings on list objects */ /* null empty strings on list objects */
Map<String, Object> filteredData = new HashMap<>(); Map<String, Object> filteredData = new HashMap<>(data.size(), 1);
data.forEach((k, v) -> { data.forEach((k, v) -> {
if (!(v instanceof String && ((String) v).isEmpty())) { if (!(v instanceof String && ((String) v).isEmpty())) {
filteredData.put(k, v); filteredData.put(k, v);

View File

@ -40,7 +40,7 @@ public final class AppRoleSecretResponse extends VaultDataResponse {
ObjectMapper mapper = new ObjectMapper(); ObjectMapper mapper = new ObjectMapper();
try { try {
/* null empty strings on list objects */ /* null empty strings on list objects */
Map<String, Object> filteredData = new HashMap<>(); Map<String, Object> filteredData = new HashMap<>(data.size(), 1);
data.forEach((k, v) -> { data.forEach((k, v) -> {
if (!(v instanceof String && ((String) v).isEmpty())) { if (!(v instanceof String && ((String) v).isEmpty())) {
filteredData.put(k, v); filteredData.put(k, v);

View File

@ -22,7 +22,7 @@ import de.stklcode.jvault.connector.exception.InvalidResponseException;
import de.stklcode.jvault.connector.model.response.embedded.VersionMetadata; import de.stklcode.jvault.connector.model.response.embedded.VersionMetadata;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap; import java.util.Collections;
import java.util.Map; import java.util.Map;
/** /**
@ -66,7 +66,7 @@ public class SecretResponse extends VaultDataResponse {
*/ */
public final Map<String, Object> getData() { public final Map<String, Object> getData() {
if (data == null) { if (data == null) {
return new HashMap<>(); return Collections.emptyMap();
} }
return data; return data;
} }

View File

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

View File

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

View File

@ -29,19 +29,19 @@ import static org.hamcrest.core.Is.is;
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.6.2 * @since 0.6.2
*/ */
public class VaultConnectorExceptionTest { class VaultConnectorExceptionTest {
private static final String MSG = "This is a test exception!"; private static final String MSG = "This is a test exception!";
private static final Throwable CAUSE = new Exception("Test-Cause"); private static final Throwable CAUSE = new Exception("Test-Cause");
private static final Integer STATUS_CODE = 1337; private static final Integer STATUS_CODE = 1337;
private static final String RESPONSE = "Dummy response"; private static final String RESPONSE = "Dummy response";
@Test @Test
public void authorizationRequiredExceptionTest() { void authorizationRequiredExceptionTest() {
assertEmptyConstructor(new AuthorizationRequiredException()); assertEmptyConstructor(new AuthorizationRequiredException());
} }
@Test @Test
public void connectionExceptionTest() { void connectionExceptionTest() {
assertEmptyConstructor(new ConnectionException()); assertEmptyConstructor(new ConnectionException());
assertMsgConstructor(new ConnectionException(MSG)); assertMsgConstructor(new ConnectionException(MSG));
assertCauseConstructor(new ConnectionException(CAUSE)); assertCauseConstructor(new ConnectionException(CAUSE));
@ -49,7 +49,7 @@ public class VaultConnectorExceptionTest {
} }
@Test @Test
public void invalidRequestExceptionTest() { void invalidRequestExceptionTest() {
assertEmptyConstructor(new InvalidRequestException()); assertEmptyConstructor(new InvalidRequestException());
assertMsgConstructor(new InvalidRequestException(MSG)); assertMsgConstructor(new InvalidRequestException(MSG));
assertCauseConstructor(new InvalidRequestException(CAUSE)); assertCauseConstructor(new InvalidRequestException(CAUSE));
@ -57,7 +57,7 @@ public class VaultConnectorExceptionTest {
} }
@Test @Test
public void invalidResponseExceptionTest() { void invalidResponseExceptionTest() {
assertEmptyConstructor(new InvalidResponseException()); assertEmptyConstructor(new InvalidResponseException());
assertMsgConstructor(new InvalidResponseException(MSG)); assertMsgConstructor(new InvalidResponseException(MSG));
assertCauseConstructor(new InvalidResponseException(CAUSE)); assertCauseConstructor(new InvalidResponseException(CAUSE));
@ -93,7 +93,7 @@ public class VaultConnectorExceptionTest {
} }
@Test @Test
public void permissionDeniedExceptionTest() { void permissionDeniedExceptionTest() {
// Default message overwritten. // Default message overwritten.
PermissionDeniedException e = new PermissionDeniedException(); PermissionDeniedException e = new PermissionDeniedException();
assertThat(e, is(instanceOf(VaultConnectorException.class))); assertThat(e, is(instanceOf(VaultConnectorException.class)));
@ -108,7 +108,7 @@ public class VaultConnectorExceptionTest {
} }
@Test @Test
public void tlsExceptionTest() { void tlsExceptionTest() {
assertEmptyConstructor(new TlsException()); assertEmptyConstructor(new TlsException());
assertMsgConstructor(new TlsException(MSG)); assertMsgConstructor(new TlsException(MSG));
assertCauseConstructor(new TlsException(CAUSE)); assertCauseConstructor(new TlsException(CAUSE));

View File

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

View File

@ -33,7 +33,7 @@ import static org.hamcrest.Matchers.*;
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.4.0 * @since 0.4.0
*/ */
public class AppRoleBuilderTest { class AppRoleBuilderTest {
private static final String NAME = "TestRole"; private static final String NAME = "TestRole";
private static final String ID = "test-id"; private static final String ID = "test-id";
private static final Boolean BIND_SECRET_ID = true; private static final Boolean BIND_SECRET_ID = true;
@ -58,7 +58,7 @@ public class AppRoleBuilderTest {
NAME, ID, BIND_SECRET_ID, CIDR_1, SECRET_ID_NUM_USES, SECRET_ID_TTL, ENABLE_LOCAL_SECRET_IDS, TOKEN_TTL, TOKEN_MAX_TTL, POLICY, CIDR_1, TOKEN_EXPLICIT_MAX_TTL, TOKEN_NO_DEFAULT_POLICY, TOKEN_NUM_USES, TOKEN_PERIOD, TOKEN_TYPE.value()); NAME, ID, BIND_SECRET_ID, CIDR_1, SECRET_ID_NUM_USES, SECRET_ID_TTL, ENABLE_LOCAL_SECRET_IDS, TOKEN_TTL, TOKEN_MAX_TTL, POLICY, CIDR_1, TOKEN_EXPLICIT_MAX_TTL, TOKEN_NO_DEFAULT_POLICY, TOKEN_NUM_USES, TOKEN_PERIOD, TOKEN_TYPE.value());
@BeforeAll @BeforeAll
public static void init() { static void init() {
BOUND_CIDR_LIST.add(CIDR_1); BOUND_CIDR_LIST.add(CIDR_1);
POLICIES.add(POLICY); POLICIES.add(POLICY);
} }
@ -67,7 +67,7 @@ public class AppRoleBuilderTest {
* Build role with only a name. * Build role with only a name.
*/ */
@Test @Test
public void buildDefaultTest() throws JsonProcessingException { void buildDefaultTest() throws JsonProcessingException {
AppRole role = AppRole.builder(NAME).build(); AppRole role = AppRole.builder(NAME).build();
assertThat(role.getId(), is(nullValue())); assertThat(role.getId(), is(nullValue()));
assertThat(role.getBindSecretId(), is(nullValue())); assertThat(role.getBindSecretId(), is(nullValue()));
@ -95,7 +95,7 @@ public class AppRoleBuilderTest {
* Build role with only a name. * Build role with only a name.
*/ */
@Test @Test
public void legacyBuildDefaultTest() throws JsonProcessingException { void legacyBuildDefaultTest() throws JsonProcessingException {
AppRole role = new AppRoleBuilder(NAME).build(); AppRole role = new AppRoleBuilder(NAME).build();
assertThat(role.getId(), is(nullValue())); assertThat(role.getId(), is(nullValue()));
assertThat(role.getBindSecretId(), is(nullValue())); assertThat(role.getBindSecretId(), is(nullValue()));
@ -123,7 +123,7 @@ public class AppRoleBuilderTest {
* Build token without all parameters set. * Build token without all parameters set.
*/ */
@Test @Test
public void buildFullTest() throws JsonProcessingException { void buildFullTest() throws JsonProcessingException {
AppRole role = AppRole.builder(NAME) AppRole role = AppRole.builder(NAME)
.withId(ID) .withId(ID)
.withBindSecretID(BIND_SECRET_ID) .withBindSecretID(BIND_SECRET_ID)
@ -168,7 +168,7 @@ public class AppRoleBuilderTest {
* Build token without all parameters set. * Build token without all parameters set.
*/ */
@Test @Test
public void legacyBuildFullTest() throws JsonProcessingException { void legacyBuildFullTest() throws JsonProcessingException {
AppRole role = new AppRoleBuilder(NAME) AppRole role = new AppRoleBuilder(NAME)
.withId(ID) .withId(ID)
.withBindSecretID(BIND_SECRET_ID) .withBindSecretID(BIND_SECRET_ID)
@ -213,7 +213,7 @@ public class AppRoleBuilderTest {
* Test convenience methods * Test convenience methods
*/ */
@Test @Test
public void convenienceMethodsTest() { void convenienceMethodsTest() {
/* bind_secret_id */ /* bind_secret_id */
AppRole role = AppRole.builder(NAME).build(); AppRole role = AppRole.builder(NAME).build();
assertThat(role.getBindSecretId(), is(nullValue())); assertThat(role.getBindSecretId(), is(nullValue()));
@ -257,7 +257,7 @@ public class AppRoleBuilderTest {
* Test convenience methods * Test convenience methods
*/ */
@Test @Test
public void legacyConvenienceMethodsTest() { void legacyConvenienceMethodsTest() {
/* bind_secret_id */ /* bind_secret_id */
AppRole role = new AppRoleBuilder(NAME).build(); AppRole role = new AppRoleBuilder(NAME).build();
assertThat(role.getBindSecretId(), is(nullValue())); assertThat(role.getBindSecretId(), is(nullValue()));

View File

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

View File

@ -27,13 +27,13 @@ import static org.hamcrest.Matchers.is;
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.4.0 * @since 0.4.0
*/ */
public class AuthBackendTest { class AuthBackendTest {
/** /**
* Test forType() method. * Test forType() method.
*/ */
@Test @Test
public void forTypeTest() { void forTypeTest() {
assertThat(AuthBackend.forType("token"), is(AuthBackend.TOKEN)); assertThat(AuthBackend.forType("token"), is(AuthBackend.TOKEN));
assertThat(AuthBackend.forType("app-id"), is(AuthBackend.APPID)); assertThat(AuthBackend.forType("app-id"), is(AuthBackend.APPID));
assertThat(AuthBackend.forType("userpass"), is(AuthBackend.USERPASS)); assertThat(AuthBackend.forType("userpass"), is(AuthBackend.USERPASS));

View File

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

View File

@ -32,7 +32,7 @@ import static org.hamcrest.Matchers.*;
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.9 * @since 0.9
*/ */
public class TokenRoleBuilderTest { class TokenRoleBuilderTest {
private static final String NAME = "test-role"; private static final String NAME = "test-role";
private static final String ALLOWED_POLICY_1 = "apol-1"; private static final String ALLOWED_POLICY_1 = "apol-1";
private static final String ALLOWED_POLICY_2 = "apol-2"; private static final String ALLOWED_POLICY_2 = "apol-2";
@ -78,7 +78,7 @@ public class TokenRoleBuilderTest {
* Build token without any parameters. * Build token without any parameters.
*/ */
@Test @Test
public void buildDefaultTest() throws JsonProcessingException { void buildDefaultTest() throws JsonProcessingException {
TokenRole role = TokenRole.builder().build(); TokenRole role = TokenRole.builder().build();
assertThat(role.getAllowedPolicies(), is(nullValue())); assertThat(role.getAllowedPolicies(), is(nullValue()));
assertThat(role.getDisallowedPolicies(), is(nullValue())); assertThat(role.getDisallowedPolicies(), is(nullValue()));
@ -100,7 +100,7 @@ public class TokenRoleBuilderTest {
* Build token without all parameters NULL. * Build token without all parameters NULL.
*/ */
@Test @Test
public void buildNullTest() throws JsonProcessingException { void buildNullTest() throws JsonProcessingException {
TokenRole role = TokenRole.builder() TokenRole role = TokenRole.builder()
.forName(null) .forName(null)
.withAllowedPolicies(null) .withAllowedPolicies(null)
@ -141,7 +141,7 @@ public class TokenRoleBuilderTest {
* Build token without all parameters set. * Build token without all parameters set.
*/ */
@Test @Test
public void buildFullTest() throws JsonProcessingException { void buildFullTest() throws JsonProcessingException {
TokenRole role = TokenRole.builder() TokenRole role = TokenRole.builder()
.forName(NAME) .forName(NAME)
.withAllowedPolicies(ALLOWED_POLICIES) .withAllowedPolicies(ALLOWED_POLICIES)

View File

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

View File

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

View File

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

View File

@ -35,7 +35,7 @@ import static org.junit.jupiter.api.Assertions.fail;
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.8 * @since 0.8
*/ */
public class CredentialsResponseTest { class CredentialsResponseTest {
private static final Map<String, Object> DATA = new HashMap<>(); private static final Map<String, Object> DATA = new HashMap<>();
private static final String VAL_USER = "testUserName"; private static final String VAL_USER = "testUserName";
private static final String VAL_PASS = "5up3r5ecr3tP455"; private static final String VAL_PASS = "5up3r5ecr3tP455";
@ -52,7 +52,7 @@ public class CredentialsResponseTest {
*/ */
@Test @Test
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void getCredentialsTest() throws InvalidResponseException { void getCredentialsTest() throws InvalidResponseException {
// Create empty Object. // Create empty Object.
CredentialsResponse res = new CredentialsResponse(); CredentialsResponse res = new CredentialsResponse();
assertThat("Username not present in data map should not return anything", res.getUsername(), is(nullValue())); assertThat("Username not present in data map should not return anything", res.getUsername(), is(nullValue()));

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,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);
}
}
}