22 Commits

Author SHA1 Message Date
2412a291f6 prepare release of v1.1.1
All checks were successful
continuous-integration/drone/push Build is passing
2022-08-29 10:02:41 +02:00
b5ed7704e3 test: scan for "Vault server started" instead of fixed delay
All checks were successful
continuous-integration/drone/push Build is passing
2022-08-29 09:42:23 +02:00
a1626aa1c7 ci: fix drone CI pipeline
All checks were successful
continuous-integration/drone/push Build is passing
The Ubuntu Focal base image does not ship "unzip" by default, so using
the current Maven/JDK image we cannot extract the Vault binary.
Add an additional setup step to solve this problem.
2022-08-16 16:56:28 +02:00
3fb8454711 ci: update CI pipelines and test dependencies
Some checks failed
continuous-integration/drone/push Build is failing
2022-08-14 20:35:54 +02:00
ecf18881b9 test: extend assertion for warnings creating token with custom ID
All checks were successful
continuous-integration/drone/push Build is passing
With Vault 1.11 a second warning is raised. We accept "at least one"
for now.
2022-06-23 18:29:23 +02:00
69287f7196 deps: update jackson dependency to 2.13.2 2022-06-23 18:28:17 +02:00
4b1b4399e1 test against Vault 1.11.0 2022-06-23 18:16:40 +02:00
9ce819b1d0 prepare release of v1.1.0
All checks were successful
continuous-integration/drone/push Build is passing
2022-04-24 17:54:04 +02:00
64e55eddd8 model: add request ID to data response models
All checks were successful
continuous-integration/drone/push Build is passing
2022-04-24 16:44:50 +02:00
feb6e147fe model: add support for (dis)allowed policy glob patterns in TokenRole
All checks were successful
continuous-integration/drone/push Build is passing
2022-04-24 16:40:33 +02:00
b0d2b038eb model: add missing fields to AuthMethod model
All checks were successful
continuous-integration/drone/push Build is passing
2022-04-24 16:32:49 +02:00
f3cc16f44a test: bundle serialization tests into abstract test case
All checks were successful
continuous-integration/drone/push Build is passing
2022-04-19 17:24:17 +02:00
4f3cb4b330 model: eliminate double-mapping of generic data in response classes
Explicitly declare mapping of the "data" field in response classes.
Therefore, the JSON setter setData() is no longer used. SecretResponse
is split into subclasses for secret with and without metadata.
2022-04-19 17:24:16 +02:00
021421a54c model: implement Serializable with model classes
implement equals() and hashCode()
2022-04-19 17:24:09 +02:00
18cb89ace4 test: update to JRE8+ version of Wiremock with Junit5 extension
All checks were successful
continuous-integration/drone/push Build is passing
2022-04-12 21:01:40 +02:00
85aa5c3c30 deps: update Jackson Databind to 2.13.2.2 + minor plugin updates
All checks were successful
continuous-integration/drone/push Build is passing
2022-04-02 10:25:23 +02:00
912b9ec61b test: minor adjustments for integration tests against Vault 1.10
All checks were successful
continuous-integration/drone/push Build is passing
Accept token prefixes "hvb." and "b." as valid results for creation
without specific preferences.
2022-03-24 20:43:00 +01:00
bd0c5b08fe model: add wrap_info to data response model
All checks were successful
continuous-integration/drone/push Build is passing
2022-03-06 18:11:31 +01:00
5f3a36e2c5 update copyright notice to 2022 2022-03-06 18:10:33 +01:00
deb03cc2b0 minor dependency updates 2022-03-06 17:56:52 +01:00
f6180c4f90 model: add migration, recovery and storage type fields to seal status
All checks were successful
continuous-integration/drone/push Build is passing
2022-02-05 13:01:57 +01:00
dc4b62496a model: use correct "replication_performance_mode" JSON field
All checks were successful
continuous-integration/drone/push Build is passing
The official docs incorrectly state "replication_perf_mode" which was
renamed to "replication_performance_mode" way back in Vault 0.9. We now
use the correct field name that is emitted by the API.
2021-12-27 18:54:49 +01:00
81 changed files with 2072 additions and 677 deletions

View File

