parent
7ab9be3c1f
commit
781300d024
|
@ -0,0 +1,44 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>com.baeldung.spring-credhub</groupId>
|
||||||
|
<artifactId>spring-credhub</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>parent-boot-2</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<relativePath>../parent-boot-2</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.credhub</groupId>
|
||||||
|
<artifactId>spring-credhub-starter</artifactId>
|
||||||
|
<version>2.2.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.code.gson</groupId>
|
||||||
|
<artifactId>gson</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>8</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,7 @@
|
||||||
|
package com.baeldung;
|
||||||
|
|
||||||
|
public class OrderApplication {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
System.out.println("Hello world!");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
package com.baeldung.controller;
|
||||||
|
|
||||||
|
import com.baeldung.model.Credential;
|
||||||
|
import com.baeldung.service.CredentialService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.credhub.support.CredentialPermission;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PutMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
public class CredentialController {
|
||||||
|
@Autowired
|
||||||
|
CredentialService credentialService;
|
||||||
|
|
||||||
|
@PostMapping("/credentials")
|
||||||
|
public ResponseEntity<String> generatePassword(@RequestBody String credentialName) {
|
||||||
|
return new ResponseEntity<>(credentialService.generatePassword(credentialName), HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping("/credentials")
|
||||||
|
public ResponseEntity<String> writeJSONCredential(@RequestBody Credential secret) {
|
||||||
|
return new ResponseEntity<>(credentialService.writeCredential(secret), HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/credentials/rotate")
|
||||||
|
public ResponseEntity<String> rotatePassword(@RequestBody String credentialName) {
|
||||||
|
return new ResponseEntity<>(credentialService.rotatePassword(credentialName), HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/credentials")
|
||||||
|
public ResponseEntity<String> deletePassword(@RequestBody String credentialName) {
|
||||||
|
return new ResponseEntity<>(credentialService.deletePassword(credentialName), HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/credentials")
|
||||||
|
public ResponseEntity<String> getPassword(@RequestBody String credentialName) {
|
||||||
|
return new ResponseEntity<>(credentialService.getPassword(credentialName), HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/permissions")
|
||||||
|
public ResponseEntity<CredentialPermission> addPermission(@RequestBody String credentialName) {
|
||||||
|
return new ResponseEntity<>(credentialService.addCredentialPermission(credentialName), HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/permissions")
|
||||||
|
public ResponseEntity<CredentialPermission> getPermission(@RequestBody String credentialName) {
|
||||||
|
return new ResponseEntity<>(credentialService.getCredentialPermission(credentialName), HttpStatus.OK);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
package com.baeldung.controller;
|
||||||
|
|
||||||
|
import static java.time.LocalDate.now;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.baeldung.model.Order;
|
||||||
|
import com.baeldung.service.CredentialService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/orders")
|
||||||
|
public class OrderController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
CredentialService credentialService;
|
||||||
|
|
||||||
|
public OrderController(CredentialService credentialService) {
|
||||||
|
this.credentialService = credentialService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping
|
||||||
|
public ResponseEntity<Collection<Order>> getAllOrders() {
|
||||||
|
try {
|
||||||
|
String apiKey = credentialService.getPassword("api_key");
|
||||||
|
return new ResponseEntity<>(getOrderList(apiKey), HttpStatus.OK);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return new ResponseEntity<>(HttpStatus.FORBIDDEN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Order> getOrderList(String apiKey) throws Exception {
|
||||||
|
if (!credentialMatch(apiKey))
|
||||||
|
throw new Exception();
|
||||||
|
Order order = new Order();
|
||||||
|
order.setId(123L);
|
||||||
|
order.setCustomerName("Craig");
|
||||||
|
order.setOrderDate(now());
|
||||||
|
List<Order> orderList = new ArrayList<>();
|
||||||
|
orderList.add(order);
|
||||||
|
return orderList;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean credentialMatch(String credValue) {
|
||||||
|
//logic to check credValue
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
package com.baeldung.model;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class Credential {
|
||||||
|
Map<String, Object> value;
|
||||||
|
String type;
|
||||||
|
String name;
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.baeldung.model;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class Order {
|
||||||
|
|
||||||
|
private Long id;
|
||||||
|
private String customerName;
|
||||||
|
private LocalDate orderDate;
|
||||||
|
}
|
|
@ -0,0 +1,195 @@
|
||||||
|
package com.baeldung.service;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.springframework.credhub.core.CredHubOperations;
|
||||||
|
import org.springframework.credhub.core.credential.CredHubCredentialOperations;
|
||||||
|
import org.springframework.credhub.core.permissionV2.CredHubPermissionV2Operations;
|
||||||
|
import org.springframework.credhub.support.CredentialDetails;
|
||||||
|
import org.springframework.credhub.support.CredentialPermission;
|
||||||
|
import org.springframework.credhub.support.CredentialRequest;
|
||||||
|
import org.springframework.credhub.support.SimpleCredentialName;
|
||||||
|
import org.springframework.credhub.support.certificate.CertificateCredential;
|
||||||
|
import org.springframework.credhub.support.certificate.CertificateCredentialRequest;
|
||||||
|
import org.springframework.credhub.support.json.JsonCredentialRequest;
|
||||||
|
import org.springframework.credhub.support.password.PasswordCredential;
|
||||||
|
import org.springframework.credhub.support.password.PasswordCredentialRequest;
|
||||||
|
import org.springframework.credhub.support.password.PasswordParameters;
|
||||||
|
import org.springframework.credhub.support.password.PasswordParametersRequest;
|
||||||
|
import org.springframework.credhub.support.permissions.Operation;
|
||||||
|
import org.springframework.credhub.support.permissions.Permission;
|
||||||
|
import org.springframework.credhub.support.rsa.RsaCredential;
|
||||||
|
import org.springframework.credhub.support.rsa.RsaCredentialRequest;
|
||||||
|
import org.springframework.credhub.support.ssh.SshCredential;
|
||||||
|
import org.springframework.credhub.support.ssh.SshCredentialRequest;
|
||||||
|
import org.springframework.credhub.support.user.UserCredential;
|
||||||
|
import org.springframework.credhub.support.user.UserCredentialRequest;
|
||||||
|
import org.springframework.credhub.support.value.ValueCredential;
|
||||||
|
import org.springframework.credhub.support.value.ValueCredentialRequest;
|
||||||
|
|
||||||
|
import com.baeldung.model.Credential;
|
||||||
|
|
||||||
|
public class CredentialService {
|
||||||
|
|
||||||
|
private final CredHubCredentialOperations credentialOperations;
|
||||||
|
private final CredHubPermissionV2Operations permissionOperations;
|
||||||
|
|
||||||
|
public CredentialService(CredHubOperations credHubOperations) {
|
||||||
|
this.credentialOperations = credHubOperations.credentials();
|
||||||
|
this.permissionOperations = credHubOperations.permissionsV2();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String generatePassword(String name) {
|
||||||
|
try {
|
||||||
|
SimpleCredentialName credentialName = new SimpleCredentialName(name);
|
||||||
|
PasswordParameters parameters = PasswordParameters.builder()
|
||||||
|
.length(24)
|
||||||
|
.excludeUpper(false)
|
||||||
|
.excludeLower(false)
|
||||||
|
.includeSpecial(true)
|
||||||
|
.excludeNumber(false)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
CredentialDetails<PasswordCredential> generatedCred = credentialOperations.generate(PasswordParametersRequest.builder()
|
||||||
|
.name(credentialName)
|
||||||
|
.parameters(parameters)
|
||||||
|
.build());
|
||||||
|
|
||||||
|
return generatedCred.getValue()
|
||||||
|
.getPassword();
|
||||||
|
} catch (Exception e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String writeCredential(Credential credential) {
|
||||||
|
try {
|
||||||
|
SimpleCredentialName credentialName = new SimpleCredentialName(credential.getName());
|
||||||
|
CredentialRequest request = null;
|
||||||
|
Map<String, Object> value = credential.getValue();
|
||||||
|
switch (credential.getType()) {
|
||||||
|
case "value":
|
||||||
|
ValueCredential valueCredential = new ValueCredential((String) value.get("value"));
|
||||||
|
request = ValueCredentialRequest.builder()
|
||||||
|
.name(credentialName)
|
||||||
|
.value(valueCredential)
|
||||||
|
.build();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "json":
|
||||||
|
request = JsonCredentialRequest.builder()
|
||||||
|
.name(credentialName)
|
||||||
|
.value(value)
|
||||||
|
.build();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "user":
|
||||||
|
UserCredential userCredential = new UserCredential((String) value.get("username"), (String) value.get("password"));
|
||||||
|
request = UserCredentialRequest.builder()
|
||||||
|
.name(credentialName)
|
||||||
|
.value(userCredential)
|
||||||
|
.build();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "password":
|
||||||
|
PasswordCredential passwordCredential = new PasswordCredential((String) value.get("password"));
|
||||||
|
request = PasswordCredentialRequest.builder()
|
||||||
|
.name(credentialName)
|
||||||
|
.value(passwordCredential)
|
||||||
|
.build();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "certificate":
|
||||||
|
CertificateCredential certificateCredential = new CertificateCredential((String) value.get("certificate"), (String) value.get("certificate_authority"), (String) value.get("private_key"));
|
||||||
|
request = CertificateCredentialRequest.builder()
|
||||||
|
.name(credentialName)
|
||||||
|
.value(certificateCredential)
|
||||||
|
.build();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "rsa":
|
||||||
|
RsaCredential rsaCredential = new RsaCredential((String) value.get("public_key"), (String) value.get("private_key"));
|
||||||
|
request = RsaCredentialRequest.builder()
|
||||||
|
.name(credentialName)
|
||||||
|
.value(rsaCredential)
|
||||||
|
.build();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "ssh":
|
||||||
|
SshCredential sshCredential = new SshCredential((String) value.get("public_key"), (String) value.get("private_key"));
|
||||||
|
request = SshCredentialRequest.builder()
|
||||||
|
.name(credentialName)
|
||||||
|
.value(sshCredential)
|
||||||
|
.build();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
if (request != null) {
|
||||||
|
credentialOperations.write(request);
|
||||||
|
}
|
||||||
|
return "Credential:" + credentialName + " written successfully!";
|
||||||
|
} catch (Exception e) {
|
||||||
|
return "Error! Unable to write credential";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String rotatePassword(String name) {
|
||||||
|
try {
|
||||||
|
SimpleCredentialName credentialName = new SimpleCredentialName(name);
|
||||||
|
CredentialDetails<PasswordCredential> oldPassword = credentialOperations.getByName(credentialName, PasswordCredential.class);
|
||||||
|
CredentialDetails<PasswordCredential> newPassword = credentialOperations.regenerate(credentialName, PasswordCredential.class);
|
||||||
|
|
||||||
|
return "Credential:" + credentialName + " re-generated successfully!";
|
||||||
|
} catch (Exception e) {
|
||||||
|
return "Error! Unable to re-generate credential";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String deletePassword(String name) {
|
||||||
|
try {
|
||||||
|
SimpleCredentialName credentialName = new SimpleCredentialName(name);
|
||||||
|
credentialOperations.deleteByName(credentialName);
|
||||||
|
return "Credential:" + credentialName + " deleted successfully!";
|
||||||
|
} catch (Exception e) {
|
||||||
|
return "Error! Unable to delete credential";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword(String name) {
|
||||||
|
try {
|
||||||
|
SimpleCredentialName credentialName = new SimpleCredentialName(name);
|
||||||
|
return credentialOperations.getByName(credentialName, PasswordCredential.class)
|
||||||
|
.getValue()
|
||||||
|
.getPassword();
|
||||||
|
} catch (Exception e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public CredentialPermission addCredentialPermission(String name) {
|
||||||
|
SimpleCredentialName credentialName = new SimpleCredentialName(name);
|
||||||
|
try {
|
||||||
|
Permission permission = Permission.builder()
|
||||||
|
.app(UUID.randomUUID()
|
||||||
|
.toString())
|
||||||
|
.operations(Operation.READ, Operation.WRITE)
|
||||||
|
.user("u101")
|
||||||
|
.build();
|
||||||
|
CredentialPermission credentialPermission = permissionOperations.addPermissions(credentialName, permission);
|
||||||
|
return credentialPermission;
|
||||||
|
} catch (Exception e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public CredentialPermission getCredentialPermission(String name) {
|
||||||
|
try {
|
||||||
|
return permissionOperations.getPermissions(name);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
management:
|
||||||
|
endpoints:
|
||||||
|
web:
|
||||||
|
exposure:
|
||||||
|
include: "*"
|
||||||
|
|
||||||
|
spring:
|
||||||
|
credhub:
|
||||||
|
url: <url>
|
|
@ -0,0 +1,87 @@
|
||||||
|
package com.baeldung.controller;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.assertj.core.util.DateUtil;
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import org.springframework.credhub.support.CredentialPermission;
|
||||||
|
import org.springframework.credhub.support.permissions.Operation;
|
||||||
|
|
||||||
|
import com.baeldung.model.Credential;
|
||||||
|
import com.baeldung.service.CredentialService;
|
||||||
|
|
||||||
|
@Ignore
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
public class CredentialServiceUnitTest {
|
||||||
|
|
||||||
|
@InjectMocks
|
||||||
|
private CredentialService credentialService;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenGeneratePassword_thenReturnNewPassword() {
|
||||||
|
String orderApiKey = credentialService.generatePassword("order_api_key");
|
||||||
|
assertFalse(orderApiKey.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenWriteCredential_thenReturnSuccess() {
|
||||||
|
Map<String, Object> value = new HashMap<>();
|
||||||
|
value.put("end_date", DateUtil.now());
|
||||||
|
value.put("start_date", DateUtil.yesterday());
|
||||||
|
|
||||||
|
Credential credential = new Credential();
|
||||||
|
credential.setName("order_config_json");
|
||||||
|
credential.setType("json");
|
||||||
|
credential.setValue(value);
|
||||||
|
|
||||||
|
String result = credentialService.writeCredential(credential);
|
||||||
|
assertThat(result).isEqualTo("Credential:order_config_json written successfully!");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenRotatePassword_thenRegenerateNewPassword() {
|
||||||
|
String orderApiKey = credentialService.rotatePassword("order_api_key");
|
||||||
|
assertThat(orderApiKey).isEqualTo("Credential:order_api_key re-generated successfully!");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenRevokePassword_thenDeletePassword() {
|
||||||
|
String orderApiKey = credentialService.deletePassword("order_api_key");
|
||||||
|
assertThat(orderApiKey).isEqualTo("Credential:order_api_key deleted successfully!");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenRetrieveExistingCredential_thenReturnCredentialValue() {
|
||||||
|
String orderConfigJson = credentialService.getPassword("order_config_json");
|
||||||
|
assertFalse(orderConfigJson.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenCredentialPermissionCreated_thenAddToCredential() {
|
||||||
|
CredentialPermission orderConfig = credentialService.addCredentialPermission("order_config_json");
|
||||||
|
List<Operation> operations = orderConfig.getPermission()
|
||||||
|
.getOperations();
|
||||||
|
String identity = orderConfig.getPermission()
|
||||||
|
.getActor()
|
||||||
|
.getIdentity();
|
||||||
|
|
||||||
|
CredentialPermission newOrderConfig = credentialService.getCredentialPermission("order_config_json");
|
||||||
|
List<Operation> newOperations = newOrderConfig.getPermission()
|
||||||
|
.getOperations();
|
||||||
|
String newIdentity = newOrderConfig.getPermission()
|
||||||
|
.getActor()
|
||||||
|
.getIdentity();
|
||||||
|
|
||||||
|
assertThat(operations.size() == newOperations.size() && operations.containsAll(newOperations) && newOperations.containsAll(operations));
|
||||||
|
assertThat(identity).isEqualTo(newIdentity);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue