-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Certificate API - Certificate backup/restore (#528)
- Implements certificate restore functionality in service - Adds certificate restore input model - Creates base backup and restore controller for certificates - Creates converter for certificate backup - Adds new UT/IT test cases - Adds new E2E test cases Resolves #500 {minor} Signed-off-by: Esta Nagy <[email protected]>
- Loading branch information
Showing
28 changed files
with
1,122 additions
and
59 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
115 changes: 115 additions & 0 deletions
115
...thub/nagyesta/lowkeyvault/controller/common/CommonCertificateBackupRestoreController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
package com.github.nagyesta.lowkeyvault.controller.common; | ||
|
||
import com.github.nagyesta.lowkeyvault.mapper.common.registry.CertificateConverterRegistry; | ||
import com.github.nagyesta.lowkeyvault.mapper.v7_3.certificate.CertificateEntityToV73CertificateItemModelConverter; | ||
import com.github.nagyesta.lowkeyvault.mapper.v7_3.certificate.CertificateEntityToV73CertificateVersionItemModelConverter; | ||
import com.github.nagyesta.lowkeyvault.mapper.v7_3.certificate.CertificateEntityToV73ModelConverter; | ||
import com.github.nagyesta.lowkeyvault.model.common.backup.CertificateBackupList; | ||
import com.github.nagyesta.lowkeyvault.model.common.backup.CertificateBackupListItem; | ||
import com.github.nagyesta.lowkeyvault.model.common.backup.CertificateBackupModel; | ||
import com.github.nagyesta.lowkeyvault.model.v7_3.certificate.*; | ||
import com.github.nagyesta.lowkeyvault.service.certificate.CertificateVaultFake; | ||
import com.github.nagyesta.lowkeyvault.service.certificate.ReadOnlyKeyVaultCertificateEntity; | ||
import com.github.nagyesta.lowkeyvault.service.certificate.id.CertificateEntityId; | ||
import com.github.nagyesta.lowkeyvault.service.certificate.id.VersionedCertificateEntityId; | ||
import com.github.nagyesta.lowkeyvault.service.certificate.impl.CertAuthorityType; | ||
import com.github.nagyesta.lowkeyvault.service.certificate.impl.CertContentType; | ||
import com.github.nagyesta.lowkeyvault.service.certificate.impl.CertificateLifetimeActionPolicy; | ||
import com.github.nagyesta.lowkeyvault.service.certificate.impl.DefaultCertificateLifetimeActionPolicy; | ||
import com.github.nagyesta.lowkeyvault.service.vault.VaultFake; | ||
import com.github.nagyesta.lowkeyvault.service.vault.VaultService; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.lang.NonNull; | ||
|
||
import javax.validation.Valid; | ||
import javax.validation.constraints.Pattern; | ||
import java.net.URI; | ||
import java.util.List; | ||
import java.util.Objects; | ||
import java.util.Optional; | ||
|
||
import static com.github.nagyesta.lowkeyvault.controller.common.util.CertificateRequestMapperUtil.convertActivityMap; | ||
|
||
@Slf4j | ||
public abstract class CommonCertificateBackupRestoreController extends BaseBackupRestoreController<CertificateEntityId, | ||
VersionedCertificateEntityId, ReadOnlyKeyVaultCertificateEntity, KeyVaultCertificateModel, DeletedKeyVaultCertificateModel, | ||
KeyVaultCertificateItemModel, DeletedKeyVaultCertificateItemModel, CertificateEntityToV73ModelConverter, | ||
CertificateEntityToV73CertificateItemModelConverter, CertificateEntityToV73CertificateVersionItemModelConverter, | ||
CertificateVaultFake, CertificatePropertiesModel, CertificateBackupListItem, CertificateBackupList, CertificateBackupModel, | ||
CertificateConverterRegistry> { | ||
|
||
protected CommonCertificateBackupRestoreController( | ||
@NonNull final CertificateConverterRegistry registry, @NonNull final VaultService vaultService) { | ||
super(registry, vaultService, VaultFake::certificateVaultFake); | ||
} | ||
|
||
public ResponseEntity<CertificateBackupModel> backup( | ||
@Valid @Pattern(regexp = NAME_PATTERN) final String certificateName, | ||
final URI baseUri) { | ||
log.info("Received request to {} backup certificate: {} using API version: {}", | ||
baseUri.toString(), certificateName, apiVersion()); | ||
return ResponseEntity.ok(backupEntity(entityId(baseUri, certificateName))); | ||
} | ||
|
||
public ResponseEntity<KeyVaultCertificateModel> restore( | ||
final URI baseUri, @Valid final CertificateBackupModel certificateBackupModel) { | ||
final CertificateBackupList list = certificateBackupModel.getValue(); | ||
log.info("Received request to {} restore certificate: {} using API version: {}", | ||
baseUri.toString(), list.getVersions().get(0).getId(), apiVersion()); | ||
final KeyVaultCertificateModel model = restoreEntity(certificateBackupModel); | ||
final CertificateVaultFake vault = getVaultByUri(baseUri); | ||
final CertificateEntityId entityId = entityId(baseUri, getSingleEntityName(certificateBackupModel)); | ||
model.getPolicy().setLifetimeActions(updateLifetimeActions(vault, entityId, list)); | ||
return ResponseEntity.ok(model); | ||
} | ||
|
||
@Override | ||
protected void restoreVersion(@NonNull final CertificateVaultFake vault, | ||
@NonNull final VersionedCertificateEntityId versionedEntityId, | ||
@NonNull final CertificateBackupListItem entityVersion) { | ||
final CertificatePropertiesModel attributes = Objects | ||
.requireNonNullElse(entityVersion.getAttributes(), new CertificatePropertiesModel()); | ||
vault.restoreCertificateVersion(versionedEntityId, CertificateRestoreInput.builder() | ||
.name(versionedEntityId.id()) | ||
.certificateContent(entityVersion.getCertificateAsString()) | ||
.keyVersion(entityVersion.getKeyVersion()) | ||
.contentType(CertContentType.byMimeType(entityVersion.getPolicy().getSecretProperties().getContentType())) | ||
.password(entityVersion.getPassword()) | ||
.policy(entityVersion.getPolicy()) | ||
.issuancePolicy(entityVersion.getIssuancePolicy()) | ||
.tags(entityVersion.getTags()) | ||
.created(attributes.getCreatedOn()) | ||
.updated(attributes.getUpdatedOn()) | ||
.notBefore(attributes.getNotBefore()) | ||
.expires(attributes.getExpiresOn()) | ||
.enabled(attributes.isEnabled()) | ||
.build()); | ||
} | ||
|
||
@Override | ||
protected CertificateBackupList getBackupList() { | ||
return new CertificateBackupList(); | ||
} | ||
|
||
@Override | ||
protected CertificateBackupModel getBackupModel() { | ||
return new CertificateBackupModel(); | ||
} | ||
|
||
private List<CertificateLifetimeActionModel> updateLifetimeActions( | ||
final CertificateVaultFake vault, final CertificateEntityId entityId, final CertificateBackupList list) { | ||
final VersionedCertificateEntityId latestVersion = vault.getEntities().getLatestVersionOfEntity(entityId); | ||
final CertAuthorityType certAuthorityType = vault.getEntities().getReadOnlyEntity(latestVersion) | ||
.getIssuancePolicy().getCertAuthorityType(); | ||
final CertificateLifetimeActionPolicy lifetimeActionPolicy = Optional.ofNullable(list.getVersions()) | ||
.map(v -> v.get(v.size() - 1)) | ||
.map(CertificateBackupListItem::getPolicy) | ||
.map(CertificatePolicyModel::getLifetimeActions) | ||
.map(actions -> new CertificateLifetimeActionPolicy(entityId, convertActivityMap(actions))) | ||
.orElse(new DefaultCertificateLifetimeActionPolicy(entityId, certAuthorityType)); | ||
vault.setLifetimeActionPolicy(lifetimeActionPolicy); | ||
return registry().lifetimeActionConverters(apiVersion()).convert(vault.lifetimeActionPolicy(entityId)); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
62 changes: 62 additions & 0 deletions
62
...a/com/github/nagyesta/lowkeyvault/controller/v7_3/CertificateBackupRestoreController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
package com.github.nagyesta.lowkeyvault.controller.v7_3; | ||
|
||
import com.github.nagyesta.lowkeyvault.controller.common.CommonCertificateBackupRestoreController; | ||
import com.github.nagyesta.lowkeyvault.mapper.common.registry.CertificateConverterRegistry; | ||
import com.github.nagyesta.lowkeyvault.model.common.ApiConstants; | ||
import com.github.nagyesta.lowkeyvault.model.common.backup.CertificateBackupModel; | ||
import com.github.nagyesta.lowkeyvault.model.v7_3.certificate.KeyVaultCertificateModel; | ||
import com.github.nagyesta.lowkeyvault.service.vault.VaultService; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.context.annotation.DependsOn; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.lang.NonNull; | ||
import org.springframework.stereotype.Component; | ||
import org.springframework.validation.annotation.Validated; | ||
import org.springframework.web.bind.annotation.*; | ||
|
||
import javax.validation.Valid; | ||
import javax.validation.constraints.Pattern; | ||
import java.net.URI; | ||
|
||
import static com.github.nagyesta.lowkeyvault.model.common.ApiConstants.API_VERSION_7_3; | ||
import static com.github.nagyesta.lowkeyvault.model.common.ApiConstants.V_7_3; | ||
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; | ||
|
||
@Slf4j | ||
@RestController | ||
@Validated | ||
@DependsOn("certificateBackupConverter") | ||
@Component("CertificateBackupRestoreControllerV73") | ||
public class CertificateBackupRestoreController extends CommonCertificateBackupRestoreController { | ||
|
||
@Autowired | ||
public CertificateBackupRestoreController( | ||
@NonNull final CertificateConverterRegistry registry, @NonNull final VaultService vaultService) { | ||
super(registry, vaultService); | ||
} | ||
|
||
@Override | ||
@PostMapping(value = "/certificates/{certificateName}/backup", | ||
params = API_VERSION_7_3, | ||
produces = APPLICATION_JSON_VALUE) | ||
public ResponseEntity<CertificateBackupModel> backup(@PathVariable @Valid @Pattern(regexp = NAME_PATTERN) final String certificateName, | ||
@RequestAttribute(name = ApiConstants.REQUEST_BASE_URI) final URI baseUri) { | ||
return super.backup(certificateName, baseUri); | ||
} | ||
|
||
@Override | ||
@PostMapping(value = "/certificates/restore", | ||
params = API_VERSION_7_3, | ||
consumes = APPLICATION_JSON_VALUE, | ||
produces = APPLICATION_JSON_VALUE) | ||
public ResponseEntity<KeyVaultCertificateModel> restore(@RequestAttribute(name = ApiConstants.REQUEST_BASE_URI) final URI baseUri, | ||
@Valid @RequestBody final CertificateBackupModel certificateBackupModel) { | ||
return super.restore(baseUri, certificateBackupModel); | ||
} | ||
|
||
@Override | ||
protected String apiVersion() { | ||
return V_7_3; | ||
} | ||
} |
Oops, something went wrong.