#5 Role and Secret creation implemented and tested

This commit is contained in:
2016-11-04 23:02:36 +01:00
parent c7b4c46ad2
commit 40742b00de
21 changed files with 1447 additions and 76 deletions

View File

@@ -0,0 +1,147 @@
/*
* Copyright 2016 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;
import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import java.util.List;
/**
* Vault AppRole role metamodel.
*
* @author Stefan Kalscheuer
* @since 0.4.0
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class AppRole {
@JsonProperty("role_name")
private String name;
@JsonProperty("role_id")
@JsonInclude(JsonInclude.Include.NON_NULL)
private String id;
@JsonProperty("bind_secret_id")
@JsonInclude(JsonInclude.Include.NON_NULL)
private Boolean bindSecretId;
private List<String> boundCidrList;
private List<String> policies;
@JsonProperty("secret_id_num_uses")
@JsonInclude(JsonInclude.Include.NON_NULL)
private Integer secretIdNumUses;
@JsonProperty("secret_id_ttl")
@JsonInclude(JsonInclude.Include.NON_NULL)
private Integer secretIdTtl;
@JsonProperty("token_ttl")
@JsonInclude(JsonInclude.Include.NON_NULL)
private Integer tokenTtl;
@JsonProperty("token_max_ttl")
@JsonInclude(JsonInclude.Include.NON_NULL)
private Integer tokenMaxTtl;
@JsonProperty("period")
@JsonInclude(JsonInclude.Include.NON_NULL)
private Integer period;
public AppRole() {
}
public AppRole(String name, String id, Boolean bindSecretId, List<String> boundCidrList, List<String> policies, Integer secretIdNumUses, Integer secretIdTtl, Integer tokenTtl, Integer tokenMaxTtl, Integer period) {
this.name = name;
this.id = id;
this.bindSecretId = bindSecretId;
this.boundCidrList = boundCidrList;
this.policies = policies;
this.secretIdNumUses = secretIdNumUses;
this.secretIdTtl = secretIdTtl;
this.tokenTtl = tokenTtl;
this.tokenMaxTtl = tokenMaxTtl;
this.period = period;
}
public String getName() {
return name;
}
public String getId() {
return id;
}
public Boolean getBindSecretId() {
return bindSecretId;
}
public List<String> getBoundCidrList() {
return boundCidrList;
}
@JsonSetter("bound_cidr_list")
public void setBoundCidrList(List<String> boundCidrList) {
this.boundCidrList = boundCidrList;
}
@JsonGetter("bound_cidr_list")
public String getBoundCidrListString() {
if (boundCidrList == null || boundCidrList.isEmpty())
return "";
return String.join(",", boundCidrList);
}
public List<String> getPolicies() {
return policies;
}
@JsonSetter("policies")
public void setPolicies(List<String> policies) {
this.policies = policies;
}
@JsonGetter("policies")
public String getPoliciesString() {
if (policies == null || policies.isEmpty())
return "";
return String.join(",", policies);
}
public Integer getSecretIdNumUses() {
return secretIdNumUses;
}
public Integer getSecretIdTtl() {
return secretIdTtl;
}
public Integer getTokenTtl() {
return tokenTtl;
}
public Integer getTokenMaxTtl() {
return tokenMaxTtl;
}
public Integer getPeriod() {
return period;
}
}

View File

@@ -0,0 +1,209 @@
/*
* Copyright 2016 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;
import java.util.ArrayList;
import java.util.List;
/**
* A builder for vault AppRole roles..
*
* @author Stefan Kalscheuer
* @since 0.4.0
*/
public class AppRoleBuilder {
private String name;
private String id;
private Boolean bindSecretId;
private List<String> boundCidrList;
private List<String> policies;
private Integer secretIdNumUses;
private Integer secretIdTtl;
private Integer tokenTtl;
private Integer tokenMaxTtl;
private Integer period;
public AppRoleBuilder(String name) {
this.name = name;
}
/**
* Add custom role ID (optional)
*
* @param id the ID
* @return self
*/
public AppRoleBuilder withId(final String id) {
this.id = id;
return this;
}
/**
* Set if role is bound to secret ID
*
* @param bindSecretId the display name
* @return self
*/
public AppRoleBuilder withBindSecretID(final Boolean bindSecretId) {
this.bindSecretId = bindSecretId;
return this;
}
/**
* Bind role to secret ID.
* Convenience method for {@link #withBindSecretID(Boolean)}
*
* @return self
*/
public AppRoleBuilder withBindSecretID() {
return withBindSecretID(true);
}
/**
* Do not bind role to secret ID.
* Convenience method for {@link #withBindSecretID(Boolean)}
*
* @return self
*/
public AppRoleBuilder withoutBindSecretID() {
return withBindSecretID(false);
}
/**
* Set bound CIDR blocks.
*
* @param boundCidrList List of CIDR blocks which can perform login
* @return self
*/
public AppRoleBuilder withBoundCidrList(final List<String> boundCidrList) {
this.boundCidrList = boundCidrList;
return this;
}
/**
* Add a CIDR block to list of bound blocks.
*
* @param cidrBlock the CIDR block
* @return self
*/
public AppRoleBuilder withCidrBlock(final String cidrBlock) {
if (boundCidrList == null)
boundCidrList = new ArrayList<>();
boundCidrList.add(cidrBlock);
return this;
}
/**
* Add given policies
*
* @param policies the policies
* @return self
*/
public AppRoleBuilder withPolicies(final List<String> policies) {
if (this.policies == null)
this.policies = new ArrayList<>();
this.policies.addAll(policies);
return this;
}
/**
* Add a single policy.
*
* @param policy the policy
* @return self
*/
public AppRoleBuilder withPolicy(final String policy) {
if (this.policies == null)
this.policies = new ArrayList<>();
policies.add(policy);
return this;
}
/**
* Set number of uses for sectet IDs.
*
* @param secredIdNumUses the number of uses
* @return self
*/
public AppRoleBuilder withSecretIdNumUses(final Integer secredIdNumUses) {
this.secretIdNumUses = secredIdNumUses;
return this;
}
/**
* Set default sectet ID TTL in seconds.
*
* @param secredIdTtl the TTL
* @return self
*/
public AppRoleBuilder withSecretIdTtl(final Integer secredIdTtl) {
this.secretIdTtl = secredIdTtl;
return this;
}
/**
* Set default token TTL in seconds.
*
* @param tokenTtl the TTL
* @return self
*/
public AppRoleBuilder withTokenTtl(final Integer tokenTtl) {
this.tokenTtl = tokenTtl;
return this;
}
/**
* Set maximum token TTL in seconds.
*
* @param tokenMaxTtl the TTL
* @return self
*/
public AppRoleBuilder withTokenMaxTtl(final Integer tokenMaxTtl) {
this.tokenMaxTtl = tokenMaxTtl;
return this;
}
/**
* Set renewal period for generated token in seconds.
*
* @param period period in seconds
* @return self
*/
public AppRoleBuilder withPeriod(final Integer period) {
this.period = period;
return this;
}
/**
* Build the AppRole role based on given parameters.
*
* @return the role
*/
public AppRole build() {
return new AppRole(name,
id,
bindSecretId,
boundCidrList,
policies,
secretIdNumUses,
secretIdTtl,
tokenTtl,
tokenMaxTtl,
period);
}
}

