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