@ -3,7 +3,7 @@ name: default
steps: steps:
- name: compile - name: compile
image: maven:3-jdk-11 image: maven:3-openjdk-17
commands: commands:
- mvn -B clean compile - mvn -B clean compile
when: when:
@ -14,7 +14,7 @@ steps:
- fix/* - fix/*
- release/* - release/*
- name: unit-tests - name: unit-tests
image: maven:3-jdk-11 image: maven:3-openjdk-17
commands: commands:
- mvn -B test - mvn -B test
when: when:
@ -22,16 +22,27 @@ steps:
- develop - develop
- feature/* - feature/*
- fix/* - fix/*
- name: unit-integration-tests - name: setup-vault
image: maven:3-jdk-11 image: alpine:latest
environment: environment:
VAULT_VERSION: 1.9.0 VAULT_VERSION: 1.11.2
commands: commands:
- curl -s -o vault_1.9.0_linux_amd64.zip https://releases.hashicorp.com/vault/1.9.0/vault_1.9.0_linux_amd64.zip - wget -q -O vault_$${VAULT_VERSION}_linux_amd64.zip https://releases.hashicorp.com/vault/$${VAULT_VERSION}/vault_$${VAULT_VERSION}_linux_amd64.zip
- curl -s https://releases.hashicorp.com/vault/1.9.0/vault_1.9.0_SHA256SUMS | grep linux_amd64 | sha256sum -c - wget -q -O - https://releases.hashicorp.com/vault/$${VAULT_VERSION}/vault_$${VAULT_VERSION}_SHA256SUMS | grep linux_amd64 | sha256sum -c
- unzip vault_1.9.0_linux_amd64.zip - unzip vault_$${VAULT_VERSION}_linux_amd64.zip
- rm vault_1.9.0_linux_amd64.zip - rm vault_$${VAULT_VERSION}_linux_amd64.zip
- mv vault /bin/ - mkdir -p .bin
- mv vault .bin/
when:
branch:
- main
- release/*
- name: unit-integration-tests
image: maven:3-openjdk-17
environment:
VAULT_VERSION: 1.11.2
commands:
- export PATH=.bin:$${PATH}
- mvn -B -P integration-test verify - mvn -B -P integration-test verify
when: when:
branch: branch:

View File

@ -5,19 +5,19 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
matrix: matrix:
jdk: [ 11, 17 ] jdk: [ 11, 17, 18 ]
vault: [ '1.9.0' ] vault: [ '1.11.2' ]
include: include:
- jdk: 11 - jdk: 17
vault: '1.9.0' vault: '1.11.2'
analysis: true analysis: true
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v3
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Set up Java - name: Set up Java
uses: actions/setup-java@v2 uses: actions/setup-java@v3
with: with:
java-version: ${{ matrix.jdk }} java-version: ${{ matrix.jdk }}
distribution: 'temurin' distribution: 'temurin'

View File

@ -1,3 +1,32 @@
## 1.1.1 (2022-08-29)
### Dependencies
* Updated Jackson to 2.13.3
### Test
* Tested against Vault 1.11.2
* Tested with Java 18
## 1.1.0 (2022-04-24)
### Fix
* Use `replication_performance_mode` instead of `replication_perf_mode` in health response.
### Improvements
* Add `migration`, `recovery_seal` and `storage_type` fields to `SealReponse` model
* Add support for `wrap_info` in data response models
* Dependency updates
* Model and response classes implement `Serializable` (#57)
* Split `SercretResponse` into `PlainSecretResponse` and `MetaSecretResponse` subclasses (common API unchanged)
* Add missing fields to `AuthMethod` model
* Add support for (dis)allowed policy glob patterns in `TokenRole`
* Add request ID to data response models
### Test
* Tested against Vault 1.10.1
## 1.0.1 (2021-11-21) ## 1.0.1 (2021-11-21)
### Fix ### Fix

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.9.0 * Tested against Vault 1.11.2
## 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>1.0.1</version> <version>1.1.1</version>
</dependency> </dependency>
``` ```

44
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>1.0.1</version> <version>1.1.1</version>
<packaging>jar</packaging> <packaging>jar</packaging>
@ -50,7 +50,7 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version> <version>3.10.1</version>
<configuration> <configuration>
<source>11</source> <source>11</source>
<target>11</target> <target>11</target>
@ -62,17 +62,17 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-clean-plugin</artifactId> <artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version> <version>3.2.0</version>
</plugin> </plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId> <artifactId>maven-resources-plugin</artifactId>
<version>3.2.0</version> <version>3.3.0</version>
</plugin> </plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId> <artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version> <version>3.2.2</version>
<configuration> <configuration>
<archive> <archive>
<manifestEntries> <manifestEntries>
@ -84,12 +84,12 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId> <artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version> <version>3.0.1</version>
</plugin> </plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId> <artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version> <version>3.0.0</version>
</plugin> </plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
@ -116,31 +116,31 @@
<dependency> <dependency>
<groupId>com.fasterxml.jackson.core</groupId> <groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId> <artifactId>jackson-databind</artifactId>
<version>2.13.0</version> <version>2.13.3</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.8.1</version> <version>5.9.0</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.mockito</groupId> <groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId> <artifactId>mockito-core</artifactId>
<version>4.1.0</version> <version>4.7.0</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.github.stefanbirkner</groupId> <groupId>com.github.stefanbirkner</groupId>
<artifactId>system-lambda</artifactId> <artifactId>system-lambda</artifactId>
<version>1.2.0</version> <version>1.2.1</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.github.tomakehurst</groupId> <groupId>com.github.tomakehurst</groupId>
<artifactId>wiremock</artifactId> <artifactId>wiremock-jre8</artifactId>
<version>2.27.2</version> <version>2.33.2</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
@ -149,6 +149,18 @@
<version>2.11.0</version> <version>2.11.0</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>nl.jqno.equalsverifier</groupId>
<artifactId>equalsverifier</artifactId>
<version>3.10.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.awaitility</groupId>
<artifactId>awaitility</artifactId>
<version>4.2.0</version>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
<dependencyManagement> <dependencyManagement>
@ -197,7 +209,7 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId> <artifactId>maven-javadoc-plugin</artifactId>
<version>3.3.1</version> <version>3.4.1</version>
<configuration> <configuration>
<source>11</source> <source>11</source>
</configuration> </configuration>
@ -246,7 +258,7 @@
<plugin> <plugin>
<groupId>org.jacoco</groupId> <groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId> <artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.7</version> <version>0.8.8</version>
<executions> <executions>
<execution> <execution>
<id>default-prepare-agent</id> <id>default-prepare-agent</id>
@ -294,7 +306,7 @@
<plugin> <plugin>
<groupId>org.owasp</groupId> <groupId>org.owasp</groupId>
<artifactId>dependency-check-maven</artifactId> <artifactId>dependency-check-maven</artifactId>
<version>6.5.0</version> <version>7.1.2</version>
<executions> <executions>
<execution> <execution>
<goals> <goals>

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2021 Stefan Kalscheuer * Copyright 2016-2022 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -411,7 +411,7 @@ 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, emptyMap(), token, SecretResponse.class); return request.get(key, emptyMap(), token, PlainSecretResponse.class);
} }
@Override @Override
@ -423,7 +423,7 @@ public class HTTPVaultConnector implements VaultConnector {
args.put("version", version.toString()); args.put("version", version.toString());
} }
return request.get(mount + PATH_DATA + key, args, token, SecretResponse.class); return request.get(mount + PATH_DATA + key, args, token, MetaSecretResponse.class);
} }
@Override @Override

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2021 Stefan Kalscheuer * Copyright 2016-2022 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -18,17 +18,22 @@ package de.stklcode.jvault.connector.model;
import com.fasterxml.jackson.annotation.*; import com.fasterxml.jackson.annotation.*;
import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects;
/** /**
* Vault AppRole role metamodel. * Vault AppRole role metamodel.
* *
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.4.0 * @since 0.4.0
* @since 1.1 implements {@link Serializable}
*/ */
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
public final class AppRole { public final class AppRole implements Serializable {
private static final long serialVersionUID = -6248529625864573990L;
/** /**
* Get {@link Builder} instance. * Get {@link Builder} instance.
* *
@ -316,6 +321,39 @@ public final class AppRole {
return tokenType; return tokenType;
} }
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
} else if (o == null || getClass() != o.getClass()) {
return false;
}
AppRole appRole = (AppRole) o;
return Objects.equals(name, appRole.name) &&
Objects.equals(id, appRole.id) &&
Objects.equals(bindSecretId, appRole.bindSecretId) &&
Objects.equals(secretIdBoundCidrs, appRole.secretIdBoundCidrs) &&
Objects.equals(secretIdNumUses, appRole.secretIdNumUses) &&
Objects.equals(secretIdTtl, appRole.secretIdTtl) &&
Objects.equals(enableLocalSecretIds, appRole.enableLocalSecretIds) &&
Objects.equals(tokenTtl, appRole.tokenTtl) &&
Objects.equals(tokenMaxTtl, appRole.tokenMaxTtl) &&
Objects.equals(tokenPolicies, appRole.tokenPolicies) &&
Objects.equals(tokenBoundCidrs, appRole.tokenBoundCidrs) &&
Objects.equals(tokenExplicitMaxTtl, appRole.tokenExplicitMaxTtl) &&
Objects.equals(tokenNoDefaultPolicy, appRole.tokenNoDefaultPolicy) &&
Objects.equals(tokenNumUses, appRole.tokenNumUses) &&
Objects.equals(tokenPeriod, appRole.tokenPeriod) &&
Objects.equals(tokenType, appRole.tokenType);
}
@Override
public int hashCode() {
return Objects.hash(name, id, bindSecretId, secretIdBoundCidrs, secretIdNumUses, secretIdTtl,
enableLocalSecretIds, tokenTtl, tokenMaxTtl, tokenPolicies, tokenBoundCidrs, tokenExplicitMaxTtl,
tokenNoDefaultPolicy, tokenNumUses, tokenPeriod, tokenType);
}
/** /**
* A builder for vault AppRole roles.. * A builder for vault AppRole roles..

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2021 Stefan Kalscheuer * Copyright 2016-2022 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -18,17 +18,22 @@ package de.stklcode.jvault.connector.model;
import com.fasterxml.jackson.annotation.*; import com.fasterxml.jackson.annotation.*;
import java.io.Serializable;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects;
/** /**
* Vault AppRole role metamodel. * Vault AppRole role metamodel.
* *
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.4.0 * @since 0.4.0
* @since 1.1 implements {@link Serializable}
*/ */
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
public final class AppRoleSecret { public final class AppRoleSecret implements Serializable {
private static final long serialVersionUID = -3401074170145792641L;
@JsonProperty("secret_id") @JsonProperty("secret_id")
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
private String id; private String id;
@ -166,4 +171,29 @@ public final class AppRoleSecret {
public Integer getTtl() { public Integer getTtl() {
return ttl; return ttl;
} }
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
} else if (o == null || getClass() != o.getClass()) {
return false;
}
AppRoleSecret that = (AppRoleSecret) o;
return Objects.equals(id, that.id) &&
Objects.equals(accessor, that.accessor) &&
Objects.equals(metadata, that.metadata) &&
Objects.equals(cidrList, that.cidrList) &&
Objects.equals(creationTime, that.creationTime) &&
Objects.equals(expirationTime, that.expirationTime) &&
Objects.equals(lastUpdatedTime, that.lastUpdatedTime) &&
Objects.equals(numUses, that.numUses) &&
Objects.equals(ttl, that.ttl);
}
@Override
public int hashCode() {
return Objects.hash(id, accessor, metadata, cidrList, creationTime, expirationTime, lastUpdatedTime, numUses,
ttl);
}
} }

View File

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

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2021 Stefan Kalscheuer * Copyright 2016-2022 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -20,6 +20,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import java.io.Serializable;
import java.util.*; import java.util.*;
/** /**
@ -27,9 +28,12 @@ import java.util.*;
* *
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.4.0 * @since 0.4.0
* @since 1.1 implements {@link Serializable}
*/ */
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
public final class Token { public final class Token implements Serializable {
private static final long serialVersionUID = 5208508683665365287L;
/** /**
* Get {@link Builder} instance. * Get {@link Builder} instance.
* *
@ -214,6 +218,35 @@ public final class Token {
return entityAlias; return entityAlias;
} }
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
} else if (o == null || getClass() != o.getClass()) {
return false;
}
Token token = (Token) o;
return Objects.equals(id, token.id) &&
Objects.equals(type, token.type) &&
Objects.equals(displayName, token.displayName) &&
Objects.equals(noParent, token.noParent) &&
Objects.equals(noDefaultPolicy, token.noDefaultPolicy) &&
Objects.equals(ttl, token.ttl) &&
Objects.equals(explicitMaxTtl, token.explicitMaxTtl) &&
Objects.equals(numUses, token.numUses) &&
Objects.equals(policies, token.policies) &&
Objects.equals(meta, token.meta) &&
Objects.equals(renewable, token.renewable) &&
Objects.equals(period, token.period) &&
Objects.equals(entityAlias, token.entityAlias);
}
@Override
public int hashCode() {
return Objects.hash(id, type, displayName, noParent, noDefaultPolicy, ttl, explicitMaxTtl, numUses, policies,
meta, renewable, period, entityAlias);
}
/** /**
* Constants for token types. * Constants for token types.
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2021 Stefan Kalscheuer * Copyright 2016-2022 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -20,17 +20,22 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects;
/** /**
* Vault Token Role metamodel. * Vault Token Role metamodel.
* *
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.9 * @since 0.9
* @since 1.1 implements {@link Serializable}
*/ */
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
public final class TokenRole { public final class TokenRole implements Serializable {
private static final long serialVersionUID = -3505215215838576321L;
/** /**
* Get {@link Builder} instance. * Get {@link Builder} instance.
* *
@ -48,10 +53,18 @@ public final class TokenRole {
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
private List<String> allowedPolicies; private List<String> allowedPolicies;
@JsonProperty("allowed_policies_glob")
@JsonInclude(JsonInclude.Include.NON_NULL)
private List<String> allowedPoliciesGlob;
@JsonProperty("disallowed_policies") @JsonProperty("disallowed_policies")
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
private List<String> disallowedPolicies; private List<String> disallowedPolicies;
@JsonProperty("disallowed_policies_glob")
@JsonInclude(JsonInclude.Include.NON_NULL)
private List<String> disallowedPoliciesGlob;
@JsonProperty("orphan") @JsonProperty("orphan")
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
private Boolean orphan; private Boolean orphan;
@ -101,7 +114,9 @@ public final class TokenRole {
public TokenRole(final Builder builder) { public TokenRole(final Builder builder) {
this.name = builder.name; this.name = builder.name;
this.allowedPolicies = builder.allowedPolicies; this.allowedPolicies = builder.allowedPolicies;
this.allowedPoliciesGlob = builder.allowedPoliciesGlob;
this.disallowedPolicies = builder.disallowedPolicies; this.disallowedPolicies = builder.disallowedPolicies;
this.disallowedPoliciesGlob = builder.disallowedPoliciesGlob;
this.orphan = builder.orphan; this.orphan = builder.orphan;
this.renewable = builder.renewable; this.renewable = builder.renewable;
this.pathSuffix = builder.pathSuffix; this.pathSuffix = builder.pathSuffix;
@ -128,6 +143,14 @@ public final class TokenRole {
return allowedPolicies; return allowedPolicies;
} }
/**
* @return List of allowed policy glob patterns
* @since 1.1
*/
public List<String> getAllowedPoliciesGlob() {
return allowedPoliciesGlob;
}
/** /**
* @return List of disallowed policies * @return List of disallowed policies
*/ */
@ -135,6 +158,14 @@ public final class TokenRole {
return disallowedPolicies; return disallowedPolicies;
} }
/**
* @return List of disallowed policy glob patterns
* @since 1.1
*/
public List<String> getDisallowedPoliciesGlob() {
return disallowedPoliciesGlob;
}
/** /**
* @return Is Token Role orphan? * @return Is Token Role orphan?
*/ */
@ -205,6 +236,38 @@ public final class TokenRole {
return tokenType; return tokenType;
} }
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
} else if (o == null || getClass() != o.getClass()) {
return false;
}
TokenRole tokenRole = (TokenRole) o;
return Objects.equals(name, tokenRole.name) &&
Objects.equals(allowedPolicies, tokenRole.allowedPolicies) &&
Objects.equals(allowedPoliciesGlob, tokenRole.allowedPoliciesGlob) &&
Objects.equals(disallowedPolicies, tokenRole.disallowedPolicies) &&
Objects.equals(disallowedPoliciesGlob, tokenRole.disallowedPoliciesGlob) &&
Objects.equals(orphan, tokenRole.orphan) &&
Objects.equals(renewable, tokenRole.renewable) &&
Objects.equals(pathSuffix, tokenRole.pathSuffix) &&
Objects.equals(allowedEntityAliases, tokenRole.allowedEntityAliases) &&
Objects.equals(tokenBoundCidrs, tokenRole.tokenBoundCidrs) &&
Objects.equals(tokenExplicitMaxTtl, tokenRole.tokenExplicitMaxTtl) &&
Objects.equals(tokenNoDefaultPolicy, tokenRole.tokenNoDefaultPolicy) &&
Objects.equals(tokenNumUses, tokenRole.tokenNumUses) &&
Objects.equals(tokenPeriod, tokenRole.tokenPeriod) &&
Objects.equals(tokenType, tokenRole.tokenType);
}
@Override
public int hashCode() {
return Objects.hash(name, allowedPolicies, allowedPoliciesGlob, disallowedPolicies, disallowedPoliciesGlob,
orphan, renewable, pathSuffix, allowedEntityAliases, tokenBoundCidrs, tokenExplicitMaxTtl,
tokenNoDefaultPolicy, tokenNumUses, tokenPeriod, tokenType);
}
/** /**
* A builder for vault token roles. * A builder for vault token roles.
* *
@ -214,7 +277,9 @@ public final class TokenRole {
public static final class Builder { public static final class Builder {
private String name; private String name;
private List<String> allowedPolicies; private List<String> allowedPolicies;
private List<String> allowedPoliciesGlob;
private List<String> disallowedPolicies; private List<String> disallowedPolicies;
private List<String> disallowedPoliciesGlob;
private Boolean orphan; private Boolean orphan;
private Boolean renewable; private Boolean renewable;
private String pathSuffix; private String pathSuffix;
@ -269,6 +334,40 @@ public final class TokenRole {
return this; return this;
} }
/**
* Add an allowed policy glob pattern.
*
* @param allowedPolicyGlob allowed policy glob pattern to add
* @return self
* @since 1.1
*/
public Builder withAllowedPolicyGlob(final String allowedPolicyGlob) {
if (allowedPolicyGlob != null) {
if (this.allowedPoliciesGlob == null) {
this.allowedPoliciesGlob = new ArrayList<>();
}
this.allowedPoliciesGlob.add(allowedPolicyGlob);
}
return this;
}
/**
* Add allowed policy glob patterns.
*
* @param allowedPoliciesGlob list of allowed policy glob patterns
* @return self
* @since 1.1
*/
public Builder withAllowedPoliciesGlob(final List<String> allowedPoliciesGlob) {
if (allowedPoliciesGlob != null) {
if (this.allowedPoliciesGlob == null) {
this.allowedPoliciesGlob = new ArrayList<>();
}
this.allowedPoliciesGlob.addAll(allowedPoliciesGlob);
}
return this;
}
/** /**
* Add a disallowed policy. * Add a disallowed policy.
* *
@ -301,6 +400,40 @@ public final class TokenRole {
return this; return this;
} }
/**
* Add an allowed policy glob pattern.
*
* @param disallowedPolicyGlob disallowed policy glob pattern to add
* @return self
* @since 1.1
*/
public Builder withDisallowedPolicyGlob(final String disallowedPolicyGlob) {
if (disallowedPolicyGlob != null) {
if (this.disallowedPoliciesGlob == null) {
this.disallowedPoliciesGlob = new ArrayList<>();
}
this.disallowedPoliciesGlob.add(disallowedPolicyGlob);
}
return this;
}
/**
* Add disallowed policy glob patterns.
*
* @param disallowedPoliciesGlob list of disallowed policy glob patterns
* @return self
* @since 1.1
*/
public Builder withDisallowedPoliciesGlob(final List<String> disallowedPoliciesGlob) {
if (disallowedPoliciesGlob != null) {
if (this.disallowedPoliciesGlob == null) {
this.disallowedPoliciesGlob = new ArrayList<>();
}
this.disallowedPoliciesGlob.addAll(disallowedPoliciesGlob);
}
return this;
}
/** /**
* Set TRUE if the token role should be created orphan. * Set TRUE if the token role should be created orphan.
* *

View File

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

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2021 Stefan Kalscheuer * Copyright 2016-2022 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -17,13 +17,10 @@
package de.stklcode.jvault.connector.model.response; package de.stklcode.jvault.connector.model.response;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.annotation.JsonProperty;
import de.stklcode.jvault.connector.exception.InvalidResponseException;
import de.stklcode.jvault.connector.model.AppRole; import de.stklcode.jvault.connector.model.AppRole;
import java.io.IOException; import java.util.Objects;
import java.util.HashMap;
import java.util.Map;
/** /**
* Vault response for AppRole lookup. * Vault response for AppRole lookup.
@ -33,24 +30,10 @@ import java.util.Map;
*/ */
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
public final class AppRoleResponse extends VaultDataResponse { public final class AppRoleResponse extends VaultDataResponse {
private AppRole role; private static final long serialVersionUID = -6536422219633829177L;
@Override @JsonProperty("data")
public void setData(final Map<String, Object> data) throws InvalidResponseException { private AppRole role;
var mapper = new ObjectMapper();
try {
/* null empty strings on list objects */
Map<String, Object> filteredData = new HashMap<>(data.size(), 1);
data.forEach((k, v) -> {
if (!(v instanceof String && ((String) v).isEmpty())) {
filteredData.put(k, v);
}
});
this.role = mapper.readValue(mapper.writeValueAsString(filteredData), AppRole.class);
} catch (IOException e) {
throw new InvalidResponseException("Failed deserializing response", e);
}
}
/** /**
* @return The role * @return The role
@ -58,4 +41,20 @@ public final class AppRoleResponse extends VaultDataResponse {
public AppRole getRole() { public AppRole getRole() {
return role; return role;
} }
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
} else if (o == null || getClass() != o.getClass() || !super.equals(o)) {
return false;
}
AppRoleResponse that = (AppRoleResponse) o;
return Objects.equals(role, that.role);
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), role);
}
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2021 Stefan Kalscheuer * Copyright 2016-2022 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -17,13 +17,10 @@
package de.stklcode.jvault.connector.model.response; package de.stklcode.jvault.connector.model.response;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.annotation.JsonProperty;
import de.stklcode.jvault.connector.exception.InvalidResponseException;
import de.stklcode.jvault.connector.model.AppRoleSecret; import de.stklcode.jvault.connector.model.AppRoleSecret;
import java.io.IOException; import java.util.Objects;
import java.util.HashMap;
import java.util.Map;
/** /**
* Vault response for AppRole lookup. * Vault response for AppRole lookup.
@ -33,24 +30,10 @@ import java.util.Map;
*/ */
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
public final class AppRoleSecretResponse extends VaultDataResponse { public final class AppRoleSecretResponse extends VaultDataResponse {
private AppRoleSecret secret; private static final long serialVersionUID = -2484103304072370585L;
@Override @JsonProperty("data")
public void setData(final Map<String, Object> data) throws InvalidResponseException { private AppRoleSecret secret;
var mapper = new ObjectMapper();
try {
/* null empty strings on list objects */
Map<String, Object> filteredData = new HashMap<>(data.size(), 1);
data.forEach((k, v) -> {
if (!(v instanceof String && ((String) v).isEmpty())) {
filteredData.put(k, v);
}
});
this.secret = mapper.readValue(mapper.writeValueAsString(filteredData), AppRoleSecret.class);
} catch (IOException e) {
throw new InvalidResponseException("Failed deserializing response", e);
}
}
/** /**
* @return The secret * @return The secret
@ -58,4 +41,20 @@ public final class AppRoleSecretResponse extends VaultDataResponse {
public AppRoleSecret getSecret() { public AppRoleSecret getSecret() {
return secret; return secret;
} }
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
} else if (o == null || getClass() != o.getClass() || !super.equals(o)) {
return false;
}
AppRoleSecretResponse that = (AppRoleSecretResponse) o;
return Objects.equals(secret, that.secret);
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), secret);
}
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2021 Stefan Kalscheuer * Copyright 2016-2022 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -17,13 +17,12 @@
package de.stklcode.jvault.connector.model.response; package de.stklcode.jvault.connector.model.response;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.annotation.JsonProperty;
import de.stklcode.jvault.connector.exception.InvalidResponseException;
import de.stklcode.jvault.connector.model.response.embedded.AuthMethod; import de.stklcode.jvault.connector.model.response.embedded.AuthMethod;
import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Objects;
/** /**
* Authentication method response. * Authentication method response.
@ -33,6 +32,9 @@ import java.util.Map;
*/ */
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
public final class AuthMethodsResponse extends VaultDataResponse { public final class AuthMethodsResponse extends VaultDataResponse {
private static final long serialVersionUID = -1802724129533405375L;
@JsonProperty("data")
private Map<String, AuthMethod> supportedMethods; private Map<String, AuthMethod> supportedMethods;
/** /**
@ -42,23 +44,26 @@ public final class AuthMethodsResponse extends VaultDataResponse {
this.supportedMethods = new HashMap<>(); this.supportedMethods = new HashMap<>();
} }
@Override
public void setData(final Map<String, Object> data) throws InvalidResponseException {
var mapper = new ObjectMapper();
for (Map.Entry<String, Object> entry : data.entrySet()) {
try {
this.supportedMethods.put(entry.getKey(),
mapper.readValue(mapper.writeValueAsString(entry.getValue()), AuthMethod.class));
} catch (IOException e) {
throw new InvalidResponseException();
}
}
}
/** /**
* @return Supported authentication methods * @return Supported authentication methods
*/ */
public Map<String, AuthMethod> getSupportedMethods() { public Map<String, AuthMethod> getSupportedMethods() {
return supportedMethods; return supportedMethods;
} }
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
} else if (o == null || getClass() != o.getClass() || !super.equals(o)) {
return false;
}
AuthMethodsResponse that = (AuthMethodsResponse) o;
return Objects.equals(supportedMethods, that.supportedMethods);
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), supportedMethods);
}
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2021 Stefan Kalscheuer * Copyright 2016-2022 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -18,12 +18,9 @@ package de.stklcode.jvault.connector.model.response;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
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 java.io.IOException; import java.util.Objects;
import java.util.Map;
/** /**
* Vault response for authentication providing auth info in {@link AuthData} field. * Vault response for authentication providing auth info in {@link AuthData} field.
@ -33,37 +30,10 @@ import java.util.Map;
*/ */
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
public final class AuthResponse extends VaultDataResponse { public final class AuthResponse extends VaultDataResponse {
private Map<String, Object> data; private static final long serialVersionUID = 1628851361067456715L;
private AuthData auth;
/**
* Set authentication data. The input will be mapped to the {@link AuthData} model.
*
* @param auth Raw authentication data
* @throws InvalidResponseException on mapping errors
*/
@JsonProperty("auth") @JsonProperty("auth")
public void setAuth(final Map<String, Object> auth) throws InvalidResponseException { private AuthData auth;
var mapper = new ObjectMapper();
try {
this.auth = mapper.readValue(mapper.writeValueAsString(auth), AuthData.class);
} catch (IOException e) {
throw new InvalidResponseException("Failed deserializing response", e);
}
}
@Override
public void setData(final Map<String, Object> data) {
this.data = data;
}
/**
* @return Raw data
*/
public Map<String, Object> getData() {
return data;
}
/** /**
* @return Authentication data * @return Authentication data
@ -71,4 +41,20 @@ public final class AuthResponse extends VaultDataResponse {
public AuthData getAuth() { public AuthData getAuth() {
return auth; return auth;
} }
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
} else if (o == null || getClass() != o.getClass() || !super.equals(o)) {
return false;
}
AuthResponse that = (AuthResponse) o;
return Objects.equals(auth, that.auth);
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), auth);
}
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2021 Stefan Kalscheuer * Copyright 2016-2022 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -25,7 +25,8 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
* @since 0.5.0 * @since 0.5.0
*/ */
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
public final class CredentialsResponse extends SecretResponse { public final class CredentialsResponse extends PlainSecretResponse {
private static final long serialVersionUID = -1439692963299045425L;
/** /**
* @return Username * @return Username

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2021 Stefan Kalscheuer * Copyright 2016-2022 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -20,6 +20,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List; import java.util.List;
import java.util.Objects;
/** /**
* Vault response in case of errors. * Vault response in case of errors.
@ -29,6 +30,8 @@ import java.util.List;
*/ */
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
public final class ErrorResponse implements VaultResponse { public final class ErrorResponse implements VaultResponse {
private static final long serialVersionUID = -6227368087842549149L;
@JsonProperty("errors") @JsonProperty("errors")
private List<String> errors; private List<String> errors;
@ -47,4 +50,20 @@ public final class ErrorResponse implements VaultResponse {
return errors.get(0); return errors.get(0);
} }
} }
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
} else if (o == null || getClass() != o.getClass()) {
return false;
}
ErrorResponse that = (ErrorResponse) o;
return Objects.equals(errors, that.errors);
}
@Override
public int hashCode() {
return Objects.hash(errors);
}
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2021 Stefan Kalscheuer * Copyright 2016-2022 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -19,6 +19,8 @@ package de.stklcode.jvault.connector.model.response;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.Objects;
/** /**
* Vault response for health query. * Vault response for health query.
* *
@ -27,6 +29,8 @@ import com.fasterxml.jackson.annotation.JsonProperty;
*/ */
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
public final class HealthResponse implements VaultResponse { public final class HealthResponse implements VaultResponse {
private static final long serialVersionUID = 6483840078694294401L;
@JsonProperty("cluster_id") @JsonProperty("cluster_id")
private String clusterID; private String clusterID;
@ -48,7 +52,7 @@ public final class HealthResponse implements VaultResponse {
@JsonProperty("initialized") @JsonProperty("initialized")
private Boolean initialized; private Boolean initialized;
@JsonProperty("replication_perf_mode") @JsonProperty("replication_performance_mode")
private String replicationPerfMode; private String replicationPerfMode;
@JsonProperty("replication_dr_mode") @JsonProperty("replication_dr_mode")
@ -129,4 +133,30 @@ public final class HealthResponse implements VaultResponse {
public Boolean isPerformanceStandby() { public Boolean isPerformanceStandby() {
return performanceStandby; return performanceStandby;
} }
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
} else if (o == null || getClass() != o.getClass()) {
return false;
}
HealthResponse that = (HealthResponse) o;
return Objects.equals(clusterID, that.clusterID) &&
Objects.equals(clusterName, that.clusterName) &&
Objects.equals(version, that.version) &&
Objects.equals(serverTimeUTC, that.serverTimeUTC) &&
Objects.equals(standby, that.standby) &&
Objects.equals(sealed, that.sealed) &&
Objects.equals(initialized, that.initialized) &&
Objects.equals(replicationPerfMode, that.replicationPerfMode) &&
Objects.equals(replicationDrMode, that.replicationDrMode) &&
Objects.equals(performanceStandby, that.performanceStandby);
}
@Override
public int hashCode() {
return Objects.hash(clusterID, clusterName, version, serverTimeUTC, standby, sealed, initialized,
replicationPerfMode, replicationDrMode, performanceStandby);
}
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2021 Stefan Kalscheuer * Copyright 2016-2022 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -19,6 +19,8 @@ package de.stklcode.jvault.connector.model.response;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.Objects;
/** /**
* Vault response for help request. * Vault response for help request.
* *
@ -27,6 +29,8 @@ import com.fasterxml.jackson.annotation.JsonProperty;
*/ */
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
public final class HelpResponse implements VaultResponse { public final class HelpResponse implements VaultResponse {
private static final long serialVersionUID = -1152070966642848490L;
@JsonProperty("help") @JsonProperty("help")
private String help; private String help;
@ -36,4 +40,20 @@ public final class HelpResponse implements VaultResponse {
public String getHelp() { public String getHelp() {
return help; return help;
} }
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
} else if (o == null || getClass() != o.getClass()) {
return false;
}
HelpResponse that = (HelpResponse) o;
return Objects.equals(help, that.help);
}
@Override
public int hashCode() {
return Objects.hash(help);
}
} }

View File

@ -0,0 +1,75 @@
/*
* 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.model.response;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import de.stklcode.jvault.connector.model.response.embedded.SecretWrapper;
import de.stklcode.jvault.connector.model.response.embedded.VersionMetadata;
import java.io.Serializable;
import java.util.Collections;
import java.util.Map;
import java.util.Objects;
/**
* Vault response for secret responses with metadata.
*
* @author Stefan Kalscheuer
* @since 1.1 abstract
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class MetaSecretResponse extends SecretResponse {
private static final long serialVersionUID = -1076542846391240162L;
@JsonProperty("data")
private SecretWrapper secret;
@Override
public final Map<String, Serializable> getData() {
if (secret != null) {
return secret.getData();
} else {
return Collections.emptyMap();
}
}
@Override
public final VersionMetadata getMetadata() {
if (secret != null) {
return secret.getMetadata();
} else {
return null;
}
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
} else if (o == null || getClass() != o.getClass() || !super.equals(o)) {
return false;
}
MetaSecretResponse that = (MetaSecretResponse) o;
return Objects.equals(secret, that.secret);
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), secret);
}
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2021 Stefan Kalscheuer * Copyright 2016-2022 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -17,12 +17,11 @@
package de.stklcode.jvault.connector.model.response; package de.stklcode.jvault.connector.model.response;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.annotation.JsonProperty;
import de.stklcode.jvault.connector.exception.InvalidResponseException;
import de.stklcode.jvault.connector.model.response.embedded.SecretMetadata; import de.stklcode.jvault.connector.model.response.embedded.SecretMetadata;
import java.io.IOException; import java.util.Objects;
import java.util.Map;
/** /**
* Vault response for secret metadata (KV v2). * Vault response for secret metadata (KV v2).
@ -32,19 +31,11 @@ import java.util.Map;
*/ */
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
public class MetadataResponse extends VaultDataResponse { public class MetadataResponse extends VaultDataResponse {
private static final long serialVersionUID = -3679762333630984679L;
@JsonProperty("data")
private SecretMetadata metadata; private SecretMetadata metadata;
@Override
public final void setData(final Map<String, Object> data) throws InvalidResponseException {
var mapper = new ObjectMapper();
try {
this.metadata = mapper.readValue(mapper.writeValueAsString(data), SecretMetadata.class);
} catch (IOException e) {
throw new InvalidResponseException("Failed deserializing response", e);
}
}
/** /**
* Get the actual metadata. * Get the actual metadata.
* *
@ -53,4 +44,20 @@ public class MetadataResponse extends VaultDataResponse {
public SecretMetadata getMetadata() { public SecretMetadata getMetadata() {
return metadata; return metadata;
} }
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
} else if (o == null || getClass() != o.getClass() || !super.equals(o)) {
return false;
}
MetadataResponse that = (MetadataResponse) o;
return Objects.equals(metadata, that.metadata);
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), metadata);
}
} }

View File

@ -0,0 +1,66 @@
/*
* 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.model.response;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import de.stklcode.jvault.connector.model.response.embedded.VersionMetadata;
import java.io.Serializable;
import java.util.Collections;
import java.util.Map;
import java.util.Objects;
/**
* Vault response for plain secret responses.
*
* @author Stefan Kalscheuer
* @since 1.1 abstract
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class PlainSecretResponse extends SecretResponse {
private static final long serialVersionUID = 3010138542437913023L;
@JsonProperty("data")
private Map<String, Serializable> data;
@Override
public final Map<String, Serializable> getData() {
return Objects.requireNonNullElseGet(data, Collections::emptyMap);
}
@Override
public final VersionMetadata getMetadata() {
return null;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
} else if (o == null || getClass() != o.getClass() || !super.equals(o)) {
return false;
}
PlainSecretResponse that = (PlainSecretResponse) o;
return Objects.equals(data, that.data);
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), data);
}
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2021 Stefan Kalscheuer * Copyright 2016-2022 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -17,8 +17,11 @@
package de.stklcode.jvault.connector.model.response; package de.stklcode.jvault.connector.model.response;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.io.Serializable;
import java.util.Map; import java.util.Map;
import java.util.Objects;
/** /**
* Simple Vault data response. * Simple Vault data response.
@ -28,17 +31,31 @@ import java.util.Map;
*/ */
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
public final class RawDataResponse extends VaultDataResponse { public final class RawDataResponse extends VaultDataResponse {
private Map<String, Object> data; private static final long serialVersionUID = -319727427792124071L;
@Override @JsonProperty("data")
public void setData(final Map<String, Object> data) { private Map<String, Serializable> data;
this.data = data;
}
/** /**
* @return Raw data {@link Map} * @return Raw data {@link Map}
*/ */
public Map<String, Object> getData() { public Map<String, Serializable> getData() {
return data; return data;
} }
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
} else if (o == null || getClass() != o.getClass() || !super.equals(o)) {
return false;
}
RawDataResponse that = (RawDataResponse) o;
return Objects.equals(data, that.data);
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), data);
}
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2021 Stefan Kalscheuer * Copyright 2016-2022 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -19,6 +19,8 @@ package de.stklcode.jvault.connector.model.response;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.Objects;
/** /**
* Vault response for seal status or unseal request. * Vault response for seal status or unseal request.
* *
@ -27,6 +29,8 @@ import com.fasterxml.jackson.annotation.JsonProperty;
*/ */
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
public final class SealResponse implements VaultResponse { public final class SealResponse implements VaultResponse {
private static final long serialVersionUID = -3661916639367542617L;
@JsonProperty("type") @JsonProperty("type")
private String type; private String type;
@ -57,6 +61,15 @@ public final class SealResponse implements VaultResponse {
@JsonProperty("cluster_id") @JsonProperty("cluster_id")
private String clusterId; private String clusterId;
@JsonProperty("migration")
private Boolean migration;
@JsonProperty("recovery_seal")
private Boolean recoverySeal;
@JsonProperty("storage_type")
private String storageType;
/** /**
* @return Seal type. * @return Seal type.
* @since 0.8 * @since 0.8
@ -132,4 +145,57 @@ public final class SealResponse implements VaultResponse {
public String getClusterId() { public String getClusterId() {
return clusterId; return clusterId;
} }
/**
* @return Migration status (since Vault 1.4)
* @since 1.1
*/
public Boolean getMigration() {
return migration;
}
/**
* @return Recovery seal status.
* @since 1.1
*/
public Boolean getRecoverySeal() {
return recoverySeal;
}
/**
* @return Storage type (since Vault 1.3).
* @since 1.1
*/
public String getStorageType() {
return storageType;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
} else if (o == null || getClass() != o.getClass()) {
return false;
}
SealResponse that = (SealResponse) o;
return sealed == that.sealed &&
initialized == that.initialized &&
Objects.equals(type, that.type) &&
Objects.equals(threshold, that.threshold) &&
Objects.equals(numberOfShares, that.numberOfShares) &&
Objects.equals(progress, that.progress) &&
Objects.equals(version, that.version) &&
Objects.equals(nonce, that.nonce) &&
Objects.equals(clusterName, that.clusterName) &&
Objects.equals(clusterId, that.clusterId) &&
Objects.equals(migration, that.migration) &&
Objects.equals(recoverySeal, that.recoverySeal) &&
Objects.equals(storageType, that.storageType);
}
@Override
public int hashCode() {
return Objects.hash(type, sealed, initialized, threshold, numberOfShares, progress, version, nonce,
clusterName, clusterId, migration, recoverySeal, storageType);
}
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2021 Stefan Kalscheuer * Copyright 2016-2022 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -18,10 +18,11 @@ package de.stklcode.jvault.connector.model.response;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import de.stklcode.jvault.connector.exception.InvalidResponseException; import de.stklcode.jvault.connector.model.response.embedded.SecretListWrapper;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Objects;
/** /**
* Vault response for secret list request. * Vault response for secret list request.
@ -31,27 +32,34 @@ import java.util.Map;
*/ */
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
public final class SecretListResponse extends VaultDataResponse { public final class SecretListResponse extends VaultDataResponse {
private List<String> keys;
/** private static final long serialVersionUID = 8597121175002967213L;
* Set data. Extracts list of keys from raw response data.
*
* @param data Raw data
* @throws InvalidResponseException on parsing errors
*/
@JsonProperty("data") @JsonProperty("data")
public void setData(final Map<String, Object> data) throws InvalidResponseException { private SecretListWrapper data;
try {
this.keys = (List<String>) data.get("keys");
} catch (ClassCastException e) {
throw new InvalidResponseException("Keys could not be parsed from data.", e);
}
}
/** /**
* @return List of secret keys * @return List of secret keys
*/ */
public List<String> getKeys() { public List<String> getKeys() {
return keys; if (data == null) {
return Collections.emptyList();
}
return Objects.requireNonNullElseGet(data.getKeys(), Collections::emptyList);
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
} else if (o == null || getClass() != o.getClass() || !super.equals(o)) {
return false;
}
SecretListResponse that = (SecretListResponse) o;
return Objects.equals(data, that.data);
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), data);
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2021 Stefan Kalscheuer * Copyright 2016-2022 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -22,7 +22,7 @@ import de.stklcode.jvault.connector.exception.InvalidResponseException;
import de.stklcode.jvault.connector.model.response.embedded.VersionMetadata; import de.stklcode.jvault.connector.model.response.embedded.VersionMetadata;
import java.io.IOException; import java.io.IOException;
import java.util.Collections; import java.io.Serializable;
import java.util.Map; import java.util.Map;
/** /**
@ -30,46 +30,20 @@ import java.util.Map;
* *
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.1 * @since 0.1
* @since 1.1 abstract
*/ */
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
public class SecretResponse extends VaultDataResponse { public abstract class SecretResponse extends VaultDataResponse {
private static final String KEY_DATA = "data"; private static final long serialVersionUID = 5198088815871692951L;
private static final String KEY_METADATA = "metadata";
private Map<String, Object> data;
private VersionMetadata metadata;
@Override
public final void setData(final Map<String, Object> data) throws InvalidResponseException {
if (data.size() == 2
&& data.containsKey(KEY_DATA) && data.get(KEY_DATA) instanceof Map
&& data.containsKey(KEY_METADATA) && data.get(KEY_METADATA) instanceof Map) {
var mapper = new ObjectMapper();
try {
// This is apparently a KV v2 value.
this.data = (Map<String, Object>) data.get(KEY_DATA);
this.metadata = mapper.readValue(mapper.writeValueAsString(data.get(KEY_METADATA)), VersionMetadata.class);
} catch (ClassCastException | IOException e) {
throw new InvalidResponseException("Failed deserializing response", e);
}
} else {
// For KV v1 without metadata just store the data map.
this.data = data;
}
}
/** /**
* Get complete data object. * Get complete data object.
* *
* @return data map * @return data map
* @since 0.4.0 * @since 0.4.0
* @since 1.1 Serializable map value.
*/ */
public final Map<String, Object> getData() { public abstract Map<String, Serializable> getData();
if (data == null) {
return Collections.emptyMap();
}
return data;
}
/** /**
* Get secret metadata. This is only available for KV v2 secrets. * Get secret metadata. This is only available for KV v2 secrets.
@ -77,9 +51,7 @@ public class SecretResponse extends VaultDataResponse {
* @return Metadata of the secret. * @return Metadata of the secret.
* @since 0.8 * @since 0.8
*/ */
public final VersionMetadata getMetadata() { public abstract VersionMetadata getMetadata();
return metadata;
}
/** /**
* Get a single value for given key. * Get a single value for given key.
@ -89,9 +61,6 @@ public class SecretResponse extends VaultDataResponse {
* @since 0.4.0 * @since 0.4.0
*/ */
public final Object get(final String key) { public final Object get(final String key) {
if (data == null) {
return null;
}
return getData().get(key); return getData().get(key);
} }
@ -100,12 +69,12 @@ public class SecretResponse extends VaultDataResponse {
* *
* @param key the key * @param key the key
* @param type Class to parse response * @param type Class to parse response
* @param <T> Class to parse response * @param <C> Class to parse response
* @return Parsed object or {@code null} if absent * @return Parsed object or {@code null} if absent
* @throws InvalidResponseException on parsing error * @throws InvalidResponseException on parsing error
* @since 0.4.0 * @since 0.4.0
*/ */
public final <T> T get(final String key, final Class<T> type) throws InvalidResponseException { public final <C> C get(final String key, final Class<C> type) throws InvalidResponseException {
try { try {
Object rawValue = get(key); Object rawValue = get(key);
if (rawValue == null) { if (rawValue == null) {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2021 Stefan Kalscheuer * Copyright 2016-2022 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -17,12 +17,10 @@
package de.stklcode.jvault.connector.model.response; package de.stklcode.jvault.connector.model.response;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.annotation.JsonProperty;
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.util.Objects;
import java.util.Map;
/** /**
* Vault response for a single secret version metadata, i.e. after update (KV v2). * Vault response for a single secret version metadata, i.e. after update (KV v2).
@ -32,19 +30,11 @@ import java.util.Map;
*/ */
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
public class SecretVersionResponse extends VaultDataResponse { public class SecretVersionResponse extends VaultDataResponse {
private static final long serialVersionUID = 2748635005258576174L;
@JsonProperty("data")
private VersionMetadata metadata; private VersionMetadata metadata;
@Override
public final void setData(final Map<String, Object> data) throws InvalidResponseException {
var mapper = new ObjectMapper();
try {
this.metadata = mapper.readValue(mapper.writeValueAsString(data), VersionMetadata.class);
} catch (IOException e) {
throw new InvalidResponseException("Failed deserializing response", e);
}
}
/** /**
* Get the actual metadata. * Get the actual metadata.
* *
@ -53,4 +43,20 @@ public class SecretVersionResponse extends VaultDataResponse {
public VersionMetadata getMetadata() { public VersionMetadata getMetadata() {
return metadata; return metadata;
} }
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
} else if (o == null || getClass() != o.getClass() || !super.equals(o)) {
return false;
}
SecretVersionResponse that = (SecretVersionResponse) o;
return Objects.equals(metadata, that.metadata);
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), metadata);
}
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2021 Stefan Kalscheuer * Copyright 2016-2022 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -18,12 +18,9 @@ package de.stklcode.jvault.connector.model.response;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
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 java.io.IOException; import java.util.Objects;
import java.util.Map;
/** /**
* Vault response from token lookup providing Token information in {@link TokenData} field. * Vault response from token lookup providing Token information in {@link TokenData} field.
@ -33,31 +30,41 @@ import java.util.Map;
*/ */
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
public final class TokenResponse extends VaultDataResponse { public final class TokenResponse extends VaultDataResponse {
private static final long serialVersionUID = -4053126653764241197L;
@JsonProperty("data")
private TokenData data; private TokenData data;
@JsonProperty("auth") @JsonProperty("auth")
private Boolean auth; private Boolean auth;
/**
* Set data. Parses response data map to {@link TokenData}.
*
* @param data Raw response data
* @throws InvalidResponseException on parsing errors
*/
@Override
public void setData(final Map<String, Object> data) throws InvalidResponseException {
var mapper = new ObjectMapper();
try {
this.data = mapper.readValue(mapper.writeValueAsString(data), TokenData.class);
} catch (IOException e) {
throw new InvalidResponseException("Failed deserializing response", e);
}
}
/** /**
* @return Token data * @return Token data
*/ */
public TokenData getData() { public TokenData getData() {
return data; return data;
} }
/**
* @return Auth data
*/
public Boolean getAuth() {
return auth;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
} else if (o == null || getClass() != o.getClass() || !super.equals(o)) {
return false;
}
TokenResponse that = (TokenResponse) o;
return Objects.equals(data, that.data) && Objects.equals(auth, that.auth);
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), data, auth);
}
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2021 Stefan Kalscheuer * Copyright 2016-2022 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -17,13 +17,11 @@
package de.stklcode.jvault.connector.model.response; package de.stklcode.jvault.connector.model.response;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.annotation.JsonProperty;
import de.stklcode.jvault.connector.exception.InvalidResponseException;
import de.stklcode.jvault.connector.model.TokenRole; import de.stklcode.jvault.connector.model.TokenRole;
import de.stklcode.jvault.connector.model.response.embedded.TokenData; import de.stklcode.jvault.connector.model.response.embedded.TokenData;
import java.io.IOException; import java.util.Objects;
import java.util.Map;
/** /**
* Vault response from token role lookup providing Token information in {@link TokenData} field. * Vault response from token role lookup providing Token information in {@link TokenData} field.
@ -33,23 +31,10 @@ import java.util.Map;
*/ */
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
public final class TokenRoleResponse extends VaultDataResponse { public final class TokenRoleResponse extends VaultDataResponse {
private TokenRole data; private static final long serialVersionUID = 5265363857731948626L;
/** @JsonProperty("data")
* Set data. Parses response data map to {@link TokenRole}. private TokenRole data;
*
* @param data Raw response data
* @throws InvalidResponseException on parsing errors
*/
@Override
public void setData(final Map<String, Object> data) throws InvalidResponseException {
var mapper = new ObjectMapper();
try {
this.data = mapper.readValue(mapper.writeValueAsString(data), TokenRole.class);
} catch (IOException e) {
throw new InvalidResponseException("Failed deserializing response", e);
}
}
/** /**
* @return TokenRole data * @return TokenRole data
@ -57,4 +42,20 @@ public final class TokenRoleResponse extends VaultDataResponse {
public TokenRole getData() { public TokenRole getData() {
return data; return data;
} }
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
} else if (o == null || getClass() != o.getClass() || !super.equals(o)) {
return false;
}
TokenRoleResponse that = (TokenRoleResponse) o;
return Objects.equals(data, that.data);
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), data);
}
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2021 Stefan Kalscheuer * Copyright 2016-2022 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -17,10 +17,10 @@
package de.stklcode.jvault.connector.model.response; package de.stklcode.jvault.connector.model.response;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import de.stklcode.jvault.connector.exception.InvalidResponseException; import de.stklcode.jvault.connector.model.response.embedded.WrapInfo;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Objects;
/** /**
* Abstract Vault response with default payload fields. * Abstract Vault response with default payload fields.
@ -29,6 +29,11 @@ import java.util.Map;
* @since 0.1 * @since 0.1
*/ */
public abstract class VaultDataResponse implements VaultResponse { public abstract class VaultDataResponse implements VaultResponse {
private static final long serialVersionUID = 7486270767477652184L;
@JsonProperty("request_id")
private String requestId;
@JsonProperty("lease_id") @JsonProperty("lease_id")
private String leaseId; private String leaseId;
@ -41,14 +46,16 @@ public abstract class VaultDataResponse implements VaultResponse {
@JsonProperty("warnings") @JsonProperty("warnings")
private List<String> warnings; private List<String> warnings;
@JsonProperty("wrap_info")
private WrapInfo wrapInfo;
/** /**
* Set data. To be implemented in the specific subclasses, as data can be of arbitrary structure. * @return Request ID
* * @since 1.1
* @param data Raw response data
* @throws InvalidResponseException on parsing errors
*/ */
@JsonProperty("data") public final String getRequestId() {
public abstract void setData(final Map<String, Object> data) throws InvalidResponseException; return requestId;
}
/** /**
* @return Lease ID * @return Lease ID
@ -77,4 +84,33 @@ public abstract class VaultDataResponse implements VaultResponse {
public final List<String> getWarnings() { public final List<String> getWarnings() {
return warnings; return warnings;
} }
/**
* @return Wrapping information
* @since 1.1
*/
public final WrapInfo getWrapInfo() {
return wrapInfo;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
} else if (o == null || getClass() != o.getClass()) {
return false;
}
VaultDataResponse that = (VaultDataResponse) o;
return renewable == that.renewable &&
Objects.equals(requestId, that.requestId) &&
Objects.equals(leaseId, that.leaseId) &&
Objects.equals(leaseDuration, that.leaseDuration) &&
Objects.equals(warnings, that.warnings) &&
Objects.equals(wrapInfo, that.wrapInfo);
}
@Override
public int hashCode() {
return Objects.hash(requestId, leaseId, renewable, leaseDuration, warnings, wrapInfo);
}
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2021 Stefan Kalscheuer * Copyright 2016-2022 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,11 +16,14 @@
package de.stklcode.jvault.connector.model.response; package de.stklcode.jvault.connector.model.response;
import java.io.Serializable;
/** /**
* Marker interface for responses from Vault backend. * Marker interface for responses from Vault backend.
* *
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.1 * @since 0.1
* @since 1.1 extends {@link Serializable}
*/ */
public interface VaultResponse { public interface VaultResponse extends Serializable {
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2021 Stefan Kalscheuer * Copyright 2016-2022 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -19,17 +19,22 @@ package de.stklcode.jvault.connector.model.response.embedded;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import java.io.Serializable;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects;
/** /**
* Embedded authorization information inside Vault response. * Embedded authorization information inside Vault response.
* *
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.1 * @since 0.1
* @since 1.1 implements {@link Serializable}
*/ */
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
public final class AuthData { public final class AuthData implements Serializable {
private static final long serialVersionUID = -6962244199229885869L;
@JsonProperty("client_token") @JsonProperty("client_token")
private String clientToken; private String clientToken;
@ -133,4 +138,31 @@ public final class AuthData {
public boolean isOrphan() { public boolean isOrphan() {
return orphan; return orphan;
} }
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
AuthData authData = (AuthData) o;
return renewable == authData.renewable &&
orphan == authData.orphan &&
Objects.equals(clientToken, authData.clientToken) &&
Objects.equals(accessor, authData.accessor) &&
Objects.equals(policies, authData.policies) &&
Objects.equals(tokenPolicies, authData.tokenPolicies) &&
Objects.equals(metadata, authData.metadata) &&
Objects.equals(leaseDuration, authData.leaseDuration) &&
Objects.equals(entityId, authData.entityId) &&
Objects.equals(tokenType, authData.tokenType);
}
@Override
public int hashCode() {
return Objects.hash(clientToken, accessor, policies, tokenPolicies, metadata, leaseDuration, renewable,
entityId, tokenType, orphan);
}
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2021 Stefan Kalscheuer * Copyright 2016-2022 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -21,28 +21,45 @@ import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonSetter; import com.fasterxml.jackson.annotation.JsonSetter;
import de.stklcode.jvault.connector.model.AuthBackend; import de.stklcode.jvault.connector.model.AuthBackend;
import java.io.Serializable;
import java.util.Map; import java.util.Map;
import java.util.Objects;
/** /**
* Embedded authentication method response. * Embedded authentication method response.
* *
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.1 * @since 0.1
* @since 1.1 implements {@link Serializable}
*/ */
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
public final class AuthMethod { public final class AuthMethod implements Serializable {
private static final long serialVersionUID = -2718660627880077335L;
private AuthBackend type; private AuthBackend type;
private String rawType; private String rawType;
@JsonProperty("accessor")
private String accessor;
@JsonProperty("description") @JsonProperty("description")
private String description; private String description;
@JsonProperty("config") @JsonProperty("config")
private Map<String, String> config; private Map<String, String> config;
@JsonProperty("external_entropy_access")
private boolean externalEntropyAccess;
@JsonProperty("local") @JsonProperty("local")
private boolean local; private boolean local;
@JsonProperty("seal_wrap")
private boolean sealWrap;
@JsonProperty("uuid")
private String uuid;
/** /**
* @param type Backend type, passed to {@link AuthBackend#forType(String)} * @param type Backend type, passed to {@link AuthBackend#forType(String)}
*/ */
@ -66,6 +83,14 @@ public final class AuthMethod {
return rawType; return rawType;
} }
/**
* @return Accessor
* @since 1.1
*/
public String getAccessor() {
return accessor;
}
/** /**
* @return Description * @return Description
*/ */
@ -80,10 +105,58 @@ public final class AuthMethod {
return config; return config;
} }
/**
* @return Backend has access to external entropy source
* @since 1.1
*/
public boolean isExternalEntropyAccess() {
return externalEntropyAccess;
}
/** /**
* @return Is local backend * @return Is local backend
*/ */
public boolean isLocal() { public boolean isLocal() {
return local; return local;
} }
/**
* @return Seal wrapping enabled
* @since 1.1
*/
public boolean isSealWrap() {
return sealWrap;
}
/**
* @return Backend UUID
* @since 1.1
*/
public String getUuid() {
return uuid;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
} else if (o == null || getClass() != o.getClass()) {
return false;
}
AuthMethod that = (AuthMethod) o;
return local == that.local &&
type == that.type &&
externalEntropyAccess == that.externalEntropyAccess &&
sealWrap == that.sealWrap &&
Objects.equals(rawType, that.rawType) &&
Objects.equals(accessor, that.accessor) &&
Objects.equals(description, that.description) &&
Objects.equals(config, that.config) &&
Objects.equals(uuid, that.uuid);
}
@Override
public int hashCode() {
return Objects.hash(type, rawType, accessor, description, config, externalEntropyAccess, local, sealWrap, uuid);
}
} }

View File

@ -0,0 +1,42 @@
package de.stklcode.jvault.connector.model.response.embedded;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.io.Serializable;
import java.util.List;
import java.util.Objects;
/**
* Wrapper object for secret key lists.
*
* @author Stefan Kalscheuer
* @since 1.1
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class SecretListWrapper implements Serializable {
private static final long serialVersionUID = -8777605197063766125L;
@JsonProperty("keys")
private List<String> keys;
public List<String> getKeys() {
return keys;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
} else if (o == null || getClass() != o.getClass()) {
return false;
}
SecretListWrapper that = (SecretListWrapper) o;
return Objects.equals(keys, that.keys);
}
@Override
public int hashCode() {
return Objects.hash(keys);
}
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2021 Stefan Kalscheuer * Copyright 2016-2022 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -19,19 +19,24 @@ package de.stklcode.jvault.connector.model.response.embedded;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import java.io.Serializable;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException; import java.time.format.DateTimeParseException;
import java.util.Map; import java.util.Map;
import java.util.Objects;
/** /**
* Embedded metadata for Key-Value v2 secrets. * Embedded metadata for Key-Value v2 secrets.
* *
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.8 * @since 0.8
* @since 1.1 implements {@link Serializable}
*/ */
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
public final class SecretMetadata { public final class SecretMetadata implements Serializable {
private static final long serialVersionUID = 1684891108903409038L;
private static final DateTimeFormatter TIME_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSSSSSX"); private static final DateTimeFormatter TIME_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSSSSSX");
@JsonProperty("created_time") @JsonProperty("created_time")
@ -124,4 +129,24 @@ public final class SecretMetadata {
return versions; return versions;
} }
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
} else if (o == null || getClass() != o.getClass()) {
return false;
}
SecretMetadata that = (SecretMetadata) o;
return Objects.equals(createdTimeString, that.createdTimeString) &&
Objects.equals(currentVersion, that.currentVersion) &&
Objects.equals(maxVersions, that.maxVersions) &&
Objects.equals(oldestVersion, that.oldestVersion) &&
Objects.equals(updatedTime, that.updatedTime) &&
Objects.equals(versions, that.versions);
}
@Override
public int hashCode() {
return Objects.hash(createdTimeString, currentVersion, maxVersions, oldestVersion, updatedTime, versions);
}
} }

View File

@ -0,0 +1,49 @@
package de.stklcode.jvault.connector.model.response.embedded;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.io.Serializable;
import java.util.Map;
import java.util.Objects;
/**
* Wrapper object for secret data and metadata.
*
* @author Stefan Kalscheuer
* @since 1.1
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class SecretWrapper implements Serializable {
private static final long serialVersionUID = 8600413181758893378L;
@JsonProperty("data")
private Map<String, Serializable> data;
@JsonProperty("metadata")
private VersionMetadata metadata;
public Map<String, Serializable> getData() {
return data;
}
public VersionMetadata getMetadata() {
return metadata;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
} else if (o == null || getClass() != o.getClass()) {
return false;
}
SecretWrapper that = (SecretWrapper) o;
return Objects.equals(data, that.data) && Objects.equals(metadata, that.metadata);
}
@Override
public int hashCode() {
return Objects.hash(data, metadata);
}
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2021 Stefan Kalscheuer * Copyright 2016-2022 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -19,18 +19,23 @@ package de.stklcode.jvault.connector.model.response.embedded;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import java.io.Serializable;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects;
/** /**
* Embedded token information inside Vault response. * Embedded token information inside Vault response.
* *
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.1 * @since 0.1
* @since 1.1 implements {@link Serializable}
*/ */
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
public final class TokenData { public final class TokenData implements Serializable {
private static final long serialVersionUID = 2915180734313753649L;
@JsonProperty("accessor") @JsonProperty("accessor")
private String accessor; private String accessor;
@ -231,4 +236,37 @@ public final class TokenData {
public Map<String, Object> getMeta() { public Map<String, Object> getMeta() {
return meta; return meta;
} }
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
} else if (o == null || getClass() != o.getClass()) {
return false;
}
TokenData tokenData = (TokenData) o;
return orphan == tokenData.orphan &&
renewable == tokenData.renewable &&
Objects.equals(accessor, tokenData.accessor) &&
Objects.equals(creationTime, tokenData.creationTime) &&
Objects.equals(creationTtl, tokenData.creationTtl) &&
Objects.equals(name, tokenData.name) &&
Objects.equals(entityId, tokenData.entityId) &&
Objects.equals(expireTime, tokenData.expireTime) &&
Objects.equals(explicitMaxTtl, tokenData.explicitMaxTtl) &&
Objects.equals(id, tokenData.id) &&
Objects.equals(issueTime, tokenData.issueTime) &&
Objects.equals(meta, tokenData.meta) &&
Objects.equals(numUses, tokenData.numUses) &&
Objects.equals(path, tokenData.path) &&
Objects.equals(policies, tokenData.policies) &&
Objects.equals(ttl, tokenData.ttl) &&
Objects.equals(type, tokenData.type);
}
@Override
public int hashCode() {
return Objects.hash(accessor, creationTime, creationTtl, name, entityId, expireTime, explicitMaxTtl, id,
issueTime, meta, numUses, orphan, path, policies, renewable, ttl, type);
}
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2021 Stefan Kalscheuer * Copyright 2016-2022 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -19,18 +19,23 @@ package de.stklcode.jvault.connector.model.response.embedded;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import java.io.Serializable;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException; import java.time.format.DateTimeParseException;
import java.util.Objects;
/** /**
* Embedded metadata for a single Key-Value v2 version. * Embedded metadata for a single Key-Value v2 version.
* *
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.8 * @since 0.8
* @since 1.1 implements {@link Serializable}
*/ */
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
public final class VersionMetadata { public final class VersionMetadata implements Serializable {
private static final long serialVersionUID = -5286693953873839611L;
private static final DateTimeFormatter TIME_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSSSSSX"); private static final DateTimeFormatter TIME_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSSSSSX");
@JsonProperty("created_time") @JsonProperty("created_time")
@ -103,4 +108,22 @@ public final class VersionMetadata {
return version; return version;
} }
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
} else if (o == null || getClass() != o.getClass()) {
return false;
}
VersionMetadata that = (VersionMetadata) o;
return destroyed == that.destroyed &&
Objects.equals(createdTimeString, that.createdTimeString) &&
Objects.equals(deletionTimeString, that.deletionTimeString) &&
Objects.equals(version, that.version);
}
@Override
public int hashCode() {
return Objects.hash(createdTimeString, deletionTimeString, destroyed, version);
}
} }

View File

@ -0,0 +1,91 @@
/*
* Copyright 2016-2022 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.model.response.embedded;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.io.Serializable;
import java.util.Objects;
/**
* Wrapping information object.
*
* @author Stefan Kalscheuer
* @since 1.1
*/
public class WrapInfo implements Serializable {
private static final long serialVersionUID = -7764500642913116581L;
@JsonProperty("token")
private String token;
@JsonProperty("ttl")
private Integer ttl;
@JsonProperty("creation_time")
private String creationTime;
@JsonProperty("creation_path")
private String creationPath;
/**
* @return Token
*/
public String getToken() {
return token;
}
/**
* @return TTL (in seconds)
*/
public Integer getTtl() {
return ttl;
}
/**
* @return Creation time
*/
public String getCreationTime() {
return creationTime;
}
/**
* @return Creation path
*/
public String getCreationPath() {
return creationPath;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
} else if (o == null || getClass() != o.getClass()) {
return false;
}
WrapInfo that = (WrapInfo) o;
return Objects.equals(token, that.token) &&
Objects.equals(ttl, that.ttl) &&
Objects.equals(creationTime, that.creationTime) &&
Objects.equals(creationPath, that.creationPath);
}
@Override
public int hashCode() {
return Objects.hash(token, ttl, creationTime, creationPath);
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2021 Stefan Kalscheuer * Copyright 2016-2022 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -37,6 +37,7 @@ import java.util.regex.Pattern;
import static java.util.Collections.singletonMap; import static java.util.Collections.singletonMap;
import static org.apache.commons.io.FileUtils.copyDirectory; import static org.apache.commons.io.FileUtils.copyDirectory;
import static org.awaitility.Awaitility.await;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assumptions.assumeFalse; import static org.junit.jupiter.api.Assumptions.assumeFalse;
import static org.junit.jupiter.api.Assumptions.assumeTrue; import static org.junit.jupiter.api.Assumptions.assumeTrue;
@ -49,7 +50,7 @@ import static org.junit.jupiter.api.Assumptions.assumeTrue;
* @since 0.1 * @since 0.1
*/ */
class HTTPVaultConnectorIT { class HTTPVaultConnectorIT {
private static String VAULT_VERSION = "1.9.0"; // The vault version this test is supposed to run against. private static String VAULT_VERSION = "1.11.2"; // The vault version this test is supposed to run against.
private static final String KEY1 = "E38bkCm0VhUvpdCKGQpcohhD9XmcHJ/2hreOSY019Lho"; private static final String KEY1 = "E38bkCm0VhUvpdCKGQpcohhD9XmcHJ/2hreOSY019Lho";
private static final String KEY2 = "O5OHwDleY3IiPdgw61cgHlhsrEm6tVJkrxhF6QAnILd1"; private static final String KEY2 = "O5OHwDleY3IiPdgw61cgHlhsrEm6tVJkrxhF6QAnILd1";
private static final String KEY3 = "mw7Bm3nbt/UWa/juDjjL2EPQ04kiJ0saC5JEXwJvXYsB"; private static final String KEY3 = "mw7Bm3nbt/UWa/juDjjL2EPQ04kiJ0saC5JEXwJvXYsB";
@ -80,11 +81,6 @@ class HTTPVaultConnectorIT {
// Initialize Vault. // Initialize Vault.
VaultConfiguration config = initializeVault(tempDir, isTls); VaultConfiguration config = initializeVault(tempDir, isTls);
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
// Initialize connector. // Initialize connector.
HTTPVaultConnectorBuilder builder = HTTPVaultConnector.builder() HTTPVaultConnectorBuilder builder = HTTPVaultConnector.builder()
@ -908,7 +904,8 @@ class HTTPVaultConnectorIT {
assertFalse(res.getAuth().isOrphan(), "Root token should not be orphan"); assertFalse(res.getAuth().isOrphan(), "Root token should not be orphan");
// Starting with Vault 1.0 a warning "custom ID uses weaker SHA1.." is given. // Starting with Vault 1.0 a warning "custom ID uses weaker SHA1.." is given.
assertEquals(1, res.getWarnings().size(), "Token creation did not return expected warning"); // Starting with Vault 1.11 a second warning "Endpoint ignored unrecognized parameters" is given.
assertFalse(res.getWarnings().isEmpty(), "Token creation did not return expected warning");
// Create token with attributes. // Create token with attributes.
Token token2 = Token.builder() Token token2 = Token.builder()
@ -952,7 +949,11 @@ class HTTPVaultConnectorIT {
.withType(Token.Type.BATCH) .withType(Token.Type.BATCH)
.build(); .build();
res = assertDoesNotThrow(() -> connector.createToken(token4), "Token creation failed"); res = assertDoesNotThrow(() -> connector.createToken(token4), "Token creation failed");
assertTrue(res.getAuth().getClientToken().startsWith("b"), "Unexpected token prefix"); assertTrue(
// Expecting batch token. "hvb." Prefix as of Vault 1.10, "b." before.
res.getAuth().getClientToken().startsWith("b.") || res.getAuth().getClientToken().startsWith("hvb."),
"Unexpected token prefix"
);
assertEquals(1, res.getAuth().getPolicies().size(), "Invalid number of policies returned"); assertEquals(1, res.getAuth().getPolicies().size(), "Invalid number of policies returned");
assertTrue(res.getAuth().getPolicies().contains("batchpolicy"), "Custom policy policy not set"); assertTrue(res.getAuth().getPolicies().contains("batchpolicy"), "Custom policy policy not set");
assertFalse(res.getAuth().isRenewable(), "Token should not be renewable"); assertFalse(res.getAuth().isRenewable(), "Token should not be renewable");
@ -1217,30 +1218,37 @@ class HTTPVaultConnectorIT {
} }
// Write configuration file. // Write configuration file.
BufferedWriter bw = null; File configFile = new File(dir, "vault.conf");
File configFile; try (BufferedWriter bw = new BufferedWriter(new FileWriter(configFile))) {
try {
configFile = new File(dir, "vault.conf");
bw = new BufferedWriter(new FileWriter(configFile));
bw.write(config.toString()); bw.write(config.toString());
} catch (IOException e) { } catch (IOException e) {
throw new IllegalStateException("Unable to generate config file", e); throw new IllegalStateException("Unable to generate config file", e);
} finally {
try {
if (bw != null)
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
} }
// Start vault process. // Start vault process.
try { try {
vaultProcess = Runtime.getRuntime().exec("vault server -config " + configFile.toString()); vaultProcess = Runtime.getRuntime().exec("vault server -config " + configFile);
} catch (IOException e) { } catch (IOException e) {
throw new IllegalStateException("Unable to start vault. Make sure vault binary is in your executable path", e); throw new IllegalStateException("Unable to start vault. Make sure vault binary is in your executable path", e);
} }
await().atMost(5, TimeUnit.SECONDS).until(() -> {
try (InputStream stdout = vaultProcess.getInputStream();
InputStreamReader reader = new InputStreamReader(stdout);
BufferedReader br = new BufferedReader(reader)) {
String line = br.readLine();
while (line != null) {
if (line.contains("Vault server started")) {
return true;
} else {
line = br.readLine();
}
}
return false;
}
});
return config; return config;
} }
@ -1265,28 +1273,14 @@ class HTTPVaultConnectorIT {
* @return port number * @return port number
*/ */
private static Integer getFreePort() { private static Integer getFreePort() {
ServerSocket socket = null; try (ServerSocket socket = new ServerSocket(0)) {
try {
socket = new ServerSocket(0);
socket.setReuseAddress(true); socket.setReuseAddress(true);
int port = socket.getLocalPort();
try { return socket.getLocalPort();
socket.close();
} catch (IOException e) {
// Ignore IOException on close()
}
return port;
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} }
throw new IllegalStateException("Unable to find a free TCP port"); throw new IllegalStateException("Unable to find a free TCP port");
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2021 Stefan Kalscheuer * Copyright 2016-2022 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,16 +16,14 @@
package de.stklcode.jvault.connector; package de.stklcode.jvault.connector;
import com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.client.WireMock; import com.github.tomakehurst.wiremock.client.WireMock;
import com.github.tomakehurst.wiremock.core.WireMockConfiguration; import com.github.tomakehurst.wiremock.junit5.WireMockExtension;
import de.stklcode.jvault.connector.exception.ConnectionException; import de.stklcode.jvault.connector.exception.ConnectionException;
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 org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.junit.jupiter.api.function.Executable; import org.junit.jupiter.api.function.Executable;
import java.io.IOException; import java.io.IOException;
@ -40,6 +38,7 @@ import java.util.Collections;
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.anyUrl; import static com.github.tomakehurst.wiremock.client.WireMock.anyUrl;
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
/** /**
@ -50,21 +49,10 @@ import static org.junit.jupiter.api.Assertions.*;
* @since 0.7.0 * @since 0.7.0
*/ */
class HTTPVaultConnectorTest { class HTTPVaultConnectorTest {
private static WireMockServer wireMock; @RegisterExtension
static WireMockExtension wireMock = WireMockExtension.newInstance()
@BeforeAll .options(wireMockConfig().dynamicPort())
static void prepare() { .build();
// Initialize HTTP mock.
wireMock = new WireMockServer(WireMockConfiguration.options().dynamicPort());
wireMock.start();
WireMock.configureFor("localhost", wireMock.port());
}
@AfterAll
static void tearDown() {
wireMock.stop();
wireMock = null;
}
/** /**
* Test exceptions thrown during request. * Test exceptions thrown during request.
@ -108,7 +96,7 @@ class HTTPVaultConnectorTest {
// Now simulate a failing request that succeeds on second try. // Now simulate a failing request that succeeds on second try.
connector = HTTPVaultConnector.builder(wireMock.url("/")).withNumberOfRetries(1).withTimeout(250).build(); connector = HTTPVaultConnector.builder(wireMock.url("/")).withNumberOfRetries(1).withTimeout(250).build();
WireMock.stubFor( wireMock.stubFor(
WireMock.any(anyUrl()) WireMock.any(anyUrl())
.willReturn(aResponse().withStatus(500)) .willReturn(aResponse().withStatus(500))
.willReturn(aResponse().withStatus(500)) .willReturn(aResponse().withStatus(500))
@ -334,7 +322,7 @@ class HTTPVaultConnectorTest {
} }
private void mockHttpResponse(int status, String body, String contentType) { private void mockHttpResponse(int status, String body, String contentType) {
WireMock.stubFor( wireMock.stubFor(
WireMock.any(anyUrl()).willReturn( WireMock.any(anyUrl()).willReturn(
aResponse().withStatus(status).withBody(body).withHeader("Content-Type", contentType) aResponse().withStatus(status).withBody(body).withHeader("Content-Type", contentType)
) )

View File

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

View File

@ -0,0 +1,70 @@
package de.stklcode.jvault.connector.model;
import nl.jqno.equalsverifier.EqualsVerifier;
import org.junit.jupiter.api.Test;
import java.io.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
/**
* Abstract testcase for model classes.
*
* @author Stefan Kalscheuer
* @since 1.1
*/
public abstract class AbstractModelTest<T> {
protected final Class<?> modelClass;
/**
* Test case constructor.
*
* @param modelClass Target class to test.
*/
protected AbstractModelTest(Class<T> modelClass) {
this.modelClass = modelClass;
}
/**
* Create a "full" model instance.
*
* @return Model instance.
*/
protected abstract T createFull();
/**
* Test if {@link Object#equals(Object)} and {@link Object#hashCode()} are implemented, s.t. all fields are covered.
*/
@Test
void testEqualsHashcode() {
EqualsVerifier.simple().forClass(modelClass).verify();
}
/**
* Test Java serialization of a full model instance.
* Serialization and deserialization must not fail and the resulting object should equal the original object.
*/
@Test
void serializationTest() {
T original = createFull();
byte[] bytes;
try (var bos = new ByteArrayOutputStream();
var oos = new ObjectOutputStream(bos)) {
oos.writeObject(original);
bytes = bos.toByteArray();
} catch (IOException e) {
fail("Serialization failed", e);
return;
}
try (var bis = new ByteArrayInputStream(bytes);
var ois = new ObjectInputStream(bis)) {
Object copy = ois.readObject();
assertEquals(modelClass, copy.getClass(), "Invalid class after deserialization");
assertEquals(original, copy, "Deserialized object should be equal to the original");
} catch (IOException | ClassNotFoundException e) {
fail("Deserialization failed", e);
}
}
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2021 Stefan Kalscheuer * Copyright 2016-2022 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -20,8 +20,6 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -35,14 +33,21 @@ import static org.junit.jupiter.api.Assumptions.assumeTrue;
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.5.0 * @since 0.5.0
*/ */
class AppRoleSecretTest { class AppRoleSecretTest extends AbstractModelTest<AppRoleSecret> {
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 = Map.of(
private static final List<String> TEST_CIDR = Arrays.asList("203.0.113.0/24", "198.51.100.0/24"); "foo", "bar",
"number", 1337
);
private static final List<String> TEST_CIDR = List.of("203.0.113.0/24", "198.51.100.0/24");
static { AppRoleSecretTest() {
TEST_META.put("foo", "bar"); super(AppRoleSecret.class);
TEST_META.put("number", 1337); }
@Override
protected AppRoleSecret createFull() {
return new AppRoleSecret(TEST_ID, TEST_META, TEST_CIDR);
} }
/** /**
@ -167,7 +172,6 @@ class AppRoleSecretTest {
assertEquals("TEST_LASTUPDATE", secret2.getLastUpdatedTime()); assertEquals("TEST_LASTUPDATE", secret2.getLastUpdatedTime());
assertEquals(678, secret2.getNumUses()); assertEquals(678, secret2.getNumUses());
assertEquals(12345, secret2.getTtl()); assertEquals(12345, secret2.getTtl());
} }
private static void setPrivateField(Object object, String fieldName, Object value) throws NoSuchFieldException, IllegalAccessException { private static void setPrivateField(Object object, String fieldName, Object value) throws NoSuchFieldException, IllegalAccessException {
@ -182,5 +186,4 @@ class AppRoleSecretTest {
return json.replaceAll("\"cidr_list\":\"([^\"]*)\"", "\"cidr_list\":\\[$1\\]") return json.replaceAll("\"cidr_list\":\"([^\"]*)\"", "\"cidr_list\":\\[$1\\]")
.replaceAll("(\\d+\\.\\d+\\.\\d+\\.\\d+/\\d+)", "\"$1\""); .replaceAll("(\\d+\\.\\d+\\.\\d+\\.\\d+/\\d+)", "\"$1\"");
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2021 Stefan Kalscheuer * Copyright 2016-2022 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -32,7 +32,7 @@ import static org.junit.jupiter.api.Assertions.*;
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.4.0 * @since 0.4.0
*/ */
class AppRoleTest { class AppRoleTest extends AbstractModelTest<AppRole> {
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;
@ -56,6 +56,31 @@ class AppRoleTest {
private static final String JSON_FULL = String.format("{\"role_name\":\"%s\",\"role_id\":\"%s\",\"bind_secret_id\":%s,\"secret_id_bound_cidrs\":\"%s\",\"secret_id_num_uses\":%d,\"secret_id_ttl\":%d,\"enable_local_secret_ids\":%s,\"token_ttl\":%d,\"token_max_ttl\":%d,\"token_policies\":\"%s\",\"token_bound_cidrs\":\"%s\",\"token_explicit_max_ttl\":%d,\"token_no_default_policy\":%s,\"token_num_uses\":%d,\"token_period\":%d,\"token_type\":\"%s\"}", private static final String JSON_FULL = String.format("{\"role_name\":\"%s\",\"role_id\":\"%s\",\"bind_secret_id\":%s,\"secret_id_bound_cidrs\":\"%s\",\"secret_id_num_uses\":%d,\"secret_id_ttl\":%d,\"enable_local_secret_ids\":%s,\"token_ttl\":%d,\"token_max_ttl\":%d,\"token_policies\":\"%s\",\"token_bound_cidrs\":\"%s\",\"token_explicit_max_ttl\":%d,\"token_no_default_policy\":%s,\"token_num_uses\":%d,\"token_period\":%d,\"token_type\":\"%s\"}",
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());
AppRoleTest() {
super(AppRole.class);
}
@Override
protected AppRole createFull() {
return AppRole.builder(NAME)
.withId(ID)
.withBindSecretID(BIND_SECRET_ID)
.withSecretIdBoundCidrs(BOUND_CIDR_LIST)
.withTokenPolicies(POLICIES)
.withSecretIdNumUses(SECRET_ID_NUM_USES)
.withSecretIdTtl(SECRET_ID_TTL)
.withEnableLocalSecretIds(ENABLE_LOCAL_SECRET_IDS)
.withTokenTtl(TOKEN_TTL)
.withTokenMaxTtl(TOKEN_MAX_TTL)
.withTokenBoundCidrs(BOUND_CIDR_LIST)
.withTokenExplicitMaxTtl(TOKEN_EXPLICIT_MAX_TTL)
.withTokenNoDefaultPolicy(TOKEN_NO_DEFAULT_POLICY)
.withTokenNumUses(TOKEN_NUM_USES)
.withTokenPeriod(TOKEN_PERIOD)
.withTokenType(TOKEN_TYPE)
.build();
}
@BeforeAll @BeforeAll
static void init() { static void init() {
BOUND_CIDR_LIST.add(CIDR_1); BOUND_CIDR_LIST.add(CIDR_1);
@ -93,23 +118,7 @@ class AppRoleTest {
*/ */
@Test @Test
void buildFullTest() throws JsonProcessingException { void buildFullTest() throws JsonProcessingException {
AppRole role = AppRole.builder(NAME) AppRole role = createFull();
.withId(ID)
.withBindSecretID(BIND_SECRET_ID)
.withSecretIdBoundCidrs(BOUND_CIDR_LIST)
.withTokenPolicies(POLICIES)
.withSecretIdNumUses(SECRET_ID_NUM_USES)
.withSecretIdTtl(SECRET_ID_TTL)
.withEnableLocalSecretIds(ENABLE_LOCAL_SECRET_IDS)
.withTokenTtl(TOKEN_TTL)
.withTokenMaxTtl(TOKEN_MAX_TTL)
.withTokenBoundCidrs(BOUND_CIDR_LIST)
.withTokenExplicitMaxTtl(TOKEN_EXPLICIT_MAX_TTL)
.withTokenNoDefaultPolicy(TOKEN_NO_DEFAULT_POLICY)
.withTokenNumUses(TOKEN_NUM_USES)
.withTokenPeriod(TOKEN_PERIOD)
.withTokenType(TOKEN_TYPE)
.build();
assertEquals(NAME, role.getName()); assertEquals(NAME, role.getName());
assertEquals(ID, role.getId()); assertEquals(ID, role.getId());
assertEquals(BIND_SECRET_ID, role.getBindSecretId()); assertEquals(BIND_SECRET_ID, role.getBindSecretId());

View File

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

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2021 Stefan Kalscheuer * Copyright 2016-2022 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -26,21 +26,29 @@ import java.util.List;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
/** /**
* Unit Test for {@link Token.Builder} * Unit Test for {@link TokenRole} and {@link TokenRole.Builder}.
* *
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.9 * @since 0.9
*/ */
class TokenRoleBuilderTest { class TokenRoleTest extends AbstractModelTest<TokenRole> {
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";
private static final String ALLOWED_POLICY_3 = "apol-3"; private static final String ALLOWED_POLICY_3 = "apol-3";
private static final List<String> ALLOWED_POLICIES = Arrays.asList(ALLOWED_POLICY_1, ALLOWED_POLICY_2); private static final List<String> ALLOWED_POLICIES = Arrays.asList(ALLOWED_POLICY_1, ALLOWED_POLICY_2);
private static final String ALLOWED_POLICY_GLOB_1 = "apol-g1*";
private static final String ALLOWED_POLICY_GLOB_2 = "apol-g2*";
private static final String ALLOWED_POLICY_GLOB_3 = "apol-g3*";
private static final List<String> ALLOWED_POLICIES_GLOB = Arrays.asList(ALLOWED_POLICY_GLOB_2, ALLOWED_POLICY_GLOB_3);
private static final String DISALLOWED_POLICY_1 = "dpol-1"; private static final String DISALLOWED_POLICY_1 = "dpol-1";
private static final String DISALLOWED_POLICY_2 = "dpol-2"; private static final String DISALLOWED_POLICY_2 = "dpol-2";
private static final String DISALLOWED_POLICY_3 = "dpol-3"; private static final String DISALLOWED_POLICY_3 = "dpol-3";
private static final List<String> DISALLOWED_POLICIES = Arrays.asList(DISALLOWED_POLICY_2, DISALLOWED_POLICY_3); private static final List<String> DISALLOWED_POLICIES = Arrays.asList(DISALLOWED_POLICY_2, DISALLOWED_POLICY_3);
private static final String DISALLOWED_POLICY_GLOB_1 = "dpol-g1*";
private static final String DISALLOWED_POLICY_GLOB_2 = "dpol-g2*";
private static final String DISALLOWED_POLICY_GLOB_3 = "dpol-g3*";
private static final List<String> DISALLOWED_POLICIES_GLOB = Arrays.asList(DISALLOWED_POLICY_GLOB_1, DISALLOWED_POLICY_GLOB_2);
private static final Boolean ORPHAN = false; private static final Boolean ORPHAN = false;
private static final Boolean RENEWABLE = true; private static final Boolean RENEWABLE = true;
private static final String PATH_SUFFIX = "ps"; private static final String PATH_SUFFIX = "ps";
@ -61,7 +69,9 @@ class TokenRoleBuilderTest {
private static final String JSON_FULL = "{" + private static final String JSON_FULL = "{" +
"\"name\":\"" + NAME + "\"," + "\"name\":\"" + NAME + "\"," +
"\"allowed_policies\":[\"" + ALLOWED_POLICY_1 + "\",\"" + ALLOWED_POLICY_2 + "\",\"" + ALLOWED_POLICY_3 + "\"]," + "\"allowed_policies\":[\"" + ALLOWED_POLICY_1 + "\",\"" + ALLOWED_POLICY_2 + "\",\"" + ALLOWED_POLICY_3 + "\"]," +
"\"allowed_policies_glob\":[\"" + ALLOWED_POLICY_GLOB_1 + "\",\"" + ALLOWED_POLICY_GLOB_2 + "\",\"" + ALLOWED_POLICY_GLOB_3 + "\"]," +
"\"disallowed_policies\":[\"" + DISALLOWED_POLICY_1 + "\",\"" + DISALLOWED_POLICY_2 + "\",\"" + DISALLOWED_POLICY_3 + "\"]," + "\"disallowed_policies\":[\"" + DISALLOWED_POLICY_1 + "\",\"" + DISALLOWED_POLICY_2 + "\",\"" + DISALLOWED_POLICY_3 + "\"]," +
"\"disallowed_policies_glob\":[\"" + DISALLOWED_POLICY_GLOB_1 + "\",\"" + DISALLOWED_POLICY_GLOB_2 + "\",\"" + DISALLOWED_POLICY_GLOB_3 + "\"]," +
"\"orphan\":" + ORPHAN + "," + "\"orphan\":" + ORPHAN + "," +
"\"renewable\":" + RENEWABLE + "," + "\"renewable\":" + RENEWABLE + "," +
"\"path_suffix\":\"" + PATH_SUFFIX + "\"," + "\"path_suffix\":\"" + PATH_SUFFIX + "\"," +
@ -73,6 +83,37 @@ class TokenRoleBuilderTest {
"\"token_period\":" + TOKEN_PERIOD + "," + "\"token_period\":" + TOKEN_PERIOD + "," +
"\"token_type\":\"" + TOKEN_TYPE.value() + "\"}"; "\"token_type\":\"" + TOKEN_TYPE.value() + "\"}";
TokenRoleTest() {
super(TokenRole.class);
}
@Override
protected TokenRole createFull() {
return TokenRole.builder()
.forName(NAME)
.withAllowedPolicies(ALLOWED_POLICIES)
.withAllowedPolicy(ALLOWED_POLICY_3)
.withAllowedPolicyGlob(ALLOWED_POLICY_GLOB_1)
.withAllowedPoliciesGlob(ALLOWED_POLICIES_GLOB)
.withDisallowedPolicy(DISALLOWED_POLICY_1)
.withDisallowedPolicies(DISALLOWED_POLICIES)
.withDisallowedPoliciesGlob(DISALLOWED_POLICIES_GLOB)
.withDisallowedPolicyGlob(DISALLOWED_POLICY_GLOB_3)
.orphan(ORPHAN)
.renewable(RENEWABLE)
.withPathSuffix(PATH_SUFFIX)
.withAllowedEntityAliases(ALLOWED_ENTITY_ALIASES)
.withAllowedEntityAlias(ALLOWED_ENTITY_ALIAS_2)
.withTokenBoundCidr(TOKEN_BOUND_CIDR_3)
.withTokenBoundCidrs(TOKEN_BOUND_CIDRS)
.withTokenExplicitMaxTtl(TOKEN_EXPLICIT_MAX_TTL)
.withTokenNoDefaultPolicy(TOKEN_NO_DEFAULT_POLICY)
.withTokenNumUses(TOKEN_NUM_USES)
.withTokenPeriod(TOKEN_PERIOD)
.withTokenType(TOKEN_TYPE)
.build();
}
/** /**
* Build token without any parameters. * Build token without any parameters.
*/ */
@ -132,6 +173,9 @@ class TokenRoleBuilderTest {
assertNull(role.getTokenPeriod()); assertNull(role.getTokenPeriod());
assertNull(role.getTokenType()); assertNull(role.getTokenType());
// Empty builder should be equal to no-arg construction.
assertEquals(role, new TokenRole());
// Optional fields should be ignored, so JSON string should be empty. // Optional fields should be ignored, so JSON string should be empty.
assertEquals("{}", new ObjectMapper().writeValueAsString(role)); assertEquals("{}", new ObjectMapper().writeValueAsString(role));
} }
@ -141,30 +185,16 @@ class TokenRoleBuilderTest {
*/ */
@Test @Test
void buildFullTest() throws JsonProcessingException { void buildFullTest() throws JsonProcessingException {
TokenRole role = TokenRole.builder() TokenRole role = createFull();
.forName(NAME)
.withAllowedPolicies(ALLOWED_POLICIES)
.withAllowedPolicy(ALLOWED_POLICY_3)
.withDisallowedPolicy(DISALLOWED_POLICY_1)
.withDisallowedPolicies(DISALLOWED_POLICIES)
.orphan(ORPHAN)
.renewable(RENEWABLE)
.withPathSuffix(PATH_SUFFIX)
.withAllowedEntityAliases(ALLOWED_ENTITY_ALIASES)
.withAllowedEntityAlias(ALLOWED_ENTITY_ALIAS_2)
.withTokenBoundCidr(TOKEN_BOUND_CIDR_3)
.withTokenBoundCidrs(TOKEN_BOUND_CIDRS)
.withTokenExplicitMaxTtl(TOKEN_EXPLICIT_MAX_TTL)
.withTokenNoDefaultPolicy(TOKEN_NO_DEFAULT_POLICY)
.withTokenNumUses(TOKEN_NUM_USES)
.withTokenPeriod(TOKEN_PERIOD)
.withTokenType(TOKEN_TYPE)
.build();
assertEquals(NAME, role.getName()); assertEquals(NAME, role.getName());
assertEquals(ALLOWED_POLICIES.size() + 1, role.getAllowedPolicies().size()); assertEquals(ALLOWED_POLICIES.size() + 1, role.getAllowedPolicies().size());
assertTrue(role.getAllowedPolicies().containsAll(List.of(ALLOWED_POLICY_1, ALLOWED_POLICY_2, ALLOWED_POLICY_3))); assertTrue(role.getAllowedPolicies().containsAll(List.of(ALLOWED_POLICY_1, ALLOWED_POLICY_2, ALLOWED_POLICY_3)));
assertEquals(ALLOWED_POLICIES_GLOB.size() + 1, role.getAllowedPoliciesGlob().size());
assertTrue(role.getAllowedPoliciesGlob().containsAll(List.of(ALLOWED_POLICY_GLOB_1, ALLOWED_POLICY_GLOB_2, ALLOWED_POLICY_GLOB_3)));
assertEquals(DISALLOWED_POLICIES.size() + 1, role.getDisallowedPolicies().size()); assertEquals(DISALLOWED_POLICIES.size() + 1, role.getDisallowedPolicies().size());
assertTrue(role.getDisallowedPolicies().containsAll(List.of(DISALLOWED_POLICY_1, DISALLOWED_POLICY_2, DISALLOWED_POLICY_3))); assertTrue(role.getDisallowedPolicies().containsAll(List.of(DISALLOWED_POLICY_1, DISALLOWED_POLICY_2, DISALLOWED_POLICY_3)));
assertEquals(DISALLOWED_POLICIES_GLOB.size() + 1, role.getDisallowedPoliciesGlob().size());
assertTrue(role.getDisallowedPoliciesGlob().containsAll(List.of(DISALLOWED_POLICY_GLOB_1, DISALLOWED_POLICY_GLOB_2, DISALLOWED_POLICY_GLOB_3)));
assertEquals(ORPHAN, role.getOrphan()); assertEquals(ORPHAN, role.getOrphan());
assertEquals(RENEWABLE, role.getRenewable()); assertEquals(RENEWABLE, role.getRenewable());
assertEquals(PATH_SUFFIX, role.getPathSuffix()); assertEquals(PATH_SUFFIX, role.getPathSuffix());

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2021 Stefan Kalscheuer * Copyright 2016-2022 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -31,7 +31,7 @@ import static org.junit.jupiter.api.Assertions.*;
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.4.0 * @since 0.4.0
*/ */
class TokenTest { class TokenTest extends AbstractModelTest<Token> {
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;
@ -53,6 +53,29 @@ class TokenTest {
private static final String ENTITY_ALIAS = "alias-value"; private static final String 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\"}"; 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\"}";
TokenTest() {
super(Token.class);
}
@Override
protected Token createFull() {
return Token.builder()
.withId(ID)
.withType(Token.Type.SERVICE)
.withDisplayName(DISPLAY_NAME)
.withNoParent(NO_PARENT)
.withNoDefaultPolicy(NO_DEFAULT_POLICY)
.withTtl(TTL)
.withExplicitMaxTtl(EXPLICIT_MAX_TTL)
.withNumUses(NUM_USES)
.withPolicies(POLICIES)
.withMeta(META)
.withRenewable(RENEWABLE)
.withPeriod(PERIOD)
.withEntityAlias(ENTITY_ALIAS)
.build();
}
@BeforeAll @BeforeAll
static void init() { static void init() {
POLICIES.add(POLICY); POLICIES.add(POLICY);
@ -81,6 +104,9 @@ class TokenTest {
// Optional fields should be ignored, so JSON string should be empty. // Optional fields should be ignored, so JSON string should be empty.
assertEquals("{}", new ObjectMapper().writeValueAsString(token)); assertEquals("{}", new ObjectMapper().writeValueAsString(token));
// Empty builder should be equal to no-arg construction.
assertEquals(token, new Token());
} }
/** /**
@ -88,21 +114,7 @@ class TokenTest {
*/ */
@Test @Test
void buildFullTest() throws JsonProcessingException { void buildFullTest() throws JsonProcessingException {
Token token = Token.builder() Token token = createFull();
.withId(ID)
.withType(Token.Type.SERVICE)
.withDisplayName(DISPLAY_NAME)
.withNoParent(NO_PARENT)
.withNoDefaultPolicy(NO_DEFAULT_POLICY)
.withTtl(TTL)
.withExplicitMaxTtl(EXPLICIT_MAX_TTL)
.withNumUses(NUM_USES)
.withPolicies(POLICIES)
.withMeta(META)
.withRenewable(RENEWABLE)
.withPeriod(PERIOD)
.withEntityAlias(ENTITY_ALIAS)
.build();
assertEquals(ID, token.getId()); assertEquals(ID, token.getId());
assertEquals(Token.Type.SERVICE.value(), token.getType()); assertEquals(Token.Type.SERVICE.value(), token.getType());
assertEquals(DISPLAY_NAME, token.getDisplayName()); assertEquals(DISPLAY_NAME, token.getDisplayName());

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2021 Stefan Kalscheuer * Copyright 2016-2022 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,14 +16,13 @@
package de.stklcode.jvault.connector.model.response; package de.stklcode.jvault.connector.model.response;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import de.stklcode.jvault.connector.exception.InvalidResponseException; import de.stklcode.jvault.connector.model.AbstractModelTest;
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.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
@ -33,7 +32,7 @@ import static org.junit.jupiter.api.Assertions.*;
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.6.2 * @since 0.6.2
*/ */
class AppRoleResponseTest { class AppRoleResponseTest extends AbstractModelTest<AppRoleResponse> {
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;
@ -63,10 +62,18 @@ class AppRoleResponseTest {
" \"lease_id\": \"\"\n" + " \"lease_id\": \"\"\n" +
"}"; "}";
private static final Map<String, Object> INVALID_DATA = new HashMap<>(); AppRoleResponseTest() {
super(AppRoleResponse.class);
}
static { @Override
INVALID_DATA.put("token_policies", "fancy-policy"); protected AppRoleResponse createFull() {
try {
return new ObjectMapper().readValue(RES_JSON, AppRoleResponse.class);
} catch (JsonProcessingException e) {
fail("Creation of full model instance failed", e);
return null;
}
} }
/** /**
@ -77,13 +84,6 @@ class AppRoleResponseTest {
// Create empty Object. // Create empty Object.
AppRoleResponse res = new AppRoleResponse(); AppRoleResponse res = new AppRoleResponse();
assertNull(res.getRole(), "Initial data should be empty"); assertNull(res.getRole(), "Initial data should be empty");
// Parsing invalid auth data map should fail.
assertThrows(
InvalidResponseException.class,
() -> res.setData(INVALID_DATA),
"Parsing invalid data succeeded"
);
} }
/** /**

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2021 Stefan Kalscheuer * Copyright 2016-2022 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,14 +16,14 @@
package de.stklcode.jvault.connector.model.response; package de.stklcode.jvault.connector.model.response;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import de.stklcode.jvault.connector.exception.InvalidResponseException; import de.stklcode.jvault.connector.model.AbstractModelTest;
import de.stklcode.jvault.connector.model.AuthBackend; 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.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -35,12 +35,16 @@ import static org.junit.jupiter.api.Assertions.*;
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.6.2 * @since 0.6.2
*/ */
class AuthMethodsResponseTest { class AuthMethodsResponseTest extends AbstractModelTest<AuthMethodsResponse> {
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_UUID = "4b42d1a4-0a0d-3c88-ae90-997e0c8b41be";
private static final String GH_ACCESSOR = "auth_github_badd7fd0";
private static final String GH_DESCR = "GitHub auth"; private static final String GH_DESCR = "GitHub auth";
private static final String TK_PATH = "token/"; private static final String TK_PATH = "token/";
private static final String TK_TYPE = "token"; private static final String TK_TYPE = "token";
private static final String TK_UUID = "32ea9681-6bd6-6cec-eec3-d11260ba9741";
private static final String TK_ACCESSOR = "auth_token_ac0dd95a";
private static final String TK_DESCR = "token based credentials"; private static final String TK_DESCR = "token based credentials";
private static final Integer TK_LEASE_TTL = 0; private static final Integer TK_LEASE_TTL = 0;
private static final Integer TK_MAX_LEASE_TTL = 0; private static final Integer TK_MAX_LEASE_TTL = 0;
@ -48,8 +52,13 @@ class AuthMethodsResponseTest {
private static final String RES_JSON = "{\n" + private static final String RES_JSON = "{\n" +
" \"data\": {" + " \"data\": {" +
" \"" + GH_PATH + "\": {\n" + " \"" + GH_PATH + "\": {\n" +
" \"uuid\": \"" + GH_UUID + "\",\n" +
" \"type\": \"" + GH_TYPE + "\",\n" + " \"type\": \"" + GH_TYPE + "\",\n" +
" \"description\": \"" + GH_DESCR + "\"\n" + " \"accessor\": \"" + GH_ACCESSOR + "\",\n" +
" \"description\": \"" + GH_DESCR + "\",\n" +
" \"external_entropy_access\": false,\n" +
" \"local\": false,\n" +
" \"seal_wrap\": false\n" +
" },\n" + " },\n" +
" \"" + TK_PATH + "\": {\n" + " \"" + TK_PATH + "\": {\n" +
" \"config\": {\n" + " \"config\": {\n" +
@ -57,15 +66,28 @@ class AuthMethodsResponseTest {
" \"max_lease_ttl\": " + TK_MAX_LEASE_TTL + "\n" + " \"max_lease_ttl\": " + TK_MAX_LEASE_TTL + "\n" +
" },\n" + " },\n" +
" \"description\": \"" + TK_DESCR + "\",\n" + " \"description\": \"" + TK_DESCR + "\",\n" +
" \"type\": \"" + TK_TYPE + "\"\n" + " \"type\": \"" + TK_TYPE + "\",\n" +
" \"uuid\": \"" + TK_UUID + "\",\n" +
" \"accessor\": \"" + TK_ACCESSOR + "\",\n" +
" \"external_entropy_access\": false,\n" +
" \"local\": true,\n" +
" \"seal_wrap\": false\n" +
" }\n" + " }\n" +
" }\n" + " }\n" +
"}"; "}";
private static final Map<String, Object> INVALID_DATA = new HashMap<>(); AuthMethodsResponseTest() {
super(AuthMethodsResponse.class);
}
static { @Override
INVALID_DATA.put("dummy/", new Dummy()); protected AuthMethodsResponse createFull() {
try {
return new ObjectMapper().readValue(RES_JSON, AuthMethodsResponse.class);
} catch (JsonProcessingException e) {
fail("Creation of full model instance failed", e);
return null;
}
} }
/** /**
@ -76,13 +98,6 @@ class AuthMethodsResponseTest {
// Create empty Object. // Create empty Object.
AuthMethodsResponse res = new AuthMethodsResponse(); AuthMethodsResponse res = new AuthMethodsResponse();
assertEquals(Collections.emptyMap(), res.getSupportedMethods(), "Initial method map should be empty"); assertEquals(Collections.emptyMap(), res.getSupportedMethods(), "Initial method map should be empty");
// Parsing invalid data map should fail.
assertThrows(
InvalidResponseException.class,
() -> res.setData(INVALID_DATA),
"Parsing invalid data succeeded"
);
} }
/** /**
@ -107,19 +122,31 @@ class AuthMethodsResponseTest {
assertEquals(AuthBackend.GITHUB, method.getType(), "Incorrect parsed type for GitHub"); assertEquals(AuthBackend.GITHUB, method.getType(), "Incorrect parsed type for GitHub");
assertEquals(GH_DESCR, method.getDescription(), "Incorrect description for GitHub"); assertEquals(GH_DESCR, method.getDescription(), "Incorrect description for GitHub");
assertNull(method.getConfig(), "Unexpected config for GitHub"); assertNull(method.getConfig(), "Unexpected config for GitHub");
assertEquals(GH_UUID, method.getUuid(), "Unexpected UUID for GitHub");
assertEquals(GH_ACCESSOR, method.getAccessor(), "Unexpected accessor for GitHub");
assertFalse(method.isLocal(), "Unexpected local flag for GitHub");
assertFalse(method.isExternalEntropyAccess(), "Unexpected external entropy flag for GitHub");
assertFalse(method.isSealWrap(), "Unexpected seal wrap flag for GitHub");
// Verify first method. // Verify second method.
method = supported.get(TK_PATH); method = supported.get(TK_PATH);
assertEquals(TK_TYPE, method.getRawType(), "Incorrect raw type for Token"); assertEquals(TK_TYPE, method.getRawType(), "Incorrect raw type for Token");
assertEquals(AuthBackend.TOKEN, method.getType(), "Incorrect parsed type for Token"); assertEquals(AuthBackend.TOKEN, method.getType(), "Incorrect parsed type for Token");
assertEquals(TK_DESCR, method.getDescription(), "Incorrect description for Token"); assertEquals(TK_DESCR, method.getDescription(), "Incorrect description for Token");
assertEquals(TK_UUID, method.getUuid(), "Unexpected UUID for Token");
assertEquals(TK_ACCESSOR, method.getAccessor(), "Unexpected accessor for Token");
assertTrue(method.isLocal(), "Unexpected local flag for Token");
assertFalse(method.isExternalEntropyAccess(), "Unexpected external entropy flag for Token");
assertFalse(method.isSealWrap(), "Unexpected seal wrap flag for GitHub");
assertNotNull(method.getConfig(), "Missing config for Token"); assertNotNull(method.getConfig(), "Missing config for Token");
assertEquals(2, method.getConfig().size(), "Unexpected config size for Token"); assertEquals(
assertEquals(TK_LEASE_TTL.toString(), method.getConfig().get("default_lease_ttl"), "Incorrect lease TTL config"); Map.of(
assertEquals(TK_MAX_LEASE_TTL.toString(), method.getConfig().get("max_lease_ttl"), "Incorrect max lease TTL config"); "default_lease_ttl", TK_LEASE_TTL.toString(),
} "max_lease_ttl", TK_MAX_LEASE_TTL.toString()
),
private static class Dummy { method.getConfig(),
"Unexpected config for Token"
);
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2021 Stefan Kalscheuer * Copyright 2016-2022 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,12 +16,12 @@
package de.stklcode.jvault.connector.model.response; package de.stklcode.jvault.connector.model.response;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import de.stklcode.jvault.connector.exception.InvalidResponseException; import de.stklcode.jvault.connector.model.AbstractModelTest;
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.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -33,7 +33,7 @@ import static org.junit.jupiter.api.Assertions.*;
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.6.2 * @since 0.6.2
*/ */
class AuthResponseTest { class AuthResponseTest extends AbstractModelTest<AuthResponse> {
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";
@ -69,31 +69,18 @@ class AuthResponseTest {
" }\n" + " }\n" +
"}"; "}";
private static final Map<String, Object> INVALID_AUTH_DATA = new HashMap<>(); AuthResponseTest() {
super(AuthResponse.class);
static {
INVALID_AUTH_DATA.put("policies", "fancy-policy");
} }
/** @Override
* Test getter, setter and get-methods for response data. protected AuthResponse createFull() {
*/ try {
@Test return new ObjectMapper().readValue(RES_JSON, AuthResponse.class);
void getDataRoundtrip() { } catch (JsonProcessingException e) {
// Create empty Object. fail("Creation of full model instance failed", e);
AuthResponse res = new AuthResponse(); return null;
assertNull(res.getData(), "Initial data should be empty"); }
// Parsing invalid auth data map should fail.
assertThrows(
InvalidResponseException.class,
() -> res.setAuth(INVALID_AUTH_DATA),
"Parsing invalid auth data succeeded"
);
// Data method should be agnostic.
res.setData(INVALID_AUTH_DATA);
assertEquals(INVALID_AUTH_DATA, res.getData(), "Data not passed through");
} }
/** /**

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2021 Stefan Kalscheuer * Copyright 2016-2022 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,14 +16,13 @@
package de.stklcode.jvault.connector.model.response; package de.stklcode.jvault.connector.model.response;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import de.stklcode.jvault.connector.exception.InvalidResponseException; import de.stklcode.jvault.connector.exception.InvalidResponseException;
import de.stklcode.jvault.connector.model.AbstractModelTest;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.util.HashMap; import static org.junit.jupiter.api.Assertions.*;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
/** /**
* JUnit Test for {@link CredentialsResponse} model. * JUnit Test for {@link CredentialsResponse} model.
@ -31,14 +30,33 @@ import static org.junit.jupiter.api.Assertions.assertNull;
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.8 * @since 0.8
*/ */
class CredentialsResponseTest { class CredentialsResponseTest extends AbstractModelTest<CredentialsResponse> {
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";
private static final String JSON = "{\n" +
" \"request_id\": \"68315073-6658-e3ff-2da7-67939fb91bbd\",\n" +
" \"lease_id\": \"\",\n" +
" \"lease_duration\": 2764800,\n" +
" \"renewable\": false,\n" +
" \"data\": {\n" +
" \"username\": \"" + VAL_USER + "\",\n" +
" \"password\": \"" + VAL_PASS + "\"\n" +
" },\n" +
" \"warnings\": null\n" +
"}";
static { CredentialsResponseTest() {
DATA.put("username", VAL_USER); super(CredentialsResponse.class);
DATA.put("password", VAL_PASS); }
@Override
protected CredentialsResponse createFull() {
try {
return new ObjectMapper().readValue(JSON, CredentialsResponse.class);
} catch (JsonProcessingException e) {
fail("Creation of full model instance failed", e);
return null;
}
} }
/** /**
@ -47,15 +65,16 @@ class CredentialsResponseTest {
* @throws InvalidResponseException Should not occur * @throws InvalidResponseException Should not occur
*/ */
@Test @Test
@SuppressWarnings("unchecked")
void getCredentialsTest() throws InvalidResponseException { void getCredentialsTest() throws InvalidResponseException {
// Create empty Object. // Create empty Object.
CredentialsResponse res = new CredentialsResponse(); CredentialsResponse res = new CredentialsResponse();
assertNull(res.getUsername(), "Username not present in data map should not return anything"); assertNull(res.getUsername(), "Username not present in data map should not return anything");
assertNull(res.getPassword(), "Password not present in data map should not return anything"); assertNull(res.getPassword(), "Password not present in data map should not return anything");
// Fill data map. res = assertDoesNotThrow(
res.setData(DATA); () -> new ObjectMapper().readValue(JSON, CredentialsResponse.class),
"Deserialization of CredentialsResponse failed"
);
assertEquals(VAL_USER, res.getUsername(), "Incorrect username"); assertEquals(VAL_USER, res.getUsername(), "Incorrect username");
assertEquals(VAL_PASS, res.getPassword(), "Incorrect password"); assertEquals(VAL_PASS, res.getPassword(), "Incorrect password");
} }

View File

@ -0,0 +1,90 @@
/*
* 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.model.response;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import de.stklcode.jvault.connector.model.AbstractModelTest;
import org.junit.jupiter.api.Test;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
/**
* JUnit Test for {@link ErrorResponse} model.
*
* @author Stefan Kalscheuer
*/
class ErrorResponseTest extends AbstractModelTest<ErrorResponse> {
private static final String ERROR_1 = "Error #1";
private static final String ERROR_2 = "Error #2";
private static final String JSON = "{\"errors\":[\"" + ERROR_1 + "\",\"" + ERROR_2 + "\"]}";
private static final String JSON_EMPTY = "{\"errors\":[]}";
ErrorResponseTest() {
super(ErrorResponse.class);
}
@Override
protected ErrorResponse createFull() {
try {
return new ObjectMapper().readValue(JSON, ErrorResponse.class);
} catch (JsonProcessingException e) {
fail("Creation of full model instance failed", e);
return null;
}
}
/**
* Test creation from JSON value as returned by Vault.
*/
@Test
void jsonRoundtrip() {
ObjectMapper om = new ObjectMapper();
ErrorResponse res = assertDoesNotThrow(
() -> om.readValue(JSON, ErrorResponse.class),
"ErrorResponse deserialization failed"
);
assertNotNull(res, "Parsed response is NULL");
assertEquals(List.of(ERROR_1, ERROR_2), res.getErrors(), "Unexpected error messages");
assertEquals(
JSON,
assertDoesNotThrow(() -> om.writeValueAsString(res), "ErrorResponse serialization failed"),
"Unexpected JSON string after serialization"
);
}
@Test
void testToString() {
ErrorResponse res = assertDoesNotThrow(
() -> new ObjectMapper().readValue(JSON, ErrorResponse.class),
"ErrorResponse deserialization failed"
);
assertEquals(ERROR_1, res.toString());
res = assertDoesNotThrow(
() -> new ObjectMapper().readValue(JSON_EMPTY, ErrorResponse.class),
"ErrorResponse deserialization failed with empty list"
);
assertEquals("error response", res.toString());
assertEquals("error response", new ErrorResponse().toString());
}
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2021 Stefan Kalscheuer * Copyright 2016-2022 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,7 +16,9 @@
package de.stklcode.jvault.connector.model.response; package de.stklcode.jvault.connector.model.response;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import de.stklcode.jvault.connector.model.AbstractModelTest;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
@ -27,7 +29,7 @@ import static org.junit.jupiter.api.Assertions.*;
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.7.0 * @since 0.7.0
*/ */
class HealthResponseTest { class HealthResponseTest extends AbstractModelTest<HealthResponse> {
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";
@ -47,11 +49,25 @@ class HealthResponseTest {
" \"standby\": " + STANDBY + ",\n" + " \"standby\": " + STANDBY + ",\n" +
" \"sealed\": " + SEALED + ",\n" + " \"sealed\": " + SEALED + ",\n" +
" \"initialized\": " + INITIALIZED + ",\n" + " \"initialized\": " + INITIALIZED + ",\n" +
" \"replication_perf_mode\": \"" + REPL_PERF_MODE + "\",\n" + " \"replication_performance_mode\": \"" + REPL_PERF_MODE + "\",\n" +
" \"replication_dr_mode\": \"" + REPL_DR_MODE + "\",\n" + " \"replication_dr_mode\": \"" + REPL_DR_MODE + "\",\n" +
" \"performance_standby\": " + PERF_STANDBY + "\n" + " \"performance_standby\": " + PERF_STANDBY + "\n" +
"}"; "}";
HealthResponseTest() {
super(HealthResponse.class);
}
@Override
protected HealthResponse createFull() {
try {
return new ObjectMapper().readValue(RES_JSON, HealthResponse.class);
} catch (JsonProcessingException e) {
fail("Creation of full model instance failed", e);
return null;
}
}
/** /**
* 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).
*/ */

View File

@ -0,0 +1,68 @@
/*
* 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.model.response;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import de.stklcode.jvault.connector.model.AbstractModelTest;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
/**
* JUnit Test for {@link HelpResponse} model.
*
* @author Stefan Kalscheuer
*/
class HelpResponseTest extends AbstractModelTest<HelpResponse> {
private static final String HELP = "Help Text.";
private static final String JSON = "{\"help\":\"" + HELP + "\"}";
HelpResponseTest() {
super(HelpResponse.class);
}
@Override
protected HelpResponse createFull() {
try {
return new ObjectMapper().readValue(JSON, HelpResponse.class);
} catch (JsonProcessingException e) {
fail("Creation of full model instance failed", e);
return null;
}
}
/**
* Test creation from JSON value as returned by Vault.
*/
@Test
void jsonRoundtrip() {
ObjectMapper om = new ObjectMapper();
HelpResponse res = assertDoesNotThrow(
() -> om.readValue(JSON, HelpResponse.class),
"HelpResponse deserialization failed"
);
assertNotNull(res, "Parsed response is NULL");
assertEquals(HELP, res.getHelp(), "Unexpected help text");
assertEquals(
JSON,
assertDoesNotThrow(() -> om.writeValueAsString(res), "HelpResponse serialization failed"),
"Unexpected JSON string after serialization"
);
}
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2021 Stefan Kalscheuer * Copyright 2016-2022 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,33 +16,22 @@
package de.stklcode.jvault.connector.model.response; package de.stklcode.jvault.connector.model.response;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import de.stklcode.jvault.connector.exception.InvalidResponseException; import de.stklcode.jvault.connector.model.AbstractModelTest;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
/** /**
* JUnit Test for {@link SecretResponse} model. * JUnit Test for {@link MetaSecretResponse} model.
* *
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.6.2 * @since 0.6.2
*/ */
class SecretResponseTest { class MetaSecretResponseTest extends AbstractModelTest<MetaSecretResponse> {
private static final Map<String, Object> DATA = new HashMap<>();
private static final String KEY_UNKNOWN = "unknown";
private static final String KEY_STRING = "test1";
private static final String VAL_STRING = "testvalue";
private static final String KEY_INTEGER = "test2";
private static final Integer VAL_INTEGER = 42;
private static final String KEY_LIST = "list";
private static final String VAL_LIST = "[\"first\",\"second\"]";
private static final String SECRET_REQUEST_ID = "68315073-6658-e3ff-2da7-67939fb91bbd"; private static final String SECRET_REQUEST_ID = "68315073-6658-e3ff-2da7-67939fb91bbd";
private static final String SECRET_LEASE_ID = ""; private static final String SECRET_LEASE_ID = "";
private static final Integer SECRET_LEASE_DURATION = 2764800; private static final Integer SECRET_LEASE_DURATION = 2764800;
@ -54,17 +43,6 @@ class SecretResponseTest {
private static final String SECRET_META_CREATED = "2018-03-22T02:24:06.945319214Z"; private static final String SECRET_META_CREATED = "2018-03-22T02:24:06.945319214Z";
private static final String SECRET_META_DELETED = "2018-03-23T03:25:07.056420325Z"; private static final String SECRET_META_DELETED = "2018-03-23T03:25:07.056420325Z";
private static final List<String> SECRET_WARNINGS = null; private static final List<String> SECRET_WARNINGS = null;
private static final String SECRET_JSON = "{\n" +
" \"request_id\": \"" + SECRET_REQUEST_ID + "\",\n" +
" \"lease_id\": \"" + SECRET_LEASE_ID + "\",\n" +
" \"lease_duration\": " + SECRET_LEASE_DURATION + ",\n" +
" \"renewable\": " + SECRET_RENEWABLE + ",\n" +
" \"data\": {\n" +
" \"" + SECRET_DATA_K1 + "\": \"" + SECRET_DATA_V1 + "\",\n" +
" \"" + SECRET_DATA_K2 + "\": \"" + SECRET_DATA_V2 + "\"\n" +
" },\n" +
" \"warnings\": " + SECRET_WARNINGS + "\n" +
"}";
private static final String SECRET_JSON_V2 = "{\n" + private static final String SECRET_JSON_V2 = "{\n" +
" \"request_id\": \"" + SECRET_REQUEST_ID + "\",\n" + " \"request_id\": \"" + SECRET_REQUEST_ID + "\",\n" +
" \"lease_id\": \"" + SECRET_LEASE_ID + "\",\n" + " \"lease_id\": \"" + SECRET_LEASE_ID + "\",\n" +
@ -104,49 +82,18 @@ class SecretResponseTest {
" \"warnings\": " + SECRET_WARNINGS + "\n" + " \"warnings\": " + SECRET_WARNINGS + "\n" +
"}"; "}";
MetaSecretResponseTest() {
static { super(MetaSecretResponse.class);
DATA.put(KEY_STRING, VAL_STRING);
DATA.put(KEY_INTEGER, VAL_INTEGER);
DATA.put(KEY_LIST, VAL_LIST);
} }
/** @Override
* Test getter, setter and get-methods for response data. protected MetaSecretResponse createFull() {
* try {
* @throws InvalidResponseException Should not occur return new ObjectMapper().readValue(SECRET_JSON_V2, MetaSecretResponse.class);
*/ } catch (JsonProcessingException e) {
@Test fail("Creation of full model instance failed", e);
@SuppressWarnings("unchecked") return null;
void getDataRoundtrip() throws InvalidResponseException { }
// Create empty Object.
SecretResponse res = new SecretResponse();
assertNotNull(res.getData(), "Initial data should be Map");
assertTrue(res.getData().isEmpty(), "Initial data should be empty");
assertNull(res.get(KEY_STRING), "Getter should return NULL on empty data map");
// Fill data map.
res.setData(DATA);
assertEquals(DATA, res.getData(), "Data setter/getter not transparent");
assertEquals(DATA.size(), res.getData().keySet().size(), "Data size modified");
assertTrue(res.getData().keySet().containsAll(Set.of(KEY_STRING, KEY_INTEGER, KEY_LIST)), "Data keys not passed correctly");
assertEquals(VAL_STRING, res.get(KEY_STRING), "Data values not passed correctly");
assertEquals(VAL_INTEGER, res.get(KEY_INTEGER), "Data values not passed correctly");
assertNull(res.get(KEY_UNKNOWN), "Non-Null returned on unknown key");
// Try explicit JSON conversion.
final List<?> list = res.get(KEY_LIST, List.class);
assertNotNull(list, "JSON parsing of list failed");
assertEquals(2, list.size(), "JSON parsing of list returned incorrect size");
assertTrue(list.containsAll(List.of("first", "second")), "JSON parsing of list returned incorrect elements");
assertNull(res.get(KEY_UNKNOWN, Object.class), "Non-Null returned on unknown key");
// Requesting invalid class should result in Exception.
assertThrows(
InvalidResponseException.class,
() -> res.get(KEY_LIST, Double.class),
"JSON parsing to incorrect type succeeded"
);
} }
/** /**
@ -154,15 +101,9 @@ class SecretResponseTest {
*/ */
@Test @Test
void jsonRoundtrip() { void jsonRoundtrip() {
SecretResponse res = assertDoesNotThrow(
() -> new ObjectMapper().readValue(SECRET_JSON, SecretResponse.class),
"SecretResponse deserialization failed"
);
assertSecretData(res);
// KV v2 secret. // KV v2 secret.
res = assertDoesNotThrow( MetaSecretResponse res = assertDoesNotThrow(
() -> new ObjectMapper().readValue(SECRET_JSON_V2, SecretResponse.class), () -> new ObjectMapper().readValue(SECRET_JSON_V2, MetaSecretResponse.class),
"SecretResponse deserialization failed" "SecretResponse deserialization failed"
); );
assertSecretData(res); assertSecretData(res);
@ -171,12 +112,12 @@ class SecretResponseTest {
assertNotNull(res.getMetadata().getCreatedTime(), "Creation date parsing failed"); assertNotNull(res.getMetadata().getCreatedTime(), "Creation date parsing failed");
assertEquals("", res.getMetadata().getDeletionTimeString(), "Incorrect deletion date string"); assertEquals("", res.getMetadata().getDeletionTimeString(), "Incorrect deletion date string");
assertNull(res.getMetadata().getDeletionTime(), "Incorrect deletion date"); assertNull(res.getMetadata().getDeletionTime(), "Incorrect deletion date");
assertEquals(false, res.getMetadata().isDestroyed(), "Secret destroyed when not expected"); assertFalse(res.getMetadata().isDestroyed(), "Secret destroyed when not expected");
assertEquals(1, res.getMetadata().getVersion(), "Incorrect secret version"); assertEquals(1, res.getMetadata().getVersion(), "Incorrect secret version");
// Deleted KV v2 secret. // Deleted KV v2 secret.
res = assertDoesNotThrow( res = assertDoesNotThrow(
() -> new ObjectMapper().readValue(SECRET_JSON_V2_2, SecretResponse.class), () -> new ObjectMapper().readValue(SECRET_JSON_V2_2, MetaSecretResponse.class),
"SecretResponse deserialization failed" "SecretResponse deserialization failed"
); );
assertSecretData(res); assertSecretData(res);
@ -185,12 +126,13 @@ class SecretResponseTest {
assertNotNull(res.getMetadata().getCreatedTime(), "Creation date parsing failed"); assertNotNull(res.getMetadata().getCreatedTime(), "Creation date parsing failed");
assertEquals(SECRET_META_DELETED, res.getMetadata().getDeletionTimeString(), "Incorrect deletion date string"); assertEquals(SECRET_META_DELETED, res.getMetadata().getDeletionTimeString(), "Incorrect deletion date string");
assertNotNull(res.getMetadata().getDeletionTime(), "Incorrect deletion date"); assertNotNull(res.getMetadata().getDeletionTime(), "Incorrect deletion date");
assertEquals(true, res.getMetadata().isDestroyed(), "Secret destroyed when not expected"); assertTrue(res.getMetadata().isDestroyed(), "Secret destroyed when not expected");
assertEquals(2, res.getMetadata().getVersion(), "Incorrect secret version"); assertEquals(2, res.getMetadata().getVersion(), "Incorrect secret version");
} }
private void assertSecretData(SecretResponse res) { private void assertSecretData(SecretResponse res) {
assertNotNull(res, "Parsed response is NULL"); assertNotNull(res, "Parsed response is NULL");
assertEquals(SECRET_REQUEST_ID, res.getRequestId(), "Incorrect request ID");
assertEquals(SECRET_LEASE_ID, res.getLeaseId(), "Incorrect lease ID"); assertEquals(SECRET_LEASE_ID, res.getLeaseId(), "Incorrect lease ID");
assertEquals(SECRET_LEASE_DURATION, res.getLeaseDuration(), "Incorrect lease duration"); assertEquals(SECRET_LEASE_DURATION, res.getLeaseDuration(), "Incorrect lease duration");
assertEquals(SECRET_RENEWABLE, res.isRenewable(), "Incorrect renewable status"); assertEquals(SECRET_RENEWABLE, res.isRenewable(), "Incorrect renewable status");

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2021 Stefan Kalscheuer * Copyright 2016-2022 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,7 +16,9 @@
package de.stklcode.jvault.connector.model.response; package de.stklcode.jvault.connector.model.response;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import de.stklcode.jvault.connector.model.AbstractModelTest;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
@ -27,7 +29,7 @@ import static org.junit.jupiter.api.Assertions.*;
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.8 * @since 0.8
*/ */
class MetadataResponseTest { class MetadataResponseTest extends AbstractModelTest<MetadataResponse> {
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";
@ -62,6 +64,20 @@ class MetadataResponseTest {
" }\n" + " }\n" +
"}"; "}";
MetadataResponseTest() {
super(MetadataResponse.class);
}
@Override
protected MetadataResponse createFull() {
try {
return new ObjectMapper().readValue(META_JSON, MetadataResponse.class);
} catch (JsonProcessingException e) {
fail("Creation of full model instance failed", e);
return null;
}
}
/** /**
* 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).
*/ */

View File

@ -0,0 +1,89 @@
/*
* 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.model.response;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import de.stklcode.jvault.connector.model.AbstractModelTest;
import org.junit.jupiter.api.Test;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
/**
* JUnit Test for {@link PlainSecretResponse} model.
*
* @author Stefan Kalscheuer
* @since 0.6.2
*/
class PlainSecretResponseTest extends AbstractModelTest<PlainSecretResponse> {
private static final String SECRET_REQUEST_ID = "68315073-6658-e3ff-2da7-67939fb91bbd";
private static final String SECRET_LEASE_ID = "";
private static final Integer SECRET_LEASE_DURATION = 2764800;
private static final boolean SECRET_RENEWABLE = false;
private static final String SECRET_DATA_K1 = "excited";
private static final String SECRET_DATA_V1 = "yes";
private static final String SECRET_DATA_K2 = "value";
private static final String SECRET_DATA_V2 = "world";
private static final List<String> SECRET_WARNINGS = null;
private static final String SECRET_JSON = "{\n" +
" \"request_id\": \"" + SECRET_REQUEST_ID + "\",\n" +
" \"lease_id\": \"" + SECRET_LEASE_ID + "\",\n" +
" \"lease_duration\": " + SECRET_LEASE_DURATION + ",\n" +
" \"renewable\": " + SECRET_RENEWABLE + ",\n" +
" \"data\": {\n" +
" \"" + SECRET_DATA_K1 + "\": \"" + SECRET_DATA_V1 + "\",\n" +
" \"" + SECRET_DATA_K2 + "\": \"" + SECRET_DATA_V2 + "\"\n" +
" },\n" +
" \"warnings\": " + SECRET_WARNINGS + "\n" +
"}";
PlainSecretResponseTest() {
super(PlainSecretResponse.class);
}
@Override
protected PlainSecretResponse createFull() {
try {
return new ObjectMapper().readValue(SECRET_JSON, PlainSecretResponse.class);
} catch (JsonProcessingException e) {
fail("Creation of full model instance failed", e);
return null;
}
}
/**
* Test creation from JSON value as returned by Vault (JSON example copied from Vault documentation).
*/
@Test
void jsonRoundtrip() {
SecretResponse res = assertDoesNotThrow(
() -> new ObjectMapper().readValue(SECRET_JSON, PlainSecretResponse.class),
"SecretResponse deserialization failed"
);
assertNotNull(res, "Parsed response is NULL");
assertEquals(SECRET_REQUEST_ID, res.getRequestId(), "Incorrect request ID");
assertEquals(SECRET_LEASE_ID, res.getLeaseId(), "Incorrect lease ID");
assertEquals(SECRET_LEASE_DURATION, res.getLeaseDuration(), "Incorrect lease duration");
assertEquals(SECRET_RENEWABLE, res.isRenewable(), "Incorrect renewable status");
assertEquals(SECRET_WARNINGS, res.getWarnings(), "Incorrect warnings");
assertEquals(SECRET_DATA_V1, res.get(SECRET_DATA_K1), "Response does not contain correct data");
assertEquals(SECRET_DATA_V2, res.get(SECRET_DATA_K2), "Response does not contain correct data");
}
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2021 Stefan Kalscheuer * Copyright 2016-2022 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,7 +16,9 @@
package de.stklcode.jvault.connector.model.response; package de.stklcode.jvault.connector.model.response;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import de.stklcode.jvault.connector.model.AbstractModelTest;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
@ -27,16 +29,19 @@ import static org.junit.jupiter.api.Assertions.*;
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.8 * @since 0.8
*/ */
class SealResponseTest { class SealResponseTest extends AbstractModelTest<SealResponse> {
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;
private static final Integer PROGRESS_SEALED = 2; private static final Integer PROGRESS_SEALED = 2;
private static final Integer PROGRESS_UNSEALED = 0; private static final Integer PROGRESS_UNSEALED = 0;
private static final String VERSION = "0.11.2"; private static final String VERSION = "1.8.2";
private static final String CLUSTER_NAME = "vault-cluster-d6ec3c7f"; private static final String CLUSTER_NAME = "vault-cluster-d6ec3c7f";
private static final String CLUSTER_ID = "3e8b3fec-3749-e056-ba41-b62a63b997e8"; private static final String CLUSTER_ID = "3e8b3fec-3749-e056-ba41-b62a63b997e8";
private static final String NONCE = "ef05d55d-4d2c-c594-a5e8-55bc88604c24"; private static final String NONCE = "ef05d55d-4d2c-c594-a5e8-55bc88604c24";
private static final Boolean MIGRATION = false;
private static final Boolean RECOVERY_SEAL = false;
private static final String STORAGE_TYPE = "file";
private static final String RES_SEALED = "{\n" + private static final String RES_SEALED = "{\n" +
" \"type\": \"" + TYPE + "\",\n" + " \"type\": \"" + TYPE + "\",\n" +
@ -46,7 +51,10 @@ class SealResponseTest {
" \"n\": " + SHARES + ",\n" + " \"n\": " + SHARES + ",\n" +
" \"progress\": " + PROGRESS_SEALED + ",\n" + " \"progress\": " + PROGRESS_SEALED + ",\n" +
" \"nonce\": \"\",\n" + " \"nonce\": \"\",\n" +
" \"version\": \"" + VERSION + "\"\n" + " \"version\": \"" + VERSION + "\",\n" +
" \"migration\": \"" + MIGRATION + "\",\n" +
" \"recovery_seal\": \"" + RECOVERY_SEAL + "\",\n" +
" \"storage_type\": \"" + STORAGE_TYPE + "\"\n" +
"}"; "}";
private static final String RES_UNSEALED = "{\n" + private static final String RES_UNSEALED = "{\n" +
@ -59,9 +67,26 @@ class SealResponseTest {
" \"version\": \"" + VERSION + "\",\n" + " \"version\": \"" + VERSION + "\",\n" +
" \"cluster_name\": \"" + CLUSTER_NAME + "\",\n" + " \"cluster_name\": \"" + CLUSTER_NAME + "\",\n" +
" \"cluster_id\": \"" + CLUSTER_ID + "\",\n" + " \"cluster_id\": \"" + CLUSTER_ID + "\",\n" +
" \"nonce\": \"" + NONCE + "\"\n" + " \"nonce\": \"" + NONCE + "\",\n" +
" \"migration\": \"" + MIGRATION + "\",\n" +
" \"recovery_seal\": \"" + RECOVERY_SEAL + "\",\n" +
" \"storage_type\": \"" + STORAGE_TYPE + "\"\n" +
"}"; "}";
SealResponseTest() {
super(SealResponse.class);
}
@Override
protected SealResponse createFull() {
try {
return new ObjectMapper().readValue(RES_UNSEALED, SealResponse.class);
} catch (JsonProcessingException e) {
fail("Creation of full model instance failed", e);
return null;
}
}
/** /**
* 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).
*/ */
@ -70,7 +95,7 @@ class SealResponseTest {
// First test sealed Vault's response. // First test sealed Vault's response.
SealResponse res = assertDoesNotThrow( SealResponse res = assertDoesNotThrow(
() -> new ObjectMapper().readValue(RES_SEALED, SealResponse.class), () -> new ObjectMapper().readValue(RES_SEALED, SealResponse.class),
"TokenResponse deserialization failed" "SealResponse deserialization failed"
); );
assertNotNull(res, "Parsed response is NULL"); assertNotNull(res, "Parsed response is NULL");
assertEquals(TYPE, res.getType(), "Incorrect seal type"); assertEquals(TYPE, res.getType(), "Incorrect seal type");
@ -81,6 +106,9 @@ class SealResponseTest {
assertEquals(PROGRESS_SEALED, res.getProgress(), "Incorrect progress"); assertEquals(PROGRESS_SEALED, res.getProgress(), "Incorrect progress");
assertEquals("", res.getNonce(), "Nonce not empty"); assertEquals("", res.getNonce(), "Nonce not empty");
assertEquals(VERSION, res.getVersion(), "Incorrect version"); assertEquals(VERSION, res.getVersion(), "Incorrect version");
assertEquals(MIGRATION, res.getMigration(), "Incorrect migration");
assertEquals(RECOVERY_SEAL, res.getRecoverySeal(), "Incorrect recovery seal");
assertEquals(STORAGE_TYPE, res.getStorageType(), "Incorrect storage type");
// And the fields, that should not be filled. // And the fields, that should not be filled.
assertNull(res.getClusterName(), "Cluster name should not be populated"); assertNull(res.getClusterName(), "Cluster name should not be populated");
assertNull(res.getClusterId(), "Cluster ID should not be populated"); assertNull(res.getClusterId(), "Cluster ID should not be populated");
@ -89,7 +117,7 @@ class SealResponseTest {
// Not test unsealed Vault's response. // Not test unsealed Vault's response.
res = assertDoesNotThrow( res = assertDoesNotThrow(
() -> new ObjectMapper().readValue(RES_UNSEALED, SealResponse.class), () -> new ObjectMapper().readValue(RES_UNSEALED, SealResponse.class),
"TokenResponse deserialization failed" "SealResponse deserialization failed"
); );
assertNotNull(res, "Parsed response is NULL"); assertNotNull(res, "Parsed response is NULL");
assertEquals(TYPE, res.getType(), "Incorrect seal type"); assertEquals(TYPE, res.getType(), "Incorrect seal type");
@ -102,5 +130,8 @@ class SealResponseTest {
assertEquals(VERSION, res.getVersion(), "Incorrect version"); assertEquals(VERSION, res.getVersion(), "Incorrect version");
assertEquals(CLUSTER_NAME, res.getClusterName(), "Incorrect cluster name"); assertEquals(CLUSTER_NAME, res.getClusterName(), "Incorrect cluster name");
assertEquals(CLUSTER_ID, res.getClusterId(), "Incorrect cluster ID"); assertEquals(CLUSTER_ID, res.getClusterId(), "Incorrect cluster ID");
assertEquals(MIGRATION, res.getMigration(), "Incorrect migration");
assertEquals(RECOVERY_SEAL, res.getRecoverySeal(), "Incorrect recovery seal");
assertEquals(STORAGE_TYPE, res.getStorageType(), "Incorrect storage type");
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2021 Stefan Kalscheuer * Copyright 2016-2022 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,10 +16,12 @@
package de.stklcode.jvault.connector.model.response; package de.stklcode.jvault.connector.model.response;
import de.stklcode.jvault.connector.exception.InvalidResponseException; import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import de.stklcode.jvault.connector.model.AbstractModelTest;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.util.*; import java.util.List;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
@ -29,40 +31,46 @@ import static org.junit.jupiter.api.Assertions.*;
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.8 * @since 0.8
*/ */
class SecretListResponseTest { class SecretListResponseTest extends AbstractModelTest<SecretListResponse> {
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";
private static final List<String> KEYS = Arrays.asList(KEY1, KEY2); private static final String JSON = "{\n" +
" \"auth\": null,\n" +
" \"data\": {\n" +
" \"keys\": [" +
" \"" + KEY1 + "\",\n" +
" \"" + KEY2 + "\"\n" +
" ]\n" +
" },\n" +
" \"lease_duration\": 2764800,\n" +
" \"lease_id\": \"\",\n" +
" \"renewable\": false\n" +
"}";
static { SecretListResponseTest() {
DATA.put("keys", KEYS); super(SecretListResponse.class);
}
@Override
protected SecretListResponse createFull() {
try {
return new ObjectMapper().readValue(JSON, SecretListResponse.class);
} catch (JsonProcessingException e) {
fail("Creation of full model instance failed", e);
return null;
}
} }
/** /**
* Test getter, setter and get-methods for response data. * Test JSON deserialization and key getter.
*
* @throws InvalidResponseException Should not occur
*/ */
@Test @Test
void getKeysTest() throws InvalidResponseException { void getKeysTest() {
// Create empty Object. SecretListResponse res = assertDoesNotThrow(
SecretListResponse res = new SecretListResponse(); () -> new ObjectMapper().readValue(JSON, SecretListResponse.class),
assertNull(res.getKeys(), "Keys should be null without initialization"); "SecretListResponse deserialization failed"
// Provoke internal ClassCastException.
Map<String, Object> invalidData = new HashMap<>();
invalidData.put("keys", "some string");
assertThrows(
InvalidResponseException.class,
() -> res.setData(invalidData),
"Setting incorrect class succeeded"
); );
// Fill correct data. assertEquals(List.of(KEY1, KEY2), res.getKeys(), "Unexpected secret keys");
res.setData(DATA);
assertNotNull(res.getKeys(), "Keys should be filled here");
assertEquals(2, res.getKeys().size(), "Unexpected number of keys");
assertTrue(res.getKeys().containsAll(Set.of(KEY1, KEY2)), "Unexpected keys");
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2021 Stefan Kalscheuer * Copyright 2016-2022 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,7 +16,9 @@
package de.stklcode.jvault.connector.model.response; package de.stklcode.jvault.connector.model.response;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import de.stklcode.jvault.connector.model.AbstractModelTest;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
@ -27,7 +29,7 @@ import static org.junit.jupiter.api.Assertions.*;
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.8 * @since 0.8
*/ */
class SecretVersionResponseTest { class SecretVersionResponseTest extends AbstractModelTest<SecretVersionResponse> {
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;
@ -41,6 +43,20 @@ class SecretVersionResponseTest {
" }\n" + " }\n" +
"}"; "}";
SecretVersionResponseTest() {
super(SecretVersionResponse.class);
}
@Override
protected SecretVersionResponse createFull() {
try {
return new ObjectMapper().readValue(META_JSON, SecretVersionResponse.class);
} catch (JsonProcessingException e) {
fail("Creation of full model instance failed", e);
return null;
}
}
/** /**
* 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).
*/ */
@ -54,7 +70,7 @@ class SecretVersionResponseTest {
assertNotNull(res.getMetadata(), "Parsed metadata is NULL"); assertNotNull(res.getMetadata(), "Parsed metadata is NULL");
assertEquals(CREATION_TIME, res.getMetadata().getCreatedTimeString(), "Incorrect created time"); assertEquals(CREATION_TIME, res.getMetadata().getCreatedTimeString(), "Incorrect created time");
assertEquals(DELETION_TIME, res.getMetadata().getDeletionTimeString(), "Incorrect deletion time"); assertEquals(DELETION_TIME, res.getMetadata().getDeletionTimeString(), "Incorrect deletion time");
assertEquals(false, res.getMetadata().isDestroyed(), "Incorrect destroyed state"); assertFalse(res.getMetadata().isDestroyed(), "Incorrect destroyed state");
assertEquals(VERSION, res.getMetadata().getVersion(), "Incorrect version"); assertEquals(VERSION, res.getMetadata().getVersion(), "Incorrect version");
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2021 Stefan Kalscheuer * Copyright 2016-2022 Stefan Kalscheuer
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,13 +16,13 @@
package de.stklcode.jvault.connector.model.response; package de.stklcode.jvault.connector.model.response;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import de.stklcode.jvault.connector.exception.InvalidResponseException; import de.stklcode.jvault.connector.model.AbstractModelTest;
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.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -34,7 +34,7 @@ import static org.junit.jupiter.api.Assertions.*;
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.6.2 * @since 0.6.2
*/ */
class TokenResponseTest { class TokenResponseTest extends AbstractModelTest<TokenResponse> {
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;
@ -89,10 +89,18 @@ class TokenResponseTest {
" \"auth\": null\n" + " \"auth\": null\n" +
"}"; "}";
private static final Map<String, Object> INVALID_TOKEN_DATA = new HashMap<>(); TokenResponseTest() {
super(TokenResponse.class);
}
static { @Override
INVALID_TOKEN_DATA.put("num_uses", "fourtytwo"); protected TokenResponse createFull() {
try {
return new ObjectMapper().readValue(RES_JSON, TokenResponse.class);
} catch (JsonProcessingException e) {
fail("Creation of full model instance failed", e);
return null;
}
} }
/** /**
@ -103,13 +111,6 @@ class TokenResponseTest {
// Create empty Object. // Create empty Object.
TokenResponse res = new TokenResponse(); TokenResponse res = new TokenResponse();
assertNull(res.getData(), "Initial data should be empty"); assertNull(res.getData(), "Initial data should be empty");
// Parsing invalid data map should fail.
assertThrows(
InvalidResponseException.class,
() -> res.setData(INVALID_TOKEN_DATA),
"Parsing invalid token data succeeded"
);
} }
/** /**

View File

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

View File

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