View File

@@ -0,0 +1,121 @@
/*
* Copyright 2016 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;
import com.fasterxml.jackson.annotation.*;
import java.util.List;
import java.util.Map;
/**
* Vault AppRole role metamodel.
*
* @author Stefan Kalscheuer
* @since 0.4.0
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class AppRoleSecret {
@JsonProperty("secret_id")
@JsonInclude(JsonInclude.Include.NON_NULL)
private String id;
@JsonProperty(value = "secret_id_accessor", access = JsonProperty.Access.WRITE_ONLY)
private String accessor;
@JsonProperty("metadata")
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private Map<String, Object> metadata;
private List<String> cidrList;
@JsonProperty(value = "creation_time", access = JsonProperty.Access.WRITE_ONLY)
private String creationTime;
@JsonProperty(value = "expiration_time", access = JsonProperty.Access.WRITE_ONLY)
private String expirationTime;
@JsonProperty(value = "last_updated_time", access = JsonProperty.Access.WRITE_ONLY)
private String lastUpdatedTime;
@JsonProperty(value = "secret_id_num_uses", access = JsonProperty.Access.WRITE_ONLY)
private Integer numUses;
@JsonProperty(value = "secret_id_ttl", access = JsonProperty.Access.WRITE_ONLY)
private Integer ttl;
public AppRoleSecret() {
}
public AppRoleSecret(String id) {
this.id = id;
}
public AppRoleSecret(String id, Map<String, Object> metadata, List<String> cidrList) {
this.id = id;
this.metadata = metadata;
this.cidrList = cidrList;
}
public String getId() {
return id;
}
public String getAccessor() {
return accessor;
}
public Map<String, Object> getMetadata() {
return metadata;
}
public List<String> getCidrList() {
return cidrList;
}
@JsonSetter("cidr_list")
public void setCidrList(List<String> cidrList) {
this.cidrList = cidrList;
}
@JsonGetter("cidr_list")
public String getCidrListString() {
if (cidrList == null || cidrList.isEmpty())
return "";
return String.join(",", cidrList);
}
public String getCreationTime() {
return creationTime;
}
public String getExpirationTime() {
return expirationTime;
}
public String getLastUpdatedTime() {
return lastUpdatedTime;
}
public Integer getNumUses() {
return numUses;
}
public Integer getTtl() {
return ttl;
}
}

View File

@@ -25,6 +25,7 @@ package de.stklcode.jvault.connector.model;
public enum AuthBackend {
TOKEN("token"),
APPID("app-id"),
APPROLE("approle"),
USERPASS("userpass"),
UNKNOWN("");

View File

@@ -0,0 +1,56 @@
/*
* Copyright 2016 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.databind.ObjectMapper;
import de.stklcode.jvault.connector.exception.InvalidResponseException;
import de.stklcode.jvault.connector.model.AppRole;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
/**
* Vault response for AppRole lookup.
*
* @author Stefan Kalscheuer
* @since 0.4.0
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class AppRoleResponse extends VaultDataResponse {
private AppRole role;
@Override
public void setData(Map<String, Object> data) throws InvalidResponseException {
ObjectMapper mapper = new ObjectMapper();
try {
/* null empty strings on list objects */
Map<String, Object> filteredData = new HashMap<>();
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) {
e.printStackTrace();
throw new InvalidResponseException();
}
}
public AppRole getRole() {
return role;
}
}

View File

@@ -0,0 +1,56 @@
/*
* Copyright 2016 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.databind.ObjectMapper;
import de.stklcode.jvault.connector.exception.InvalidResponseException;
import de.stklcode.jvault.connector.model.AppRole;
import de.stklcode.jvault.connector.model.AppRoleSecret;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* Vault response for AppRole lookup.
*
* @author Stefan Kalscheuer
* @since 0.4.0
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class AppRoleSecretResponse extends VaultDataResponse {
private AppRoleSecret secret;
@Override
public void setData(Map<String, Object> data) throws InvalidResponseException {
ObjectMapper mapper = new ObjectMapper();
try {
/* null empty strings on list objects */
Map<String, Object> filteredData = new HashMap<>();
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) {
e.printStackTrace();
throw new InvalidResponseException();
}
}
public AppRoleSecret getSecret() {
return secret;
}
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright 2016 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 java.util.Map;
/**
* Simple Vault data response.
*
* @author Stefan Kalscheuer
* @since 0.4.0
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class RawDataResponse extends VaultDataResponse {
private Map<String, Object> data;
@Override
public void setData(Map<String, Object> data) {
this.data = data;
}
public Map<String, Object> getData() {
return data;
}
}