mirror of
https://github.com/nsacyber/HIRS.git
synced 2025-04-15 15:06:47 +00:00
v3_issue_811: can search on all pages. currently placing all the cert pages into their own controller class due to the massive size of the main cert page controller class and because the changes i want to implement require it.
This commit is contained in:
parent
aaef31db9d
commit
44860366ad
@ -4,15 +4,13 @@ import hirs.attestationca.persist.entity.userdefined.certificate.PlatformCredent
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
@Repository
|
||||
public interface PlatformCertificateRepository extends JpaRepository<PlatformCredential, UUID>,
|
||||
JpaSpecificationExecutor<PlatformCredential> {
|
||||
public interface PlatformCertificateRepository extends JpaRepository<PlatformCredential, UUID> {
|
||||
|
||||
/**
|
||||
* Query that retrieves a list of platform credentials using the provided archive flag.
|
||||
@ -32,7 +30,6 @@ public interface PlatformCertificateRepository extends JpaRepository<PlatformCre
|
||||
*/
|
||||
Page<PlatformCredential> findByArchiveFlag(boolean archiveFlag, Pageable pageable);
|
||||
|
||||
|
||||
/**
|
||||
* Query that retrieves a list of platform credentials using the provided device id.
|
||||
*
|
||||
|
@ -1,11 +1,20 @@
|
||||
package hirs.attestationca.persist.service;
|
||||
|
||||
import hirs.attestationca.persist.DBServiceException;
|
||||
import hirs.attestationca.persist.entity.manager.CertificateRepository;
|
||||
import hirs.attestationca.persist.entity.manager.ComponentResultRepository;
|
||||
import hirs.attestationca.persist.entity.userdefined.Certificate;
|
||||
import hirs.attestationca.persist.entity.userdefined.certificate.ComponentResult;
|
||||
import hirs.attestationca.persist.entity.userdefined.certificate.PlatformCredential;
|
||||
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.ComponentIdentifier;
|
||||
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.V2.ComponentIdentifierV2;
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.TypedQuery;
|
||||
import jakarta.persistence.criteria.CriteriaBuilder;
|
||||
import jakarta.persistence.criteria.CriteriaQuery;
|
||||
import jakarta.persistence.criteria.Predicate;
|
||||
import jakarta.persistence.criteria.Root;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
@ -13,16 +22,34 @@ import org.springframework.data.domain.PageImpl;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Service layer class that handles the storage and retrieval of all types of certificates.
|
||||
*/
|
||||
@Log4j2
|
||||
@Service
|
||||
public class CertificateService {
|
||||
|
||||
private static final String TRUSTCHAIN = "trust-chain";
|
||||
private static final String PLATFORMCREDENTIAL = "platform-credentials";
|
||||
private static final String IDEVIDCERTIFICATE = "idevid-certificates";
|
||||
private static final String ENDORSEMENTCREDENTIAL = "endorsement-key-credentials";
|
||||
private static final String ISSUEDCERTIFICATES = "issued-certificates";
|
||||
|
||||
private final CertificateRepository certificateRepository;
|
||||
private final ComponentResultRepository componentResultRepository;
|
||||
private final EntityManager entityManager;
|
||||
|
||||
@Autowired
|
||||
public CertificateService(EntityManager entityManager) {
|
||||
public CertificateService(final CertificateRepository certificateRepository,
|
||||
final ComponentResultRepository componentResultRepository,
|
||||
final EntityManager entityManager) {
|
||||
this.certificateRepository = certificateRepository;
|
||||
this.componentResultRepository = componentResultRepository;
|
||||
this.entityManager = entityManager;
|
||||
}
|
||||
|
||||
@ -30,10 +57,10 @@ public class CertificateService {
|
||||
* @param entityClass generic entity class
|
||||
* @param searchableColumns list of the searchable column name
|
||||
* @param searchText text that waas input in the search textbox
|
||||
* @param archiveFlag
|
||||
* @param pageable
|
||||
* @param archiveFlag archive flag
|
||||
* @param pageable pageable
|
||||
* @param <T> generic entity class
|
||||
* @return
|
||||
* @return page full of the generic certificates.
|
||||
*/
|
||||
public <T> Page<T> findBySearchableColumnsAndArchiveFlag(Class<T> entityClass,
|
||||
List<String> searchableColumns,
|
||||
@ -48,7 +75,7 @@ public class CertificateService {
|
||||
|
||||
// Dynamically add search conditions for each field that should be searchable
|
||||
if (!StringUtils.isBlank(searchText)) {
|
||||
// Dynamically loop through columns and create LIKE conditions for each one
|
||||
// Dynamically loop through columns and create LIKE conditions for each searchable column
|
||||
for (String columnName : searchableColumns) {
|
||||
Predicate predicate =
|
||||
criteriaBuilder.like(criteriaBuilder.lower(certificate.get(columnName)),
|
||||
@ -73,4 +100,279 @@ public class CertificateService {
|
||||
List<T> resultList = typedQuery.getResultList();
|
||||
return new PageImpl<>(resultList, pageable, totalRows);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the given certificate in the database.
|
||||
*
|
||||
* @param certificateType String containing the certificate type
|
||||
* @param fileName contain the name of the file of the certificate to
|
||||
* be stored
|
||||
* @param successMessages contains any messages that will be display on the page
|
||||
* @param certificate the certificate to store
|
||||
*/
|
||||
public void storeCertificate(
|
||||
final String certificateType,
|
||||
final String fileName,
|
||||
final List<String> successMessages,
|
||||
final List<String> errorMessages,
|
||||
final Certificate certificate) {
|
||||
|
||||
Certificate existingCertificate;
|
||||
|
||||
// look for an identical certificate in the database
|
||||
try {
|
||||
existingCertificate = getCertificateByHash(
|
||||
certificateType,
|
||||
certificate.getCertificateHash());
|
||||
} catch (DBServiceException dbsEx) {
|
||||
final String failMessage = "Querying for existing certificate failed ("
|
||||
+ fileName + "): ";
|
||||
errorMessages.add(failMessage + dbsEx.getMessage());
|
||||
log.error(failMessage, dbsEx);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// save the new certificate if no match is found
|
||||
if (existingCertificate == null) {
|
||||
if (certificateType.equals(PLATFORMCREDENTIAL)) {
|
||||
PlatformCredential platformCertificate = (PlatformCredential) certificate;
|
||||
if (platformCertificate.isPlatformBase()) {
|
||||
List<PlatformCredential> sharedCertificates = getPlatformCertificateByBoardSN(
|
||||
platformCertificate.getPlatformSerial());
|
||||
for (PlatformCredential pc : sharedCertificates) {
|
||||
if (pc.isPlatformBase()) {
|
||||
final String failMessage = "Storing certificate failed: "
|
||||
+ "platform credential "
|
||||
+ "chain (" + pc.getPlatformSerial()
|
||||
+ ") base already exists in this chain ("
|
||||
+ fileName + ")";
|
||||
errorMessages.add(failMessage);
|
||||
log.error(failMessage);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.certificateRepository.save(certificate);
|
||||
parseAndSaveComponentResults(certificate);
|
||||
|
||||
final String successMsg
|
||||
= String.format("New certificate successfully uploaded (%s): ", fileName);
|
||||
successMessages.add(successMsg);
|
||||
log.info(successMsg);
|
||||
return;
|
||||
}
|
||||
} catch (DBServiceException dbsEx) {
|
||||
final String failMessage = String.format("Storing new certificate failed (%s): ",
|
||||
fileName);
|
||||
errorMessages.add(failMessage + dbsEx.getMessage());
|
||||
log.error(failMessage, dbsEx);
|
||||
return;
|
||||
} catch (IOException ioException) {
|
||||
final String ioExceptionMessage = "Failed to save component results in the database";
|
||||
errorMessages.add(ioExceptionMessage + ioException.getMessage());
|
||||
log.error(ioExceptionMessage, ioException);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// if an identical certificate is archived, update the existing certificate to
|
||||
// unarchive it and change the creation date
|
||||
if (existingCertificate.isArchived()) {
|
||||
existingCertificate.restore();
|
||||
existingCertificate.resetCreateTime();
|
||||
this.certificateRepository.save(existingCertificate);
|
||||
|
||||
List<ComponentResult> componentResults = componentResultRepository
|
||||
.findByBoardSerialNumber(((PlatformCredential) existingCertificate)
|
||||
.getPlatformSerial());
|
||||
for (ComponentResult componentResult : componentResults) {
|
||||
componentResult.restore();
|
||||
componentResult.resetCreateTime();
|
||||
this.componentResultRepository.save(componentResult);
|
||||
}
|
||||
|
||||
final String successMsg = String.format("Pre-existing certificate "
|
||||
+ "found and unarchived (%s): ", fileName);
|
||||
successMessages.add(successMsg);
|
||||
log.info(successMsg);
|
||||
return;
|
||||
}
|
||||
} catch (DBServiceException dbsEx) {
|
||||
final String failMessage = String.format("Found an identical"
|
||||
+ " pre-existing certificate in the "
|
||||
+ "archive, but failed to unarchive it (%s): ", fileName);
|
||||
errorMessages.add(failMessage + dbsEx.getMessage());
|
||||
log.error(failMessage, dbsEx);
|
||||
return;
|
||||
}
|
||||
|
||||
// if an identical certificate is already unarchived, do nothing and show a fail message
|
||||
final String failMessage
|
||||
= String.format("Storing certificate failed: an identical"
|
||||
+ " certificate already exists (%s): ", fileName);
|
||||
errorMessages.add(failMessage);
|
||||
log.error(failMessage);
|
||||
}
|
||||
|
||||
public void deleteCertificate(UUID uuid, String certificateType,
|
||||
final List<String> successMessages,
|
||||
final List<String> errorMessages) {
|
||||
|
||||
Certificate certificate = certificateRepository.getCertificate(uuid);
|
||||
|
||||
if (certificate == null) {
|
||||
// Use the term "record" here to avoid user confusion b/t cert and cred
|
||||
String notFoundMessage = "Unable to locate record with ID: " + uuid;
|
||||
errorMessages.add(notFoundMessage);
|
||||
log.warn(notFoundMessage);
|
||||
} else {
|
||||
if (certificateType.equals(PLATFORMCREDENTIAL)) {
|
||||
PlatformCredential platformCertificate = (PlatformCredential) certificate;
|
||||
if (platformCertificate.isPlatformBase()) {
|
||||
// only do this if the base is being deleted.
|
||||
List<PlatformCredential> sharedCertificates = getPlatformCertificateByBoardSN(
|
||||
platformCertificate.getPlatformSerial());
|
||||
|
||||
for (PlatformCredential pc : sharedCertificates) {
|
||||
if (!pc.isPlatformBase()) {
|
||||
pc.archive("User requested deletion via UI of the base certificate");
|
||||
certificateRepository.save(pc);
|
||||
deleteComponentResults(pc.getPlatformSerial());
|
||||
}
|
||||
}
|
||||
}
|
||||
deleteComponentResults(platformCertificate.getPlatformSerial());
|
||||
}
|
||||
|
||||
certificate.archive("User requested deletion via UI");
|
||||
certificateRepository.save(certificate);
|
||||
|
||||
String deleteCompletedMessage = "Certificate successfully deleted";
|
||||
successMessages.add(deleteCompletedMessage);
|
||||
log.info(deleteCompletedMessage);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the certificate by the hash code of its bytes. Looks for both
|
||||
* archived and unarchived certificates.
|
||||
*
|
||||
* @param certificateType String containing the certificate type
|
||||
* @param certificateHash the hash of the certificate's bytes
|
||||
* @return the certificate or null if none is found
|
||||
*/
|
||||
private Certificate getCertificateByHash(
|
||||
final String certificateType,
|
||||
final int certificateHash) {
|
||||
return switch (certificateType) {
|
||||
case PLATFORMCREDENTIAL -> this.certificateRepository
|
||||
.findByCertificateHash(certificateHash,
|
||||
"PlatformCredential");
|
||||
case ENDORSEMENTCREDENTIAL -> this.certificateRepository
|
||||
.findByCertificateHash(certificateHash,
|
||||
"EndorsementCredential");
|
||||
case TRUSTCHAIN -> this.certificateRepository
|
||||
.findByCertificateHash(certificateHash,
|
||||
"CertificateAuthorityCredential");
|
||||
case IDEVIDCERTIFICATE -> this.certificateRepository
|
||||
.findByCertificateHash(certificateHash,
|
||||
"IDevIDCertificate");
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the certificate by the platform serial number.
|
||||
*
|
||||
* @param serialNumber the platform serial number
|
||||
* @return the certificate or null if none is found
|
||||
*/
|
||||
private List<PlatformCredential> getPlatformCertificateByBoardSN(
|
||||
final String serialNumber) {
|
||||
List<PlatformCredential> associatedCertificates = new ArrayList<>();
|
||||
|
||||
if (serialNumber != null) {
|
||||
associatedCertificates.addAll(this.certificateRepository.byBoardSerialNumber(serialNumber));
|
||||
}
|
||||
|
||||
return associatedCertificates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method that utilizes the components of the provided platform certificate to generate
|
||||
* a collection of component results and subsequently stores these results in the database.
|
||||
*
|
||||
* @param certificate certificate
|
||||
*/
|
||||
private void parseAndSaveComponentResults(final Certificate certificate) throws IOException {
|
||||
PlatformCredential platformCredential;
|
||||
|
||||
if (certificate instanceof PlatformCredential) {
|
||||
platformCredential = (PlatformCredential) certificate;
|
||||
List<ComponentResult> componentResults = componentResultRepository
|
||||
.findByCertificateSerialNumberAndBoardSerialNumber(
|
||||
platformCredential.getSerialNumber().toString(),
|
||||
platformCredential.getPlatformSerial());
|
||||
|
||||
if (componentResults.isEmpty()) {
|
||||
ComponentResult componentResult;
|
||||
|
||||
if (platformCredential.getPlatformConfigurationV1() != null) {
|
||||
|
||||
List<ComponentIdentifier> componentIdentifiers =
|
||||
platformCredential.getComponentIdentifiers();
|
||||
|
||||
for (ComponentIdentifier componentIdentifier : componentIdentifiers) {
|
||||
componentResult = new ComponentResult(platformCredential.getPlatformSerial(),
|
||||
platformCredential.getSerialNumber().toString(),
|
||||
platformCredential.getPlatformChainType(),
|
||||
componentIdentifier);
|
||||
componentResult.setFailedValidation(false);
|
||||
componentResult.setDelta(!platformCredential.isPlatformBase());
|
||||
componentResultRepository.save(componentResult);
|
||||
}
|
||||
} else if (platformCredential.getPlatformConfigurationV2() != null) {
|
||||
|
||||
List<ComponentIdentifierV2> componentIdentifiersV2 =
|
||||
platformCredential.getComponentIdentifiersV2();
|
||||
|
||||
for (ComponentIdentifierV2 componentIdentifierV2 : componentIdentifiersV2) {
|
||||
componentResult = new ComponentResult(platformCredential.getPlatformSerial(),
|
||||
platformCredential.getSerialNumber().toString(),
|
||||
platformCredential.getPlatformChainType(),
|
||||
componentIdentifierV2);
|
||||
componentResult.setFailedValidation(false);
|
||||
componentResult.setDelta(!platformCredential.isPlatformBase());
|
||||
componentResultRepository.save(componentResult);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (ComponentResult componentResult : componentResults) {
|
||||
componentResult.restore();
|
||||
componentResult.resetCreateTime();
|
||||
componentResultRepository.save(componentResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper method that deletes component results based on the provided platform serial number.
|
||||
*
|
||||
* @param platformSerial platform serial number
|
||||
*/
|
||||
private void deleteComponentResults(final String platformSerial) {
|
||||
List<ComponentResult> componentResults = componentResultRepository
|
||||
.findByBoardSerialNumber(platformSerial);
|
||||
|
||||
for (ComponentResult componentResult : componentResults) {
|
||||
componentResult.archive();
|
||||
componentResultRepository.save(componentResult);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -6,19 +6,14 @@ import hirs.attestationca.persist.FilteredRecordsList;
|
||||
import hirs.attestationca.persist.entity.manager.CACredentialRepository;
|
||||
import hirs.attestationca.persist.entity.manager.CertificateRepository;
|
||||
import hirs.attestationca.persist.entity.manager.ComponentResultRepository;
|
||||
import hirs.attestationca.persist.entity.manager.EndorsementCredentialRepository;
|
||||
import hirs.attestationca.persist.entity.manager.IDevIDCertificateRepository;
|
||||
import hirs.attestationca.persist.entity.manager.IssuedCertificateRepository;
|
||||
import hirs.attestationca.persist.entity.manager.PlatformCertificateRepository;
|
||||
import hirs.attestationca.persist.entity.userdefined.Certificate;
|
||||
import hirs.attestationca.persist.entity.userdefined.certificate.CertificateAuthorityCredential;
|
||||
import hirs.attestationca.persist.entity.userdefined.certificate.ComponentResult;
|
||||
import hirs.attestationca.persist.entity.userdefined.certificate.EndorsementCredential;
|
||||
import hirs.attestationca.persist.entity.userdefined.certificate.IDevIDCertificate;
|
||||
import hirs.attestationca.persist.entity.userdefined.certificate.IssuedAttestationCertificate;
|
||||
import hirs.attestationca.persist.entity.userdefined.certificate.PlatformCredential;
|
||||
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.ComponentIdentifier;
|
||||
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.V2.ComponentIdentifierV2;
|
||||
import hirs.attestationca.persist.service.CertificateService;
|
||||
import hirs.attestationca.persist.util.CredentialHelper;
|
||||
import hirs.attestationca.portal.datatables.Column;
|
||||
@ -41,6 +36,7 @@ import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.util.StreamUtils;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
@ -62,7 +58,6 @@ import java.security.cert.X509Certificate;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
@ -84,14 +79,10 @@ public class CertificatePageController extends PageController<NoPageParams> {
|
||||
*/
|
||||
static final String ACA_CERT_DATA = "acaCertData";
|
||||
private static final String TRUSTCHAIN = "trust-chain";
|
||||
private static final String PLATFORMCREDENTIAL = "platform-credentials";
|
||||
private static final String IDEVIDCERTIFICATE = "idevid-certificates";
|
||||
private static final String ENDORSEMENTCREDENTIAL = "endorsement-key-credentials";
|
||||
private static final String ISSUEDCERTIFICATES = "issued-certificates";
|
||||
private final CertificateRepository certificateRepository;
|
||||
private final PlatformCertificateRepository platformCertificateRepository;
|
||||
private final ComponentResultRepository componentResultRepository;
|
||||
private final EndorsementCredentialRepository endorsementCredentialRepository;
|
||||
private final IssuedCertificateRepository issuedCertificateRepository;
|
||||
private final CACredentialRepository caCredentialRepository;
|
||||
private final IDevIDCertificateRepository iDevIDCertificateRepository;
|
||||
@ -101,20 +92,16 @@ public class CertificatePageController extends PageController<NoPageParams> {
|
||||
/**
|
||||
* Constructor providing the Page's display and routing specification.
|
||||
*
|
||||
* @param certificateRepository the general certificate manager
|
||||
* @param platformCertificateRepository the platform credential manager
|
||||
* @param componentResultRepository the component result repo
|
||||
* @param endorsementCredentialRepository the endorsement credential manager
|
||||
* @param issuedCertificateRepository the issued certificate manager
|
||||
* @param caCredentialRepository the ca credential manager
|
||||
* @param iDevIDCertificateRepository the IDevID certificate repository
|
||||
* @param acaCertificate the ACA's X509 certificate
|
||||
* @param certificateRepository the general certificate manager
|
||||
* @param componentResultRepository the component result repo
|
||||
* @param issuedCertificateRepository the issued certificate manager
|
||||
* @param caCredentialRepository the ca credential manager
|
||||
* @param iDevIDCertificateRepository the IDevID certificate repository
|
||||
* @param acaCertificate the ACA's X509 certificate
|
||||
*/
|
||||
@Autowired
|
||||
public CertificatePageController(final CertificateRepository certificateRepository,
|
||||
final PlatformCertificateRepository platformCertificateRepository,
|
||||
final ComponentResultRepository componentResultRepository,
|
||||
final EndorsementCredentialRepository endorsementCredentialRepository,
|
||||
final IssuedCertificateRepository issuedCertificateRepository,
|
||||
final CACredentialRepository caCredentialRepository,
|
||||
final IDevIDCertificateRepository iDevIDCertificateRepository,
|
||||
@ -122,9 +109,7 @@ public class CertificatePageController extends PageController<NoPageParams> {
|
||||
final X509Certificate acaCertificate) {
|
||||
super(Page.TRUST_CHAIN);
|
||||
this.certificateRepository = certificateRepository;
|
||||
this.platformCertificateRepository = platformCertificateRepository;
|
||||
this.componentResultRepository = componentResultRepository;
|
||||
this.endorsementCredentialRepository = endorsementCredentialRepository;
|
||||
this.issuedCertificateRepository = issuedCertificateRepository;
|
||||
this.caCredentialRepository = caCredentialRepository;
|
||||
this.iDevIDCertificateRepository = iDevIDCertificateRepository;
|
||||
@ -149,8 +134,6 @@ public class CertificatePageController extends PageController<NoPageParams> {
|
||||
private static Page getCertificatePage(final String certificateType) {
|
||||
// get page information (default to TRUST_CHAIN)
|
||||
return switch (certificateType) {
|
||||
case PLATFORMCREDENTIAL -> Page.PLATFORM_CREDENTIALS;
|
||||
case ENDORSEMENTCREDENTIAL -> Page.ENDORSEMENT_KEY_CREDENTIALS;
|
||||
case ISSUEDCERTIFICATES -> Page.ISSUED_CERTIFICATES;
|
||||
case IDEVIDCERTIFICATE -> Page.IDEVID_CERTIFICATES;
|
||||
default -> Page.TRUST_CHAIN;
|
||||
@ -165,8 +148,6 @@ public class CertificatePageController extends PageController<NoPageParams> {
|
||||
*/
|
||||
private static Class<? extends Certificate> getCertificateClass(final String certificateType) {
|
||||
return switch (certificateType) {
|
||||
case PLATFORMCREDENTIAL -> PlatformCredential.class;
|
||||
case ENDORSEMENTCREDENTIAL -> EndorsementCredential.class;
|
||||
case ISSUEDCERTIFICATES -> IssuedAttestationCertificate.class;
|
||||
case IDEVIDCERTIFICATE -> IDevIDCertificate.class;
|
||||
case TRUSTCHAIN -> CertificateAuthorityCredential.class;
|
||||
@ -206,15 +187,9 @@ public class CertificatePageController extends PageController<NoPageParams> {
|
||||
HashMap<String, String> data = new HashMap<>();
|
||||
// add page information
|
||||
switch (certificateType) {
|
||||
case PLATFORMCREDENTIAL:
|
||||
mav = getBaseModelAndView(Page.PLATFORM_CREDENTIALS);
|
||||
break;
|
||||
case IDEVIDCERTIFICATE:
|
||||
mav = getBaseModelAndView(Page.IDEVID_CERTIFICATES);
|
||||
break;
|
||||
case ENDORSEMENTCREDENTIAL:
|
||||
mav = getBaseModelAndView(Page.ENDORSEMENT_KEY_CREDENTIALS);
|
||||
break;
|
||||
case ISSUEDCERTIFICATES:
|
||||
mav = getBaseModelAndView(Page.ISSUED_CERTIFICATES);
|
||||
break;
|
||||
@ -241,26 +216,15 @@ public class CertificatePageController extends PageController<NoPageParams> {
|
||||
*/
|
||||
private List<String> findSearchableColumnsNames(List<Column> columns) {
|
||||
|
||||
// grab all the columns that are searchable, then grab all of those columns names and
|
||||
// create a list of those string names
|
||||
// Retrieve all searchable columns and collect their names into a list of strings.
|
||||
return columns.stream().filter(Column::isSearchable).map(Column::getName)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries for the list of Certificates and returns a data table response
|
||||
* with the records.
|
||||
*
|
||||
* @param certificateType String containing the certificate type
|
||||
* @param input the DataTables search/query parameters
|
||||
* @return the data table
|
||||
*/
|
||||
@ResponseBody
|
||||
@RequestMapping(value = "/{certificateType}/list",
|
||||
produces = MediaType.APPLICATION_JSON_VALUE,
|
||||
method = RequestMethod.GET)
|
||||
public DataTableResponse<? extends Certificate> getTableData(
|
||||
@PathVariable("certificateType") final String certificateType,
|
||||
@GetMapping(value = "/trust-chain/list",
|
||||
produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public DataTableResponse<? extends Certificate> getTrustChainTableData(
|
||||
final DataTableInput input) {
|
||||
log.debug("Handling list request: {}", input);
|
||||
|
||||
@ -275,178 +239,132 @@ public class CertificatePageController extends PageController<NoPageParams> {
|
||||
int currentPage = input.getStart() / input.getLength();
|
||||
Pageable pageable = PageRequest.of(currentPage, input.getLength(), Sort.by(orderColumnName));
|
||||
|
||||
// special parsing for platform credential
|
||||
// Add the EndorsementCredential for each PlatformCredential based on the
|
||||
// serial number. (pc.HolderSerialNumber = ec.SerialNumber)
|
||||
switch (certificateType) {
|
||||
case PLATFORMCREDENTIAL -> {
|
||||
FilteredRecordsList<PlatformCredential> records = new FilteredRecordsList<>();
|
||||
FilteredRecordsList<CertificateAuthorityCredential> records = new FilteredRecordsList<>();
|
||||
|
||||
org.springframework.data.domain.Page<PlatformCredential> pagedResult;
|
||||
org.springframework.data.domain.Page<CertificateAuthorityCredential> pagedResult;
|
||||
|
||||
if (StringUtils.isBlank(searchText)) {
|
||||
pagedResult =
|
||||
this.platformCertificateRepository.findByArchiveFlag(false, pageable);
|
||||
} else {
|
||||
pagedResult =
|
||||
this.certificateService.findBySearchableColumnsAndArchiveFlag(
|
||||
PlatformCredential.class,
|
||||
searchableColumns,
|
||||
searchText,
|
||||
false, pageable);
|
||||
}
|
||||
|
||||
if (pagedResult.hasContent()) {
|
||||
records.addAll(pagedResult.getContent());
|
||||
records.setRecordsTotal(pagedResult.getContent().size());
|
||||
} else {
|
||||
records.setRecordsTotal(input.getLength());
|
||||
}
|
||||
|
||||
records.setRecordsFiltered(platformCertificateRepository.findByArchiveFlag(false).size());
|
||||
EndorsementCredential associatedEC;
|
||||
|
||||
if (!records.isEmpty()) {
|
||||
// loop all the platform certificates
|
||||
for (PlatformCredential pc : records) {
|
||||
// find the EC using the PC's "holder serial number"
|
||||
associatedEC = this.endorsementCredentialRepository
|
||||
.findBySerialNumber(pc.getHolderSerialNumber());
|
||||
|
||||
if (associatedEC != null) {
|
||||
log.debug("EC ID for holder s/n {} = {}", pc
|
||||
.getHolderSerialNumber(), associatedEC.getId());
|
||||
}
|
||||
|
||||
pc.setEndorsementCredential(associatedEC);
|
||||
}
|
||||
}
|
||||
|
||||
log.debug("Returning the size of the list of platform credentials: {}", records.size());
|
||||
return new DataTableResponse<>(records, input);
|
||||
}
|
||||
case ENDORSEMENTCREDENTIAL -> {
|
||||
FilteredRecordsList<EndorsementCredential> records = new FilteredRecordsList<>();
|
||||
|
||||
org.springframework.data.domain.Page<EndorsementCredential> pagedResult;
|
||||
|
||||
if (StringUtils.isBlank(searchText)) {
|
||||
pagedResult = this.endorsementCredentialRepository.findByArchiveFlag(false, pageable);
|
||||
} else {
|
||||
pagedResult =
|
||||
this.certificateService.findBySearchableColumnsAndArchiveFlag(
|
||||
EndorsementCredential.class,
|
||||
searchableColumns,
|
||||
searchText,
|
||||
false, pageable);
|
||||
}
|
||||
|
||||
if (pagedResult.hasContent()) {
|
||||
records.addAll(pagedResult.getContent());
|
||||
records.setRecordsTotal(pagedResult.getContent().size());
|
||||
} else {
|
||||
records.setRecordsTotal(input.getLength());
|
||||
}
|
||||
|
||||
records.setRecordsFiltered(endorsementCredentialRepository.findByArchiveFlag(false).size());
|
||||
|
||||
log.debug("Returning the size of the list of endorsement credentials: {}", records.size());
|
||||
return new DataTableResponse<>(records, input);
|
||||
}
|
||||
case TRUSTCHAIN -> {
|
||||
FilteredRecordsList<CertificateAuthorityCredential> records = new FilteredRecordsList<>();
|
||||
|
||||
org.springframework.data.domain.Page<CertificateAuthorityCredential> pagedResult;
|
||||
|
||||
if (StringUtils.isBlank(searchText)) {
|
||||
pagedResult =
|
||||
this.caCredentialRepository.findByArchiveFlag(false, pageable);
|
||||
} else {
|
||||
pagedResult =
|
||||
this.certificateService.findBySearchableColumnsAndArchiveFlag(
|
||||
CertificateAuthorityCredential.class,
|
||||
searchableColumns,
|
||||
searchText,
|
||||
false, pageable);
|
||||
}
|
||||
|
||||
|
||||
if (pagedResult.hasContent()) {
|
||||
records.addAll(pagedResult.getContent());
|
||||
records.setRecordsTotal(pagedResult.getContent().size());
|
||||
} else {
|
||||
records.setRecordsTotal(input.getLength());
|
||||
}
|
||||
|
||||
records.setRecordsFiltered(caCredentialRepository.findByArchiveFlag(false).size());
|
||||
|
||||
log.debug("Returning the size of the list of trust chain certificates: {}", records.size());
|
||||
return new DataTableResponse<>(records, input);
|
||||
}
|
||||
case ISSUEDCERTIFICATES -> {
|
||||
FilteredRecordsList<IssuedAttestationCertificate> records = new FilteredRecordsList<>();
|
||||
org.springframework.data.domain.Page<IssuedAttestationCertificate> pagedResult;
|
||||
|
||||
if (StringUtils.isBlank(searchText)) {
|
||||
pagedResult =
|
||||
this.issuedCertificateRepository.findByArchiveFlag(false, pageable);
|
||||
} else {
|
||||
pagedResult =
|
||||
this.certificateService.findBySearchableColumnsAndArchiveFlag(
|
||||
IssuedAttestationCertificate.class,
|
||||
searchableColumns,
|
||||
searchText,
|
||||
false, pageable);
|
||||
}
|
||||
|
||||
if (pagedResult.hasContent()) {
|
||||
records.addAll(pagedResult.getContent());
|
||||
records.setRecordsTotal(pagedResult.getContent().size());
|
||||
} else {
|
||||
records.setRecordsTotal(input.getLength());
|
||||
}
|
||||
|
||||
records.setRecordsFiltered(issuedCertificateRepository.findByArchiveFlag(false).size());
|
||||
|
||||
log.debug("Returning the size of the list of issued certificates: {}", records.size());
|
||||
return new DataTableResponse<>(records, input);
|
||||
}
|
||||
case IDEVIDCERTIFICATE -> {
|
||||
FilteredRecordsList<IDevIDCertificate> records = new FilteredRecordsList<>();
|
||||
org.springframework.data.domain.Page<IDevIDCertificate> pagedResult;
|
||||
|
||||
if (StringUtils.isBlank(searchText)) {
|
||||
pagedResult =
|
||||
this.iDevIDCertificateRepository.findByArchiveFlag(false, pageable);
|
||||
} else {
|
||||
pagedResult =
|
||||
this.certificateService.findBySearchableColumnsAndArchiveFlag(
|
||||
IDevIDCertificate.class,
|
||||
searchableColumns,
|
||||
searchText,
|
||||
false, pageable);
|
||||
}
|
||||
|
||||
if (pagedResult.hasContent()) {
|
||||
records.addAll(pagedResult.getContent());
|
||||
records.setRecordsTotal(pagedResult.getContent().size());
|
||||
} else {
|
||||
records.setRecordsTotal(input.getLength());
|
||||
}
|
||||
|
||||
records.setRecordsFiltered(iDevIDCertificateRepository.findByArchiveFlag(false).size());
|
||||
|
||||
log.debug("Returning the size of the list of IDEVID certificates: {}", records.size());
|
||||
return new DataTableResponse<>(records, input);
|
||||
}
|
||||
default -> {
|
||||
log.error("Cannot provide the size of the records because the"
|
||||
+ "provided certificate type does not exist.");
|
||||
return new DataTableResponse<>(new FilteredRecordsList<>(), input);
|
||||
}
|
||||
if (StringUtils.isBlank(searchText)) {
|
||||
pagedResult =
|
||||
this.caCredentialRepository.findByArchiveFlag(false, pageable);
|
||||
} else {
|
||||
pagedResult =
|
||||
this.certificateService.findBySearchableColumnsAndArchiveFlag(
|
||||
CertificateAuthorityCredential.class,
|
||||
searchableColumns,
|
||||
searchText,
|
||||
false, pageable);
|
||||
}
|
||||
|
||||
|
||||
if (pagedResult.hasContent()) {
|
||||
records.addAll(pagedResult.getContent());
|
||||
records.setRecordsTotal(pagedResult.getContent().size());
|
||||
} else {
|
||||
records.setRecordsTotal(input.getLength());
|
||||
}
|
||||
|
||||
records.setRecordsFiltered(caCredentialRepository.findByArchiveFlag(false).size());
|
||||
|
||||
log.debug("Returning the size of the list of trust chain certificates: {}", records.size());
|
||||
return new DataTableResponse<>(records, input);
|
||||
}
|
||||
|
||||
|
||||
@ResponseBody
|
||||
@GetMapping(value = "/idevid-certificates/list",
|
||||
produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public DataTableResponse<? extends Certificate> getIDevIdCertificatesTableData(
|
||||
final DataTableInput input) {
|
||||
|
||||
log.debug("Handling list request: {}", input);
|
||||
|
||||
// attempt to get the column property based on the order index.
|
||||
String orderColumnName = input.getOrderColumnName();
|
||||
|
||||
log.debug("Ordering on column: {}", orderColumnName);
|
||||
|
||||
String searchText = input.getSearch().getValue();
|
||||
List<String> searchableColumns = findSearchableColumnsNames(input.getColumns());
|
||||
|
||||
int currentPage = input.getStart() / input.getLength();
|
||||
Pageable pageable = PageRequest.of(currentPage, input.getLength(), Sort.by(orderColumnName));
|
||||
|
||||
FilteredRecordsList<IDevIDCertificate> records = new FilteredRecordsList<>();
|
||||
org.springframework.data.domain.Page<IDevIDCertificate> pagedResult;
|
||||
|
||||
if (StringUtils.isBlank(searchText)) {
|
||||
pagedResult =
|
||||
this.iDevIDCertificateRepository.findByArchiveFlag(false, pageable);
|
||||
} else {
|
||||
pagedResult =
|
||||
this.certificateService.findBySearchableColumnsAndArchiveFlag(
|
||||
IDevIDCertificate.class,
|
||||
searchableColumns,
|
||||
searchText,
|
||||
false, pageable);
|
||||
}
|
||||
|
||||
if (pagedResult.hasContent()) {
|
||||
records.addAll(pagedResult.getContent());
|
||||
records.setRecordsTotal(pagedResult.getContent().size());
|
||||
} else {
|
||||
records.setRecordsTotal(input.getLength());
|
||||
}
|
||||
|
||||
records.setRecordsFiltered(iDevIDCertificateRepository.findByArchiveFlag(false).size());
|
||||
|
||||
log.debug("Returning the size of the list of IDEVID certificates: {}", records.size());
|
||||
return new DataTableResponse<>(records, input);
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@GetMapping(value = "/issued-certificates/list",
|
||||
produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public DataTableResponse<? extends Certificate> getIssuedCertificatesTableData(
|
||||
final DataTableInput input) {
|
||||
log.debug("Handling list request: {}", input);
|
||||
|
||||
// attempt to get the column property based on the order index.
|
||||
String orderColumnName = input.getOrderColumnName();
|
||||
|
||||
log.debug("Ordering on column: {}", orderColumnName);
|
||||
|
||||
String searchText = input.getSearch().getValue();
|
||||
List<String> searchableColumns = findSearchableColumnsNames(input.getColumns());
|
||||
|
||||
int currentPage = input.getStart() / input.getLength();
|
||||
Pageable pageable = PageRequest.of(currentPage, input.getLength(), Sort.by(orderColumnName));
|
||||
|
||||
FilteredRecordsList<IssuedAttestationCertificate> records = new FilteredRecordsList<>();
|
||||
org.springframework.data.domain.Page<IssuedAttestationCertificate> pagedResult;
|
||||
|
||||
if (StringUtils.isBlank(searchText)) {
|
||||
pagedResult =
|
||||
this.issuedCertificateRepository.findByArchiveFlag(false, pageable);
|
||||
} else {
|
||||
pagedResult =
|
||||
this.certificateService.findBySearchableColumnsAndArchiveFlag(
|
||||
IssuedAttestationCertificate.class,
|
||||
searchableColumns,
|
||||
searchText,
|
||||
false, pageable);
|
||||
}
|
||||
|
||||
if (pagedResult.hasContent()) {
|
||||
records.addAll(pagedResult.getContent());
|
||||
records.setRecordsTotal(pagedResult.getContent().size());
|
||||
} else {
|
||||
records.setRecordsTotal(input.getLength());
|
||||
}
|
||||
|
||||
records.setRecordsFiltered(issuedCertificateRepository.findByArchiveFlag(false).size());
|
||||
|
||||
log.debug("Returning the size of the list of issued certificates: {}", records.size());
|
||||
return new DataTableResponse<>(records, input);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Upload and processes a credential.
|
||||
*
|
||||
@ -631,7 +549,7 @@ public class CertificatePageController extends PageController<NoPageParams> {
|
||||
* file name)
|
||||
* @throws IOException when writing to response output stream
|
||||
*/
|
||||
@RequestMapping(value = "/trust-chain/bulk", method = RequestMethod.GET)
|
||||
@RequestMapping(value = "/trust-chain/bulk-download", method = RequestMethod.GET)
|
||||
public void caBulkDownload(final HttpServletResponse response)
|
||||
throws IOException {
|
||||
log.info("Handling request to download all trust chain certificates");
|
||||
@ -655,37 +573,6 @@ public class CertificatePageController extends PageController<NoPageParams> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles request to download the certs by writing it to the response stream
|
||||
* for download in bulk.
|
||||
*
|
||||
* @param response the response object (needed to update the header with the
|
||||
* file name)
|
||||
* @throws IOException when writing to response output stream
|
||||
*/
|
||||
@RequestMapping(value = "/platform-credentials/bulk", method = RequestMethod.GET)
|
||||
public void pcBulkDownload(final HttpServletResponse response)
|
||||
throws IOException {
|
||||
log.info("Handling request to download all platform certificates");
|
||||
String fileName = "platform_certificates.zip";
|
||||
final String singleFileName = "Platform_Certificate";
|
||||
String zipFileName;
|
||||
|
||||
// Set filename for download.
|
||||
response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
|
||||
response.setContentType("application/zip");
|
||||
|
||||
try (ZipOutputStream zipOut = new ZipOutputStream(response.getOutputStream())) {
|
||||
// get all files
|
||||
bulkDownload(zipOut, this.certificateRepository.findByType("PlatformCredential"), singleFileName);
|
||||
// write cert to output stream
|
||||
} catch (IllegalArgumentException ex) {
|
||||
String uuidError = "Failed to parse ID from: ";
|
||||
log.error(uuidError, ex);
|
||||
// send a 404 error when invalid certificate
|
||||
response.sendError(HttpServletResponse.SC_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles request to download the certs by writing it to the response stream
|
||||
@ -695,7 +582,7 @@ public class CertificatePageController extends PageController<NoPageParams> {
|
||||
* file name)
|
||||
* @throws IOException when writing to response output stream
|
||||
*/
|
||||
@RequestMapping(value = "/issued-certificates/bulk", method = RequestMethod.GET)
|
||||
@RequestMapping(value = "/issued-certificates/bulk-download", method = RequestMethod.GET)
|
||||
public void icBulkDownload(final HttpServletResponse response)
|
||||
throws IOException {
|
||||
log.info("Handling request to download all issued certificates");
|
||||
@ -720,38 +607,6 @@ public class CertificatePageController extends PageController<NoPageParams> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles request to download the certs by writing it to the response stream
|
||||
* for download in bulk.
|
||||
*
|
||||
* @param response the response object (needed to update the header with the
|
||||
* file name)
|
||||
* @throws IOException when writing to response output stream
|
||||
*/
|
||||
@RequestMapping(value = "/endorsement-key-credentials/bulk", method = RequestMethod.GET)
|
||||
public void ekBulkDownload(final HttpServletResponse response)
|
||||
throws IOException {
|
||||
log.info("Handling request to download all endorsement certificates");
|
||||
String fileName = "endorsement_certificates.zip";
|
||||
final String singleFileName = "Endorsement_Certificates";
|
||||
|
||||
// Set filename for download.
|
||||
response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
|
||||
response.setContentType("application/zip");
|
||||
|
||||
try (ZipOutputStream zipOut = new ZipOutputStream(response.getOutputStream())) {
|
||||
// get all files
|
||||
bulkDownload(zipOut, this.certificateRepository.findByType("EndorsementCredential"),
|
||||
singleFileName);
|
||||
// write cert to output stream
|
||||
} catch (IllegalArgumentException ex) {
|
||||
String uuidError = "Failed to parse ID from: ";
|
||||
log.error(uuidError, ex);
|
||||
// send a 404 error when invalid certificate
|
||||
response.sendError(HttpServletResponse.SC_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method that packages a collection of certificates into a zip file.
|
||||
*
|
||||
@ -809,12 +664,6 @@ public class CertificatePageController extends PageController<NoPageParams> {
|
||||
final int certificateHash) {
|
||||
|
||||
return switch (certificateType) {
|
||||
case PLATFORMCREDENTIAL -> this.certificateRepository
|
||||
.findByCertificateHash(certificateHash,
|
||||
"PlatformCredential");
|
||||
case ENDORSEMENTCREDENTIAL -> this.certificateRepository
|
||||
.findByCertificateHash(certificateHash,
|
||||
"EndorsementCredential");
|
||||
case TRUSTCHAIN -> this.certificateRepository
|
||||
.findByCertificateHash(certificateHash,
|
||||
"CertificateAuthorityCredential");
|
||||
@ -825,28 +674,6 @@ public class CertificatePageController extends PageController<NoPageParams> {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the certificate by the platform serial number.
|
||||
*
|
||||
* @param certificateType String containing the certificate type
|
||||
* @param serialNumber the platform serial number
|
||||
* @return the certificate or null if none is found
|
||||
*/
|
||||
private List<PlatformCredential> getCertificateByBoardSN(
|
||||
final String certificateType,
|
||||
final String serialNumber) {
|
||||
List<PlatformCredential> associatedCertificates = new LinkedList<>();
|
||||
|
||||
if (serialNumber != null) {
|
||||
if (certificateType.equals(PLATFORMCREDENTIAL)) {
|
||||
associatedCertificates.addAll(this.certificateRepository
|
||||
.byBoardSerialNumber(serialNumber));
|
||||
}
|
||||
}
|
||||
|
||||
return associatedCertificates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an uploaded file into a certificate and populates the given model
|
||||
* with error messages if parsing fails.
|
||||
@ -877,10 +704,6 @@ public class CertificatePageController extends PageController<NoPageParams> {
|
||||
}
|
||||
try {
|
||||
switch (certificateType) {
|
||||
case PLATFORMCREDENTIAL:
|
||||
return new PlatformCredential(fileBytes);
|
||||
case ENDORSEMENTCREDENTIAL:
|
||||
return new EndorsementCredential(fileBytes);
|
||||
case IDEVIDCERTIFICATE:
|
||||
return new IDevIDCertificate(fileBytes);
|
||||
case TRUSTCHAIN:
|
||||
@ -1071,77 +894,4 @@ public class CertificatePageController extends PageController<NoPageParams> {
|
||||
messages.addError(failMessage);
|
||||
log.error(failMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method that utilizes the components of the provided platform certificate to generate
|
||||
* a collection of component results and subsequently stores these results in the database.
|
||||
*
|
||||
* @param certificate certificate
|
||||
*/
|
||||
private void parseAndSaveComponentResults(final Certificate certificate) throws IOException {
|
||||
PlatformCredential platformCredential;
|
||||
|
||||
if (certificate instanceof PlatformCredential) {
|
||||
platformCredential = (PlatformCredential) certificate;
|
||||
List<ComponentResult> componentResults = componentResultRepository
|
||||
.findByCertificateSerialNumberAndBoardSerialNumber(
|
||||
platformCredential.getSerialNumber().toString(),
|
||||
platformCredential.getPlatformSerial());
|
||||
|
||||
if (componentResults.isEmpty()) {
|
||||
ComponentResult componentResult;
|
||||
|
||||
if (platformCredential.getPlatformConfigurationV1() != null) {
|
||||
|
||||
List<ComponentIdentifier> componentIdentifiers =
|
||||
platformCredential.getComponentIdentifiers();
|
||||
|
||||
for (ComponentIdentifier componentIdentifier : componentIdentifiers) {
|
||||
componentResult = new ComponentResult(platformCredential.getPlatformSerial(),
|
||||
platformCredential.getSerialNumber().toString(),
|
||||
platformCredential.getPlatformChainType(),
|
||||
componentIdentifier);
|
||||
componentResult.setFailedValidation(false);
|
||||
componentResult.setDelta(!platformCredential.isPlatformBase());
|
||||
componentResultRepository.save(componentResult);
|
||||
}
|
||||
} else if (platformCredential.getPlatformConfigurationV2() != null) {
|
||||
|
||||
List<ComponentIdentifierV2> componentIdentifiersV2 =
|
||||
platformCredential.getComponentIdentifiersV2();
|
||||
|
||||
for (ComponentIdentifierV2 componentIdentifierV2 : componentIdentifiersV2) {
|
||||
componentResult = new ComponentResult(platformCredential.getPlatformSerial(),
|
||||
platformCredential.getSerialNumber().toString(),
|
||||
platformCredential.getPlatformChainType(),
|
||||
componentIdentifierV2);
|
||||
componentResult.setFailedValidation(false);
|
||||
componentResult.setDelta(!platformCredential.isPlatformBase());
|
||||
componentResultRepository.save(componentResult);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (ComponentResult componentResult : componentResults) {
|
||||
componentResult.restore();
|
||||
componentResult.resetCreateTime();
|
||||
componentResultRepository.save(componentResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method that deletes component results based on the provided platform serial number.
|
||||
*
|
||||
* @param platformSerial platform serial number
|
||||
*/
|
||||
private void deleteComponentResults(final String platformSerial) {
|
||||
List<ComponentResult> componentResults = componentResultRepository
|
||||
.findByBoardSerialNumber(platformSerial);
|
||||
|
||||
for (ComponentResult componentResult : componentResults) {
|
||||
componentResult.archive();
|
||||
componentResultRepository.save(componentResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,397 @@
|
||||
package hirs.attestationca.portal.page.controllers;
|
||||
|
||||
import hirs.attestationca.persist.DBManagerException;
|
||||
import hirs.attestationca.persist.FilteredRecordsList;
|
||||
import hirs.attestationca.persist.entity.manager.CertificateRepository;
|
||||
import hirs.attestationca.persist.entity.manager.EndorsementCredentialRepository;
|
||||
import hirs.attestationca.persist.entity.userdefined.Certificate;
|
||||
import hirs.attestationca.persist.entity.userdefined.certificate.EndorsementCredential;
|
||||
import hirs.attestationca.persist.service.CertificateService;
|
||||
import hirs.attestationca.portal.datatables.Column;
|
||||
import hirs.attestationca.portal.datatables.DataTableInput;
|
||||
import hirs.attestationca.portal.datatables.DataTableResponse;
|
||||
import hirs.attestationca.portal.page.Page;
|
||||
import hirs.attestationca.portal.page.PageController;
|
||||
import hirs.attestationca.portal.page.PageMessages;
|
||||
import hirs.attestationca.portal.page.params.NoPageParams;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.bouncycastle.util.encoders.DecoderException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.util.StreamUtils;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
|
||||
import org.springframework.web.servlet.view.RedirectView;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
@Log4j2
|
||||
@Controller
|
||||
@RequestMapping("/HIRS_AttestationCAPortal/portal/certificate-request/endorsement-key-credentials")
|
||||
public class EndorsementCredentialPageController extends PageController<NoPageParams> {
|
||||
|
||||
private static final String ENDORSEMENTCREDENTIAL = "endorsement-key-credentials";
|
||||
|
||||
private final CertificateRepository certificateRepository;
|
||||
private final EndorsementCredentialRepository endorsementCredentialRepository;
|
||||
private final CertificateService certificateService;
|
||||
|
||||
@Autowired
|
||||
public EndorsementCredentialPageController(
|
||||
final CertificateRepository certificateRepository,
|
||||
final EndorsementCredentialRepository endorsementCredentialRepository,
|
||||
final CertificateService certificateService) {
|
||||
super(Page.TRUST_CHAIN);
|
||||
this.certificateRepository = certificateRepository;
|
||||
this.endorsementCredentialRepository = endorsementCredentialRepository;
|
||||
this.certificateService = certificateService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the path for the view and the data model for the page.
|
||||
*
|
||||
* @param params The object to map url parameters into.
|
||||
* @param model The data model for the request. Can contain data from
|
||||
* redirect.
|
||||
* @return the path for the view and data model for the page.
|
||||
*/
|
||||
@RequestMapping
|
||||
public ModelAndView initPage(
|
||||
final NoPageParams params, final Model model) {
|
||||
return getBaseModelAndView(Page.ENDORSEMENT_KEY_CREDENTIALS);
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@GetMapping(value = "/list",
|
||||
produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public DataTableResponse<EndorsementCredential> getEndorsementCredentialsTableData(
|
||||
final DataTableInput input) {
|
||||
|
||||
log.debug("Handling list request: {}", input);
|
||||
|
||||
// attempt to get the column property based on the order index.
|
||||
String orderColumnName = input.getOrderColumnName();
|
||||
|
||||
log.debug("Ordering on column: {}", orderColumnName);
|
||||
|
||||
String searchText = input.getSearch().getValue();
|
||||
List<String> searchableColumns = findSearchableColumnsNames(input.getColumns());
|
||||
|
||||
int currentPage = input.getStart() / input.getLength();
|
||||
Pageable pageable = PageRequest.of(currentPage, input.getLength(), Sort.by(orderColumnName));
|
||||
|
||||
FilteredRecordsList<EndorsementCredential> records = new FilteredRecordsList<>();
|
||||
|
||||
org.springframework.data.domain.Page<EndorsementCredential> pagedResult;
|
||||
|
||||
if (StringUtils.isBlank(searchText)) {
|
||||
pagedResult = this.endorsementCredentialRepository.findByArchiveFlag(false, pageable);
|
||||
} else {
|
||||
pagedResult =
|
||||
this.certificateService.findBySearchableColumnsAndArchiveFlag(
|
||||
EndorsementCredential.class,
|
||||
searchableColumns,
|
||||
searchText,
|
||||
false, pageable);
|
||||
}
|
||||
|
||||
if (pagedResult.hasContent()) {
|
||||
records.addAll(pagedResult.getContent());
|
||||
records.setRecordsTotal(pagedResult.getContent().size());
|
||||
} else {
|
||||
records.setRecordsTotal(input.getLength());
|
||||
}
|
||||
|
||||
records.setRecordsFiltered(endorsementCredentialRepository.findByArchiveFlag(false).size());
|
||||
|
||||
log.debug("Returning the size of the list of endorsement credentials: {}", records.size());
|
||||
return new DataTableResponse<>(records, input);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles request to download the cert by writing it to the response stream
|
||||
* for download.
|
||||
*
|
||||
* @param id the UUID of the cert to download
|
||||
* @param response the response object (needed to update the header with the
|
||||
* file name)
|
||||
* @throws IOException when writing to response output stream
|
||||
*/
|
||||
@GetMapping("/download")
|
||||
public void ekSingleDownload(
|
||||
@RequestParam final String id,
|
||||
final HttpServletResponse response)
|
||||
throws IOException {
|
||||
log.info("Handling request to download endorsement credential id {}", id);
|
||||
|
||||
try {
|
||||
UUID uuid = UUID.fromString(id);
|
||||
Certificate certificate = certificateRepository.getCertificate(uuid);
|
||||
|
||||
if (certificate == null) {
|
||||
// Use the term "record" here to avoid user confusion b/t cert and cred
|
||||
String notFoundMessage = "Unable to locate record with ID: " + uuid;
|
||||
log.warn(notFoundMessage);
|
||||
// send a 404 error when invalid certificate
|
||||
response.sendError(HttpServletResponse.SC_NOT_FOUND);
|
||||
} else {
|
||||
if (certificate instanceof EndorsementCredential uploadedEndorsementCredential) {
|
||||
String fileName = "filename=\"" + EndorsementCredential.class.getSimpleName()
|
||||
+ "_"
|
||||
+ uploadedEndorsementCredential.getSerialNumber()
|
||||
+ ".cer\"";
|
||||
|
||||
// Set filename for download.
|
||||
response.setHeader("Content-Disposition", "attachment;" + fileName);
|
||||
response.setContentType("application/octet-stream");
|
||||
|
||||
// write cert to output stream
|
||||
response.getOutputStream().write(certificate.getRawBytes());
|
||||
}
|
||||
}
|
||||
} catch (IllegalArgumentException ex) {
|
||||
String uuidError = "Failed to parse ID from: " + id;
|
||||
log.error(uuidError, ex);
|
||||
// send a 404 error when invalid certificate
|
||||
response.sendError(HttpServletResponse.SC_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles request to download the certs by writing it to the response stream
|
||||
* for download in bulk.
|
||||
*
|
||||
* @param response the response object (needed to update the header with the
|
||||
* file name)
|
||||
* @throws IOException when writing to response output stream
|
||||
*/
|
||||
@GetMapping("/bulk-download")
|
||||
public void ekBulkDownload(final HttpServletResponse response)
|
||||
throws IOException {
|
||||
log.info("Handling request to download all endorsement certificates");
|
||||
|
||||
final String fileName = "endorsement_certificates.zip";
|
||||
|
||||
// Set filename for download.
|
||||
response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
|
||||
response.setContentType("application/zip");
|
||||
|
||||
try (ZipOutputStream zipOut = new ZipOutputStream(response.getOutputStream())) {
|
||||
|
||||
// find all the uploaded endorsement certificates
|
||||
List<Certificate> certificates = this.certificateRepository.findByType("EndorsementCredential");
|
||||
|
||||
// convert the list of certificates to a list of endorsement certificates
|
||||
List<EndorsementCredential> uploadedEKs = certificates.stream()
|
||||
.filter(eachPC -> eachPC instanceof EndorsementCredential)
|
||||
.map(eachPC -> (EndorsementCredential) eachPC).toList();
|
||||
|
||||
// get all files
|
||||
bulkDownload(zipOut, uploadedEKs);
|
||||
// write cert to output stream
|
||||
} catch (IllegalArgumentException ex) {
|
||||
String uuidError = "Failed to parse ID from: ";
|
||||
log.error(uuidError, ex);
|
||||
// send a 404 error when invalid certificate
|
||||
response.sendError(HttpServletResponse.SC_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload and processes a credential.
|
||||
*
|
||||
* @param files the files to process
|
||||
* @param attr the redirection attributes
|
||||
* @return the redirection view
|
||||
* @throws URISyntaxException if malformed URI
|
||||
*/
|
||||
@PostMapping("/upload")
|
||||
protected RedirectView upload(
|
||||
@RequestParam("file") final MultipartFile[] files,
|
||||
final RedirectAttributes attr) throws URISyntaxException {
|
||||
|
||||
log.info("Handling request to upload one or more endorsement certificates");
|
||||
|
||||
Map<String, Object> model = new HashMap<>();
|
||||
PageMessages messages = new PageMessages();
|
||||
|
||||
List<String> errorMessages = new ArrayList<>();
|
||||
List<String> successMessages = new ArrayList<>();
|
||||
|
||||
for (MultipartFile file : files) {
|
||||
//Parse certificate
|
||||
EndorsementCredential parseEndorsementCredential = parseEndorsementCredential(file, messages);
|
||||
|
||||
//Store only if it was parsed
|
||||
if (parseEndorsementCredential != null) {
|
||||
certificateService.storeCertificate(
|
||||
ENDORSEMENTCREDENTIAL,
|
||||
file.getOriginalFilename(),
|
||||
successMessages, errorMessages, parseEndorsementCredential);
|
||||
}
|
||||
}
|
||||
|
||||
//Add messages to the model
|
||||
model.put(MESSAGES_ATTRIBUTE, messages);
|
||||
|
||||
return redirectTo(Page.ENDORSEMENT_KEY_CREDENTIALS, new NoPageParams(), model, attr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Archives (soft delete) the credential.
|
||||
*
|
||||
* @param id the UUID of the cert to delete
|
||||
* @param attr RedirectAttributes used to forward data back to the original
|
||||
* page.
|
||||
* @return redirect to this page
|
||||
* @throws URISyntaxException if malformed URI
|
||||
*/
|
||||
@PostMapping("/delete")
|
||||
public RedirectView delete(
|
||||
@RequestParam final String id,
|
||||
final RedirectAttributes attr) throws URISyntaxException {
|
||||
log.info("Handling request to delete endorsement certificate id {}", id);
|
||||
|
||||
Map<String, Object> model = new HashMap<>();
|
||||
PageMessages messages = new PageMessages();
|
||||
|
||||
try {
|
||||
List<String> successMessages = new ArrayList<>();
|
||||
List<String> errorMessages = new ArrayList<>();
|
||||
|
||||
UUID uuid = UUID.fromString(id);
|
||||
|
||||
this.certificateService.deleteCertificate(uuid, ENDORSEMENTCREDENTIAL,
|
||||
successMessages, errorMessages);
|
||||
|
||||
} catch (IllegalArgumentException ex) {
|
||||
String uuidError = "Failed to parse ID from: " + id;
|
||||
messages.addError(uuidError);
|
||||
log.error(uuidError, ex);
|
||||
} catch (DBManagerException ex) {
|
||||
String dbError = "Failed to archive cert: " + id;
|
||||
messages.addError(dbError);
|
||||
log.error(dbError, ex);
|
||||
}
|
||||
|
||||
model.put(MESSAGES_ATTRIBUTE, messages);
|
||||
return redirectTo(Page.ENDORSEMENT_KEY_CREDENTIALS, new NoPageParams(), model, attr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method that returns a list of column names that are searchable.
|
||||
*
|
||||
* @return searchable column names
|
||||
*/
|
||||
private List<String> findSearchableColumnsNames(List<Column> columns) {
|
||||
|
||||
// Retrieve all searchable columns and collect their names into a list of strings.
|
||||
return columns.stream().filter(Column::isSearchable).map(Column::getName)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Attempts to parse the provided file in order to create an Endorsement Credential.
|
||||
*
|
||||
* @param file file
|
||||
* @param messages page messages
|
||||
* @return endorsement credential
|
||||
*/
|
||||
private EndorsementCredential parseEndorsementCredential(MultipartFile file, PageMessages messages) {
|
||||
log.info("Received endorsement certificate file of size: {}", file.getSize());
|
||||
|
||||
byte[] fileBytes;
|
||||
String fileName = file.getOriginalFilename();
|
||||
|
||||
// attempt to retrieve file bytes from the provided file
|
||||
try {
|
||||
fileBytes = file.getBytes();
|
||||
} catch (IOException ioEx) {
|
||||
final String failMessage = String.format(
|
||||
"Failed to read uploaded endorsement certificate file (%s): ", fileName);
|
||||
log.error(failMessage, ioEx);
|
||||
messages.addError(failMessage + ioEx.getMessage());
|
||||
return null;
|
||||
}
|
||||
|
||||
// attempt to build the endorsement certificate from the uploaded bytes
|
||||
try {
|
||||
return new EndorsementCredential(fileBytes);
|
||||
} catch (IOException ioEx) {
|
||||
final String failMessage = String.format(
|
||||
"Failed to parse uploaded endorsement certificate file (%s): ", fileName);
|
||||
log.error(failMessage, ioEx);
|
||||
messages.addError(failMessage + ioEx.getMessage());
|
||||
return null;
|
||||
} catch (DecoderException dEx) {
|
||||
final String failMessage = String.format(
|
||||
"Failed to parse uploaded endorsement certificate pem file (%s): ", fileName);
|
||||
log.error(failMessage, dEx);
|
||||
messages.addError(failMessage + dEx.getMessage());
|
||||
return null;
|
||||
} catch (IllegalArgumentException iaEx) {
|
||||
final String failMessage = String.format(
|
||||
"endorsement certificate format not recognized(%s): ", fileName);
|
||||
log.error(failMessage, iaEx);
|
||||
messages.addError(failMessage + iaEx.getMessage());
|
||||
return null;
|
||||
} catch (IllegalStateException isEx) {
|
||||
final String failMessage = String.format(
|
||||
"Unexpected object while parsing endorsement certificate %s ", fileName);
|
||||
log.error(failMessage, isEx);
|
||||
messages.addError(failMessage + isEx.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method that packages a collection of certificates into a zip file.
|
||||
*
|
||||
* @param zipOut zip outputs stream
|
||||
* @param endorsementCredentials collection of endorsement certificates
|
||||
* @throws IOException if there are any issues packaging or downloading the zip file
|
||||
*/
|
||||
private void bulkDownload(final ZipOutputStream zipOut,
|
||||
final List<EndorsementCredential> endorsementCredentials) throws IOException {
|
||||
String zipFileName;
|
||||
final String singleFileName = "Endorsement_Certificates";
|
||||
|
||||
// get all files
|
||||
for (EndorsementCredential endorsementCredential : endorsementCredentials) {
|
||||
zipFileName = String.format("%s[%s].cer", singleFileName,
|
||||
Integer.toHexString(endorsementCredential.getCertificateHash()));
|
||||
// configure the zip entry, the properties of the 'file'
|
||||
ZipEntry zipEntry = new ZipEntry(zipFileName);
|
||||
zipEntry.setSize((long) endorsementCredential.getRawBytes().length * Byte.SIZE);
|
||||
zipEntry.setTime(System.currentTimeMillis());
|
||||
zipOut.putNextEntry(zipEntry);
|
||||
// the content of the resource
|
||||
StreamUtils.copy(endorsementCredential.getRawBytes(), zipOut);
|
||||
zipOut.closeEntry();
|
||||
}
|
||||
zipOut.finish();
|
||||
}
|
||||
}
|
@ -0,0 +1,119 @@
|
||||
//package hirs.attestationca.portal.page.controllers;
|
||||
//
|
||||
//import hirs.attestationca.persist.FilteredRecordsList;
|
||||
//import hirs.attestationca.persist.entity.manager.IDevIDCertificateRepository;
|
||||
//import hirs.attestationca.persist.entity.userdefined.certificate.IDevIDCertificate;
|
||||
//import hirs.attestationca.persist.service.CertificateService;
|
||||
//import hirs.attestationca.portal.datatables.Column;
|
||||
//import hirs.attestationca.portal.datatables.DataTableInput;
|
||||
//import hirs.attestationca.portal.datatables.DataTableResponse;
|
||||
//import hirs.attestationca.portal.page.Page;
|
||||
//import hirs.attestationca.portal.page.PageController;
|
||||
//import hirs.attestationca.portal.page.params.NoPageParams;
|
||||
//import lombok.extern.log4j.Log4j2;
|
||||
//import org.apache.commons.lang3.StringUtils;
|
||||
//import org.springframework.beans.factory.annotation.Autowired;
|
||||
//import org.springframework.data.domain.PageRequest;
|
||||
//import org.springframework.data.domain.Pageable;
|
||||
//import org.springframework.data.domain.Sort;
|
||||
//import org.springframework.http.MediaType;
|
||||
//import org.springframework.stereotype.Controller;
|
||||
//import org.springframework.ui.Model;
|
||||
//import org.springframework.web.bind.annotation.GetMapping;
|
||||
//import org.springframework.web.bind.annotation.RequestMapping;
|
||||
//import org.springframework.web.bind.annotation.ResponseBody;
|
||||
//import org.springframework.web.servlet.ModelAndView;
|
||||
//
|
||||
//import java.util.List;
|
||||
//import java.util.stream.Collectors;
|
||||
//
|
||||
//@Log4j2
|
||||
//@Controller
|
||||
//@RequestMapping("/HIRS_AttestationCAPortal/portal/certificate-request/idevid-certificates")
|
||||
//public class IDevIdCertificatePageController extends PageController<NoPageParams> {
|
||||
//
|
||||
// private final IDevIDCertificateRepository iDevIDCertificateRepository;
|
||||
// private final CertificateService certificateService;
|
||||
//
|
||||
// @Autowired
|
||||
// public IDevIdCertificatePageController(final IDevIDCertificateRepository iDevIDCertificateRepository,
|
||||
// final CertificateService certificateService) {
|
||||
// super(Page.TRUST_CHAIN);
|
||||
// this.iDevIDCertificateRepository = iDevIDCertificateRepository;
|
||||
// this.certificateService = certificateService;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Returns the path for the view and the data model for the page.
|
||||
// *
|
||||
// * @param params The object to map url parameters into.
|
||||
// * @param model The data model for the request. Can contain data from
|
||||
// * redirect.
|
||||
// * @return the path for the view and data model for the page.
|
||||
// */
|
||||
// @RequestMapping
|
||||
// public ModelAndView initPage(
|
||||
// final NoPageParams params, final Model model) {
|
||||
// return getBaseModelAndView(Page.IDEVID_CERTIFICATES);
|
||||
// }
|
||||
//
|
||||
//
|
||||
// @ResponseBody
|
||||
// @GetMapping(value = "/list",
|
||||
// produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
// public DataTableResponse<IDevIDCertificate> getIDevIdCertificatesTableData(
|
||||
// final DataTableInput input) {
|
||||
//
|
||||
// log.debug("Handling list request: {}", input);
|
||||
//
|
||||
// // attempt to get the column property based on the order index.
|
||||
// String orderColumnName = input.getOrderColumnName();
|
||||
//
|
||||
// log.debug("Ordering on column: {}", orderColumnName);
|
||||
//
|
||||
// String searchText = input.getSearch().getValue();
|
||||
// List<String> searchableColumns = findSearchableColumnsNames(input.getColumns());
|
||||
//
|
||||
// int currentPage = input.getStart() / input.getLength();
|
||||
// Pageable pageable = PageRequest.of(currentPage, input.getLength(), Sort.by(orderColumnName));
|
||||
//
|
||||
// FilteredRecordsList<IDevIDCertificate> records = new FilteredRecordsList<>();
|
||||
// org.springframework.data.domain.Page<IDevIDCertificate> pagedResult;
|
||||
//
|
||||
// if (StringUtils.isBlank(searchText)) {
|
||||
// pagedResult =
|
||||
// this.iDevIDCertificateRepository.findByArchiveFlag(false, pageable);
|
||||
// } else {
|
||||
// pagedResult =
|
||||
// this.certificateService.findBySearchableColumnsAndArchiveFlag(
|
||||
// IDevIDCertificate.class,
|
||||
// searchableColumns,
|
||||
// searchText,
|
||||
// false, pageable);
|
||||
// }
|
||||
//
|
||||
// if (pagedResult.hasContent()) {
|
||||
// records.addAll(pagedResult.getContent());
|
||||
// records.setRecordsTotal(pagedResult.getContent().size());
|
||||
// } else {
|
||||
// records.setRecordsTotal(input.getLength());
|
||||
// }
|
||||
//
|
||||
// records.setRecordsFiltered(iDevIDCertificateRepository.findByArchiveFlag(false).size());
|
||||
//
|
||||
// log.debug("Returning the size of the list of IDEVID certificates: {}", records.size());
|
||||
// return new DataTableResponse<>(records, input);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Helper method that returns a list of column names that are searchable.
|
||||
// *
|
||||
// * @return searchable column names
|
||||
// */
|
||||
// private List<String> findSearchableColumnsNames(List<Column> columns) {
|
||||
//
|
||||
// // Retrieve all searchable columns and collect their names into a list of strings.
|
||||
// return columns.stream().filter(Column::isSearchable).map(Column::getName)
|
||||
// .collect(Collectors.toList());
|
||||
// }
|
||||
//}
|
@ -0,0 +1,241 @@
|
||||
//package hirs.attestationca.portal.page.controllers;
|
||||
//
|
||||
//import hirs.attestationca.persist.FilteredRecordsList;
|
||||
//import hirs.attestationca.persist.entity.manager.CertificateRepository;
|
||||
//import hirs.attestationca.persist.entity.manager.IssuedCertificateRepository;
|
||||
//import hirs.attestationca.persist.entity.userdefined.Certificate;
|
||||
//import hirs.attestationca.persist.entity.userdefined.certificate.IssuedAttestationCertificate;
|
||||
//import hirs.attestationca.persist.service.CertificateService;
|
||||
//import hirs.attestationca.portal.datatables.Column;
|
||||
//import hirs.attestationca.portal.datatables.DataTableInput;
|
||||
//import hirs.attestationca.portal.datatables.DataTableResponse;
|
||||
//import hirs.attestationca.portal.page.Page;
|
||||
//import hirs.attestationca.portal.page.PageController;
|
||||
//import hirs.attestationca.portal.page.params.NoPageParams;
|
||||
//import jakarta.servlet.http.HttpServletResponse;
|
||||
//import lombok.extern.log4j.Log4j2;
|
||||
//import org.apache.commons.lang3.StringUtils;
|
||||
//import org.springframework.beans.factory.annotation.Autowired;
|
||||
//import org.springframework.data.domain.PageRequest;
|
||||
//import org.springframework.data.domain.Pageable;
|
||||
//import org.springframework.data.domain.Sort;
|
||||
//import org.springframework.http.MediaType;
|
||||
//import org.springframework.stereotype.Controller;
|
||||
//import org.springframework.ui.Model;
|
||||
//import org.springframework.util.StreamUtils;
|
||||
//import org.springframework.web.bind.annotation.GetMapping;
|
||||
//import org.springframework.web.bind.annotation.RequestMapping;
|
||||
//import org.springframework.web.bind.annotation.RequestParam;
|
||||
//import org.springframework.web.bind.annotation.ResponseBody;
|
||||
//import org.springframework.web.servlet.ModelAndView;
|
||||
//
|
||||
//import java.io.IOException;
|
||||
//import java.util.List;
|
||||
//import java.util.UUID;
|
||||
//import java.util.stream.Collectors;
|
||||
//import java.util.zip.ZipEntry;
|
||||
//import java.util.zip.ZipOutputStream;
|
||||
//
|
||||
//@Log4j2
|
||||
//@Controller
|
||||
//@RequestMapping("/HIRS_AttestationCAPortal/portal/certificate-request/issued-certificates")
|
||||
//public class IssuedCertificateController extends PageController<NoPageParams> {
|
||||
//
|
||||
// private final CertificateRepository certificateRepository;
|
||||
// private final IssuedCertificateRepository issuedCertificateRepository;
|
||||
// private final CertificateService certificateService;
|
||||
//
|
||||
// @Autowired
|
||||
// public IssuedCertificateController(
|
||||
// final CertificateRepository certificateRepository,
|
||||
// final IssuedCertificateRepository issuedCertificateRepository,
|
||||
// final CertificateService certificateService) {
|
||||
// super(Page.TRUST_CHAIN);
|
||||
// this.certificateRepository = certificateRepository;
|
||||
// this.issuedCertificateRepository = issuedCertificateRepository;
|
||||
// this.certificateService = certificateService;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Returns the path for the view and the data model for the page.
|
||||
// *
|
||||
// * @param params The object to map url parameters into.
|
||||
// * @param model The data model for the request. Can contain data from
|
||||
// * redirect.
|
||||
// * @return the path for the view and data model for the page.
|
||||
// */
|
||||
// @RequestMapping
|
||||
// public ModelAndView initPage(
|
||||
// final NoPageParams params, final Model model) {
|
||||
// return getBaseModelAndView(Page.ISSUED_CERTIFICATES);
|
||||
// }
|
||||
//
|
||||
// @ResponseBody
|
||||
// @GetMapping(value = "/list",
|
||||
// produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
// public DataTableResponse<IssuedAttestationCertificate> getIssuedCertificatesTableData(
|
||||
// final DataTableInput input) {
|
||||
// log.debug("Handling list request for issued certificates: {}", input);
|
||||
//
|
||||
// // attempt to get the column property based on the order index.
|
||||
// String orderColumnName = input.getOrderColumnName();
|
||||
//
|
||||
// log.debug("Ordering on column: {}", orderColumnName);
|
||||
//
|
||||
// String searchText = input.getSearch().getValue();
|
||||
// List<String> searchableColumns = findSearchableColumnsNames(input.getColumns());
|
||||
//
|
||||
// int currentPage = input.getStart() / input.getLength();
|
||||
// Pageable pageable = PageRequest.of(currentPage, input.getLength(), Sort.by(orderColumnName));
|
||||
//
|
||||
// FilteredRecordsList<IssuedAttestationCertificate> records = new FilteredRecordsList<>();
|
||||
// org.springframework.data.domain.Page<IssuedAttestationCertificate> pagedResult;
|
||||
//
|
||||
// if (StringUtils.isBlank(searchText)) {
|
||||
// pagedResult =
|
||||
// this.issuedCertificateRepository.findByArchiveFlag(false, pageable);
|
||||
// } else {
|
||||
// pagedResult =
|
||||
// this.certificateService.findBySearchableColumnsAndArchiveFlag(
|
||||
// IssuedAttestationCertificate.class,
|
||||
// searchableColumns,
|
||||
// searchText,
|
||||
// false, pageable);
|
||||
// }
|
||||
//
|
||||
// if (pagedResult.hasContent()) {
|
||||
// records.addAll(pagedResult.getContent());
|
||||
// records.setRecordsTotal(pagedResult.getContent().size());
|
||||
// } else {
|
||||
// records.setRecordsTotal(input.getLength());
|
||||
// }
|
||||
//
|
||||
// records.setRecordsFiltered(issuedCertificateRepository.findByArchiveFlag(false).size());
|
||||
//
|
||||
// log.debug("Returning the size of the list of issued certificates: {}", records.size());
|
||||
// return new DataTableResponse<>(records, input);
|
||||
//
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Handles request to download the cert by writing it to the response stream
|
||||
// * for download.
|
||||
// *
|
||||
// * @param id the UUID of the cert to download
|
||||
// * @param response the response object (needed to update the header with the
|
||||
// * file name)
|
||||
// * @throws IOException when writing to response output stream
|
||||
// */
|
||||
// @GetMapping("/download")
|
||||
// public void download(
|
||||
// @RequestParam final String id,
|
||||
// final HttpServletResponse response)
|
||||
// throws IOException {
|
||||
// log.info("Handling request to download {}", id);
|
||||
//
|
||||
// try {
|
||||
// UUID uuid = UUID.fromString(id);
|
||||
// Certificate certificate = certificateRepository.getCertificate(uuid);
|
||||
// if (certificate == null) {
|
||||
// // Use the term "record" here to avoid user confusion b/t cert and cred
|
||||
// String notFoundMessage = "Unable to locate record with ID: " + uuid;
|
||||
// log.warn(notFoundMessage);
|
||||
// // send a 404 error when invalid certificate
|
||||
// response.sendError(HttpServletResponse.SC_NOT_FOUND);
|
||||
// } else {
|
||||
// String fileName = "filename=\"" + getCertificateClass(certificateType).getSimpleName()
|
||||
// + "_"
|
||||
// + certificate.getSerialNumber()
|
||||
// + ".cer\"";
|
||||
//
|
||||
// // Set filename for download.
|
||||
// response.setHeader("Content-Disposition", "attachment;" + fileName);
|
||||
// response.setContentType("application/octet-stream");
|
||||
//
|
||||
// // write cert to output stream
|
||||
// response.getOutputStream().write(certificate.getRawBytes());
|
||||
// }
|
||||
// } catch (IllegalArgumentException ex) {
|
||||
// String uuidError = "Failed to parse ID from: " + id;
|
||||
// log.error(uuidError, ex);
|
||||
// // send a 404 error when invalid certificate
|
||||
// response.sendError(HttpServletResponse.SC_NOT_FOUND);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Handles request to download the certs by writing it to the response stream
|
||||
// * for download in bulk.
|
||||
// *
|
||||
// * @param response the response object (needed to update the header with the
|
||||
// * file name)
|
||||
// * @throws IOException when writing to response output stream
|
||||
// */
|
||||
// @GetMapping("/bulk-download")
|
||||
// public void icBulkDownload(final HttpServletResponse response)
|
||||
// throws IOException {
|
||||
// log.info("Handling request to download all issued certificates");
|
||||
// String fileName = "issued_certificates.zip";
|
||||
// final String singleFileName = "Issued_Certificate";
|
||||
// String zipFileName;
|
||||
//
|
||||
// // Set filename for download.
|
||||
// response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
|
||||
// response.setContentType("application/zip");
|
||||
//
|
||||
// try (ZipOutputStream zipOut = new ZipOutputStream(response.getOutputStream())) {
|
||||
// // get all files
|
||||
// bulkDownload(zipOut, this.certificateRepository.findByType("IssuedAttestationCertificate"),
|
||||
// singleFileName);
|
||||
// // write cert to output stream
|
||||
// } catch (IllegalArgumentException ex) {
|
||||
// String uuidError = "Failed to parse ID from: ";
|
||||
// log.error(uuidError, ex);
|
||||
// // send a 404 error when invalid certificate
|
||||
// response.sendError(HttpServletResponse.SC_NOT_FOUND);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Helper method that returns a list of column names that are searchable.
|
||||
// *
|
||||
// * @return searchable column names
|
||||
// */
|
||||
// private List<String> findSearchableColumnsNames(List<Column> columns) {
|
||||
//
|
||||
// // Retrieve all searchable columns and collect their names into a list of strings.
|
||||
// return columns.stream().filter(Column::isSearchable).map(Column::getName)
|
||||
// .collect(Collectors.toList());
|
||||
// }
|
||||
//
|
||||
//
|
||||
// /**
|
||||
// * Helper method that packages a collection of certificates into a zip file.
|
||||
// *
|
||||
// * @param zipOut zip outputs stream
|
||||
// * @param certificates collection of certificates
|
||||
// * @param singleFileName zip file name
|
||||
// * @return zip outputs stream
|
||||
// * @throws IOException if there are any issues packaging or downloading the zip file
|
||||
// */
|
||||
// private ZipOutputStream bulkDownload(final ZipOutputStream zipOut,
|
||||
// final List<Certificate> certificates,
|
||||
// final String singleFileName) throws IOException {
|
||||
// String zipFileName;
|
||||
// // get all files
|
||||
// for (Certificate certificate : certificates) {
|
||||
// zipFileName = String.format("%s[%s].cer", singleFileName,
|
||||
// Integer.toHexString(certificate.getCertificateHash()));
|
||||
// // configure the zip entry, the properties of the 'file'
|
||||
// ZipEntry zipEntry = new ZipEntry(zipFileName);
|
||||
// zipEntry.setSize((long) certificate.getRawBytes().length * Byte.SIZE);
|
||||
// zipEntry.setTime(System.currentTimeMillis());
|
||||
// zipOut.putNextEntry(zipEntry);
|
||||
// // the content of the resource
|
||||
// StreamUtils.copy(certificate.getRawBytes(), zipOut);
|
||||
// zipOut.closeEntry();
|
||||
// }
|
||||
// zipOut.finish();
|
||||
// return zipOut;
|
||||
// }
|
||||
//}
|
@ -0,0 +1,417 @@
|
||||
package hirs.attestationca.portal.page.controllers;
|
||||
|
||||
import hirs.attestationca.persist.DBManagerException;
|
||||
import hirs.attestationca.persist.FilteredRecordsList;
|
||||
import hirs.attestationca.persist.entity.manager.CertificateRepository;
|
||||
import hirs.attestationca.persist.entity.manager.EndorsementCredentialRepository;
|
||||
import hirs.attestationca.persist.entity.manager.PlatformCertificateRepository;
|
||||
import hirs.attestationca.persist.entity.userdefined.Certificate;
|
||||
import hirs.attestationca.persist.entity.userdefined.certificate.EndorsementCredential;
|
||||
import hirs.attestationca.persist.entity.userdefined.certificate.PlatformCredential;
|
||||
import hirs.attestationca.persist.service.CertificateService;
|
||||
import hirs.attestationca.portal.datatables.Column;
|
||||
import hirs.attestationca.portal.datatables.DataTableInput;
|
||||
import hirs.attestationca.portal.datatables.DataTableResponse;
|
||||
import hirs.attestationca.portal.page.Page;
|
||||
import hirs.attestationca.portal.page.PageController;
|
||||
import hirs.attestationca.portal.page.PageMessages;
|
||||
import hirs.attestationca.portal.page.params.NoPageParams;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.bouncycastle.util.encoders.DecoderException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.util.StreamUtils;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
|
||||
import org.springframework.web.servlet.view.RedirectView;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
@Log4j2
|
||||
@Controller
|
||||
@RequestMapping("/HIRS_AttestationCAPortal/portal/certificate-request/platform-credentials")
|
||||
public class PlatformCredentialPageController extends PageController<NoPageParams> {
|
||||
|
||||
private static final String PLATFORMCREDENTIAL = "platform-credentials";
|
||||
|
||||
private final CertificateRepository certificateRepository;
|
||||
private final PlatformCertificateRepository platformCertificateRepository;
|
||||
private final EndorsementCredentialRepository endorsementCredentialRepository;
|
||||
private final CertificateService certificateService;
|
||||
|
||||
@Autowired
|
||||
public PlatformCredentialPageController(final CertificateRepository certificateRepository,
|
||||
final PlatformCertificateRepository platformCertificateRepository,
|
||||
final EndorsementCredentialRepository endorsementCredentialRepository,
|
||||
final CertificateService certificateService) {
|
||||
super(Page.TRUST_CHAIN);
|
||||
this.certificateRepository = certificateRepository;
|
||||
this.platformCertificateRepository = platformCertificateRepository;
|
||||
this.endorsementCredentialRepository = endorsementCredentialRepository;
|
||||
this.certificateService = certificateService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the path for the view and the data model for the page.
|
||||
*
|
||||
* @param params The object to map url parameters into.
|
||||
* @param model The data model for the request. Can contain data from
|
||||
* redirect.
|
||||
* @return the path for the view and data model for the page.
|
||||
*/
|
||||
@RequestMapping
|
||||
public ModelAndView initPage(
|
||||
final NoPageParams params, final Model model) {
|
||||
return getBaseModelAndView(Page.PLATFORM_CREDENTIALS);
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@GetMapping(value = "/list",
|
||||
produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public DataTableResponse<PlatformCredential> getPlatformCredentialsTableData(
|
||||
final DataTableInput input) {
|
||||
|
||||
log.debug("Handling list request for platform credentials: {}", input);
|
||||
|
||||
// attempt to get the column property based on the order index.
|
||||
String orderColumnName = input.getOrderColumnName();
|
||||
|
||||
log.debug("Ordering on column: {}", orderColumnName);
|
||||
|
||||
String searchText = input.getSearch().getValue();
|
||||
List<String> searchableColumns = findSearchableColumnsNames(input.getColumns());
|
||||
|
||||
int currentPage = input.getStart() / input.getLength();
|
||||
Pageable pageable = PageRequest.of(currentPage, input.getLength(), Sort.by(orderColumnName));
|
||||
|
||||
FilteredRecordsList<PlatformCredential> records = new FilteredRecordsList<>();
|
||||
|
||||
org.springframework.data.domain.Page<PlatformCredential> pagedResult;
|
||||
|
||||
if (StringUtils.isBlank(searchText)) {
|
||||
pagedResult =
|
||||
this.platformCertificateRepository.findByArchiveFlag(false, pageable);
|
||||
} else {
|
||||
pagedResult =
|
||||
this.certificateService.findBySearchableColumnsAndArchiveFlag(
|
||||
PlatformCredential.class,
|
||||
searchableColumns,
|
||||
searchText,
|
||||
false, pageable);
|
||||
}
|
||||
|
||||
if (pagedResult.hasContent()) {
|
||||
records.addAll(pagedResult.getContent());
|
||||
records.setRecordsTotal(pagedResult.getContent().size());
|
||||
} else {
|
||||
records.setRecordsTotal(input.getLength());
|
||||
}
|
||||
|
||||
records.setRecordsFiltered(platformCertificateRepository.findByArchiveFlag(false).size());
|
||||
|
||||
EndorsementCredential associatedEC;
|
||||
|
||||
if (!records.isEmpty()) {
|
||||
// loop all the platform certificates
|
||||
for (PlatformCredential pc : records) {
|
||||
// find the EC using the PC's "holder serial number"
|
||||
associatedEC = this.endorsementCredentialRepository
|
||||
.findBySerialNumber(pc.getHolderSerialNumber());
|
||||
|
||||
if (associatedEC != null) {
|
||||
log.debug("EC ID for holder s/n {} = {}", pc
|
||||
.getHolderSerialNumber(), associatedEC.getId());
|
||||
}
|
||||
|
||||
pc.setEndorsementCredential(associatedEC);
|
||||
}
|
||||
}
|
||||
|
||||
log.debug("Returning the size of the list of platform credentials: {}", records.size());
|
||||
return new DataTableResponse<>(records, input);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles request to download the cert by writing it to the response stream
|
||||
* for download.
|
||||
*
|
||||
* @param id the UUID of the cert to download
|
||||
* @param response the response object (needed to update the header with the
|
||||
* file name)
|
||||
* @throws IOException when writing to response output stream
|
||||
*/
|
||||
@GetMapping("/download")
|
||||
public void platformCredentialSingleDownload(
|
||||
@RequestParam final String id,
|
||||
final HttpServletResponse response)
|
||||
throws IOException {
|
||||
log.info("Handling request to download platform certificate id {}", id);
|
||||
|
||||
try {
|
||||
UUID uuid = UUID.fromString(id);
|
||||
Certificate certificate = certificateRepository.getCertificate(uuid);
|
||||
|
||||
if (certificate == null) {
|
||||
log.warn("Unable to locate platform certificate record with ID: {}", uuid);
|
||||
// send a 404 error when invalid certificate
|
||||
response.sendError(HttpServletResponse.SC_NOT_FOUND);
|
||||
} else {
|
||||
if (certificate instanceof PlatformCredential uploadedPlatformCredential) {
|
||||
|
||||
String fileName = "filename=\"" + PlatformCredential.class.getSimpleName()
|
||||
+ "_"
|
||||
+ uploadedPlatformCredential.getSerialNumber()
|
||||
+ ".cer\"";
|
||||
|
||||
// Set filename for download.
|
||||
response.setHeader("Content-Disposition", "attachment;" + fileName);
|
||||
response.setContentType("application/octet-stream");
|
||||
|
||||
// write cert to output stream
|
||||
response.getOutputStream().write(certificate.getRawBytes());
|
||||
}
|
||||
}
|
||||
} catch (IllegalArgumentException ex) {
|
||||
log.error("Failed to parse platform certificate ID from: " + id, ex);
|
||||
// send a 404 error when invalid certificate
|
||||
response.sendError(HttpServletResponse.SC_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles request to download the certs by writing it to the response stream
|
||||
* for download in bulk.
|
||||
*
|
||||
* @param response the response object (needed to update the header with the
|
||||
* file name)
|
||||
* @throws IOException when writing to response output stream
|
||||
*/
|
||||
@GetMapping("/bulk-download")
|
||||
public void platformCredentialsBulkDownload(final HttpServletResponse response)
|
||||
throws IOException {
|
||||
log.info("Handling request to download all platform certificates");
|
||||
|
||||
final String fileName = "platform_certificates.zip";
|
||||
|
||||
// Set filename for download.
|
||||
response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
|
||||
response.setContentType("application/zip");
|
||||
|
||||
try (ZipOutputStream zipOut = new ZipOutputStream(response.getOutputStream())) {
|
||||
|
||||
// find all the uploaded platform certificates
|
||||
List<Certificate> certificates = this.certificateRepository.findByType("PlatformCredential");
|
||||
|
||||
// convert the list of certificates to a list of platform certificates
|
||||
List<PlatformCredential> uploadedPCs = certificates.stream()
|
||||
.filter(eachPC -> eachPC instanceof PlatformCredential)
|
||||
.map(eachPC -> (PlatformCredential) eachPC).toList();
|
||||
|
||||
// get all files and write certificates to output stream
|
||||
bulkDownloadPlatformCertificates(zipOut, uploadedPCs);
|
||||
} catch (IllegalArgumentException ex) {
|
||||
String uuidError = "Failed to parse platform certificate ID from: ";
|
||||
log.error(uuidError, ex);
|
||||
// send a 404 error when invalid certificate
|
||||
response.sendError(HttpServletResponse.SC_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload and processes a credential.
|
||||
*
|
||||
* @param files the files to process
|
||||
* @param attr the redirection attributes
|
||||
* @return the redirection view
|
||||
* @throws URISyntaxException if malformed URI
|
||||
*/
|
||||
@PostMapping("/upload")
|
||||
protected RedirectView upload(
|
||||
@RequestParam("file") final MultipartFile[] files,
|
||||
final RedirectAttributes attr) throws URISyntaxException {
|
||||
|
||||
log.info("Handling request to upload one or more platform certificates");
|
||||
|
||||
Map<String, Object> model = new HashMap<>();
|
||||
PageMessages messages = new PageMessages();
|
||||
|
||||
List<String> errorMessages = new ArrayList<>();
|
||||
List<String> successMessages = new ArrayList<>();
|
||||
|
||||
for (MultipartFile file : files) {
|
||||
//Parse certificate
|
||||
PlatformCredential parsedPlatformCredential = parsePlatformCredential(file, messages);
|
||||
|
||||
//Store only if it was parsed
|
||||
if (parsedPlatformCredential != null) {
|
||||
certificateService.storeCertificate(
|
||||
PLATFORMCREDENTIAL,
|
||||
file.getOriginalFilename(),
|
||||
successMessages, errorMessages, parsedPlatformCredential);
|
||||
}
|
||||
}
|
||||
|
||||
//Add messages to the model
|
||||
model.put(MESSAGES_ATTRIBUTE, messages);
|
||||
|
||||
return redirectTo(Page.PLATFORM_CREDENTIALS, new NoPageParams(), model, attr);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Archives (soft delete) the credential.
|
||||
*
|
||||
* @param id the UUID of the cert to delete
|
||||
* @param attr RedirectAttributes used to forward data back to the original
|
||||
* page.
|
||||
* @return redirect to this page
|
||||
* @throws URISyntaxException if malformed URI
|
||||
*/
|
||||
@PostMapping("/delete")
|
||||
public RedirectView delete(
|
||||
@RequestParam final String id,
|
||||
final RedirectAttributes attr) throws URISyntaxException {
|
||||
log.info("Handling request to delete platform certificate id {}", id);
|
||||
|
||||
Map<String, Object> model = new HashMap<>();
|
||||
PageMessages messages = new PageMessages();
|
||||
|
||||
try {
|
||||
List<String> successMessages = new ArrayList<>();
|
||||
List<String> errorMessages = new ArrayList<>();
|
||||
|
||||
UUID uuid = UUID.fromString(id);
|
||||
|
||||
this.certificateService.deleteCertificate(uuid, PLATFORMCREDENTIAL,
|
||||
successMessages, errorMessages);
|
||||
|
||||
} catch (IllegalArgumentException ex) {
|
||||
String uuidError = "Failed to parse ID from: " + id;
|
||||
messages.addError(uuidError);
|
||||
log.error(uuidError, ex);
|
||||
} catch (DBManagerException ex) {
|
||||
String dbError = "Failed to archive cert: " + id;
|
||||
messages.addError(dbError);
|
||||
log.error(dbError, ex);
|
||||
}
|
||||
|
||||
model.put(MESSAGES_ATTRIBUTE, messages);
|
||||
return redirectTo(Page.PLATFORM_CREDENTIALS, new NoPageParams(), model, attr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method that returns a list of column names that are searchable.
|
||||
*
|
||||
* @return searchable column names
|
||||
*/
|
||||
private List<String> findSearchableColumnsNames(List<Column> columns) {
|
||||
// Retrieve all searchable columns and collect their names into a list of strings.
|
||||
return columns.stream().filter(Column::isSearchable).map(Column::getName)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to parse the provided file in order to create a PLatform Credential.
|
||||
*
|
||||
* @param file file
|
||||
* @param messages page messages
|
||||
* @return platform credential
|
||||
*/
|
||||
private PlatformCredential parsePlatformCredential(MultipartFile file, PageMessages messages) {
|
||||
log.info("Received platform certificate file of size: {}", file.getSize());
|
||||
|
||||
byte[] fileBytes;
|
||||
String fileName = file.getOriginalFilename();
|
||||
|
||||
// attempt to retrieve file bytes from the provided file
|
||||
try {
|
||||
fileBytes = file.getBytes();
|
||||
} catch (IOException ioEx) {
|
||||
final String failMessage = String.format(
|
||||
"Failed to read uploaded platform certificate file (%s): ", fileName);
|
||||
log.error(failMessage, ioEx);
|
||||
messages.addError(failMessage + ioEx.getMessage());
|
||||
return null;
|
||||
}
|
||||
|
||||
// attempt to build the platform certificate from the uploaded bytes
|
||||
try {
|
||||
return new PlatformCredential(fileBytes);
|
||||
} catch (IOException ioEx) {
|
||||
final String failMessage = String.format(
|
||||
"Failed to parse uploaded platform certificate file (%s): ", fileName);
|
||||
log.error(failMessage, ioEx);
|
||||
messages.addError(failMessage + ioEx.getMessage());
|
||||
return null;
|
||||
} catch (DecoderException dEx) {
|
||||
final String failMessage = String.format(
|
||||
"Failed to parse uploaded platform certificate pem file (%s): ", fileName);
|
||||
log.error(failMessage, dEx);
|
||||
messages.addError(failMessage + dEx.getMessage());
|
||||
return null;
|
||||
} catch (IllegalArgumentException iaEx) {
|
||||
final String failMessage = String.format(
|
||||
"platform certificate format not recognized(%s): ", fileName);
|
||||
log.error(failMessage, iaEx);
|
||||
messages.addError(failMessage + iaEx.getMessage());
|
||||
return null;
|
||||
} catch (IllegalStateException isEx) {
|
||||
final String failMessage = String.format(
|
||||
"Unexpected object while parsing platform certificate %s ", fileName);
|
||||
log.error(failMessage, isEx);
|
||||
messages.addError(failMessage + isEx.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method that packages a collection of platform credentials into a zip file.
|
||||
*
|
||||
* @param zipOut zip outputs stream
|
||||
* @param platformCredentials collection of platform certificates
|
||||
* @throws IOException if there are any issues packaging or downloading the zip file
|
||||
*/
|
||||
private void bulkDownloadPlatformCertificates(final ZipOutputStream zipOut,
|
||||
final List<PlatformCredential> platformCredentials)
|
||||
throws IOException {
|
||||
String zipFileName;
|
||||
final String singleFileName = "Platform_Certificate";
|
||||
|
||||
// get all files
|
||||
for (PlatformCredential platformCredential : platformCredentials) {
|
||||
zipFileName = String.format("%s[%s].cer", singleFileName,
|
||||
Integer.toHexString(platformCredential.getCertificateHash()));
|
||||
// configure the zip entry, the properties of the 'file'
|
||||
ZipEntry zipEntry = new ZipEntry(zipFileName);
|
||||
zipEntry.setSize((long) platformCredential.getRawBytes().length * Byte.SIZE);
|
||||
zipEntry.setTime(System.currentTimeMillis());
|
||||
zipOut.putNextEntry(zipEntry);
|
||||
// the content of the resource
|
||||
StreamUtils.copy(platformCredential.getRawBytes(), zipOut);
|
||||
zipOut.closeEntry();
|
||||
}
|
||||
zipOut.finish();
|
||||
}
|
||||
}
|
@ -0,0 +1,286 @@
|
||||
//package hirs.attestationca.portal.page.controllers;
|
||||
//
|
||||
//import hirs.attestationca.persist.FilteredRecordsList;
|
||||
//import hirs.attestationca.persist.entity.manager.CACredentialRepository;
|
||||
//import hirs.attestationca.persist.entity.manager.CertificateRepository;
|
||||
//import hirs.attestationca.persist.entity.userdefined.Certificate;
|
||||
//import hirs.attestationca.persist.entity.userdefined.certificate.CertificateAuthorityCredential;
|
||||
//import hirs.attestationca.persist.service.CertificateService;
|
||||
//import hirs.attestationca.portal.datatables.Column;
|
||||
//import hirs.attestationca.portal.datatables.DataTableInput;
|
||||
//import hirs.attestationca.portal.datatables.DataTableResponse;
|
||||
//import hirs.attestationca.portal.page.Page;
|
||||
//import hirs.attestationca.portal.page.PageController;
|
||||
//import hirs.attestationca.portal.page.params.NoPageParams;
|
||||
//import hirs.attestationca.portal.page.utils.CertificateStringMapBuilder;
|
||||
//import jakarta.servlet.http.HttpServletResponse;
|
||||
//import lombok.extern.log4j.Log4j2;
|
||||
//import org.apache.commons.lang3.StringUtils;
|
||||
//import org.springframework.beans.factory.annotation.Autowired;
|
||||
//import org.springframework.data.domain.PageRequest;
|
||||
//import org.springframework.data.domain.Pageable;
|
||||
//import org.springframework.data.domain.Sort;
|
||||
//import org.springframework.http.MediaType;
|
||||
//import org.springframework.stereotype.Controller;
|
||||
//import org.springframework.ui.Model;
|
||||
//import org.springframework.util.StreamUtils;
|
||||
//import org.springframework.web.bind.annotation.GetMapping;
|
||||
//import org.springframework.web.bind.annotation.RequestMapping;
|
||||
//import org.springframework.web.bind.annotation.RequestParam;
|
||||
//import org.springframework.web.bind.annotation.ResponseBody;
|
||||
//import org.springframework.web.servlet.ModelAndView;
|
||||
//
|
||||
//import java.io.IOException;
|
||||
//import java.security.cert.CertificateEncodingException;
|
||||
//import java.security.cert.X509Certificate;
|
||||
//import java.util.HashMap;
|
||||
//import java.util.List;
|
||||
//import java.util.UUID;
|
||||
//import java.util.stream.Collectors;
|
||||
//import java.util.zip.ZipEntry;
|
||||
//import java.util.zip.ZipOutputStream;
|
||||
//
|
||||
//import static hirs.attestationca.portal.page.controllers.CertificatePageController.ACA_CERT_DATA;
|
||||
//
|
||||
//@Log4j2
|
||||
//@Controller
|
||||
//@RequestMapping("/HIRS_AttestationCAPortal/portal/certificate-request/trust-chain")
|
||||
//public class TrustChainCertificatePageController extends PageController<NoPageParams> {
|
||||
//
|
||||
// private final CertificateRepository certificateRepository;
|
||||
// private final CACredentialRepository caCredentialRepository;
|
||||
// private final CertificateService certificateService;
|
||||
// private CertificateAuthorityCredential certificateAuthorityCredential;
|
||||
//
|
||||
// @Autowired
|
||||
// public TrustChainCertificatePageController(final CertificateRepository certificateRepository,
|
||||
// final CACredentialRepository caCredentialRepository,
|
||||
// final CertificateService certificateService,
|
||||
// final X509Certificate acaCertificate) {
|
||||
// super(Page.TRUST_CHAIN);
|
||||
// this.certificateRepository = certificateRepository;
|
||||
// this.caCredentialRepository = caCredentialRepository;
|
||||
// this.certificateService = certificateService;
|
||||
//
|
||||
// try {
|
||||
// certificateAuthorityCredential
|
||||
// = new CertificateAuthorityCredential(acaCertificate.getEncoded());
|
||||
// } catch (IOException ioEx) {
|
||||
// log.error("Failed to read ACA certificate", ioEx);
|
||||
// } catch (CertificateEncodingException ceEx) {
|
||||
// log.error("Error getting encoded ACA certificate", ceEx);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Returns the path for the view and the data model for the page.
|
||||
// *
|
||||
// * @param params The object to map url parameters into.
|
||||
// * @param model The data model for the request. Can contain data from
|
||||
// * redirect.
|
||||
// * @return the path for the view and data model for the page.
|
||||
// */
|
||||
// @RequestMapping
|
||||
// public ModelAndView initPage(
|
||||
// final NoPageParams params, final Model model) {
|
||||
//
|
||||
// ModelAndView mav = getBaseModelAndView(Page.TRUST_CHAIN);
|
||||
//
|
||||
// mav.addObject(ACA_CERT_DATA,
|
||||
// new HashMap<String, String>(CertificateStringMapBuilder.getCertificateAuthorityInformation(
|
||||
// certificateAuthorityCredential, this.certificateRepository,
|
||||
// this.caCredentialRepository)));
|
||||
//
|
||||
// return mav;
|
||||
// }
|
||||
//
|
||||
// @ResponseBody
|
||||
// @GetMapping(value = "/list",
|
||||
// produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
// public DataTableResponse<CertificateAuthorityCredential> getTrustChainTableData(
|
||||
// final DataTableInput input) {
|
||||
// log.debug("Handling list request: {}", input);
|
||||
//
|
||||
// // attempt to get the column property based on the order index.
|
||||
// String orderColumnName = input.getOrderColumnName();
|
||||
//
|
||||
// log.debug("Ordering on column: {}", orderColumnName);
|
||||
//
|
||||
// String searchText = input.getSearch().getValue();
|
||||
// List<String> searchableColumns = findSearchableColumnsNames(input.getColumns());
|
||||
//
|
||||
// int currentPage = input.getStart() / input.getLength();
|
||||
// Pageable pageable = PageRequest.of(currentPage, input.getLength(), Sort.by(orderColumnName));
|
||||
//
|
||||
// FilteredRecordsList<CertificateAuthorityCredential> records = new FilteredRecordsList<>();
|
||||
//
|
||||
// org.springframework.data.domain.Page<CertificateAuthorityCredential> pagedResult;
|
||||
//
|
||||
// if (StringUtils.isBlank(searchText)) {
|
||||
// pagedResult =
|
||||
// this.caCredentialRepository.findByArchiveFlag(false, pageable);
|
||||
// } else {
|
||||
// pagedResult =
|
||||
// this.certificateService.findBySearchableColumnsAndArchiveFlag(
|
||||
// CertificateAuthorityCredential.class,
|
||||
// searchableColumns,
|
||||
// searchText,
|
||||
// false, pageable);
|
||||
// }
|
||||
//
|
||||
//
|
||||
// if (pagedResult.hasContent()) {
|
||||
// records.addAll(pagedResult.getContent());
|
||||
// records.setRecordsTotal(pagedResult.getContent().size());
|
||||
// } else {
|
||||
// records.setRecordsTotal(input.getLength());
|
||||
// }
|
||||
//
|
||||
// records.setRecordsFiltered(caCredentialRepository.findByArchiveFlag(false).size());
|
||||
//
|
||||
// log.debug("Returning the size of the list of trust chain certificates: {}", records.size());
|
||||
// return new DataTableResponse<>(records, input);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Handles request to download the cert by writing it to the response stream
|
||||
// * for download.
|
||||
// *
|
||||
// * @param id the UUID of the cert to download
|
||||
// * @param response the response object (needed to update the header with the
|
||||
// * file name)
|
||||
// * @throws IOException when writing to response output stream
|
||||
// */
|
||||
// @GetMapping("/download")
|
||||
// public void download(
|
||||
// @RequestParam final String id,
|
||||
// final HttpServletResponse response)
|
||||
// throws IOException {
|
||||
// log.info("Handling request to download {}", id);
|
||||
//
|
||||
// try {
|
||||
// UUID uuid = UUID.fromString(id);
|
||||
// Certificate certificate = certificateRepository.getCertificate(uuid);
|
||||
// if (certificate == null) {
|
||||
// // Use the term "record" here to avoid user confusion b/t cert and cred
|
||||
// String notFoundMessage = "Unable to locate record with ID: " + uuid;
|
||||
// log.warn(notFoundMessage);
|
||||
// // send a 404 error when invalid certificate
|
||||
// response.sendError(HttpServletResponse.SC_NOT_FOUND);
|
||||
// } else {
|
||||
// String fileName = "filename=\"" + getCertificateClass(certificateType).getSimpleName()
|
||||
// + "_"
|
||||
// + certificate.getSerialNumber()
|
||||
// + ".cer\"";
|
||||
//
|
||||
// // Set filename for download.
|
||||
// response.setHeader("Content-Disposition", "attachment;" + fileName);
|
||||
// response.setContentType("application/octet-stream");
|
||||
//
|
||||
// // write cert to output stream
|
||||
// response.getOutputStream().write(certificate.getRawBytes());
|
||||
// }
|
||||
// } catch (IllegalArgumentException ex) {
|
||||
// String uuidError = "Failed to parse ID from: " + id;
|
||||
// log.error(uuidError, ex);
|
||||
// // send a 404 error when invalid certificate
|
||||
// response.sendError(HttpServletResponse.SC_NOT_FOUND);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Handles request to download the ACA cert by writing it to the response
|
||||
// * stream for download.
|
||||
// *
|
||||
// * @param response the response object (needed to update the header with the
|
||||
// * file name)
|
||||
// * @throws IOException when writing to response output stream
|
||||
// */
|
||||
// @ResponseBody
|
||||
// @GetMapping("/download-aca-cert")
|
||||
// public void downloadAcaCertificate(final HttpServletResponse response)
|
||||
// throws IOException {
|
||||
//
|
||||
// // Set filename for download.
|
||||
// response.setHeader("Content-Disposition", "attachment; filename=\"hirs-aca-cert.cer\"");
|
||||
// response.setContentType("application/octet-stream");
|
||||
//
|
||||
// // write cert to output stream
|
||||
// response.getOutputStream().write(certificateAuthorityCredential.getRawBytes());
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Handles request to download the certs by writing it to the response stream
|
||||
// * for download in bulk.
|
||||
// *
|
||||
// * @param response the response object (needed to update the header with the
|
||||
// * file name)
|
||||
// * @throws IOException when writing to response output stream
|
||||
// */
|
||||
// @GetMapping("/bulk-download")
|
||||
// public void caBulkDownload(final HttpServletResponse response)
|
||||
// throws IOException {
|
||||
// log.info("Handling request to download all trust chain certificates");
|
||||
// String fileName = "trust-chain.zip";
|
||||
// final String singleFileName = "ca-certificates";
|
||||
//
|
||||
// // Set filename for download.
|
||||
// response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
|
||||
// response.setContentType("application/zip");
|
||||
//
|
||||
// try (ZipOutputStream zipOut = new ZipOutputStream(response.getOutputStream())) {
|
||||
// // get all files
|
||||
// bulkDownload(zipOut, this.certificateRepository.findByType("CertificateAuthorityCredential"),
|
||||
// singleFileName);
|
||||
// // write cert to output stream
|
||||
// } catch (IllegalArgumentException ex) {
|
||||
// String uuidError = "Failed to parse ID from: ";
|
||||
// log.error(uuidError, ex);
|
||||
// // send a 404 error when invalid certificate
|
||||
// response.sendError(HttpServletResponse.SC_NOT_FOUND);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//
|
||||
// /**
|
||||
// * Helper method that returns a list of column names that are searchable.
|
||||
// *
|
||||
// * @return searchable column names
|
||||
// */
|
||||
// private List<String> findSearchableColumnsNames(List<Column> columns) {
|
||||
//
|
||||
// // Retrieve all searchable columns and collect their names into a list of strings.
|
||||
// return columns.stream().filter(Column::isSearchable).map(Column::getName)
|
||||
// .collect(Collectors.toList());
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Helper method that packages a collection of certificates into a zip file.
|
||||
// *
|
||||
// * @param zipOut zip outputs stream
|
||||
// * @param certificates collection of certificates
|
||||
// * @param singleFileName zip file name
|
||||
// * @return zip outputs stream
|
||||
// * @throws IOException if there are any issues packaging or downloading the zip file
|
||||
// */
|
||||
// private ZipOutputStream bulkDownload(final ZipOutputStream zipOut,
|
||||
// final List<Certificate> certificates,
|
||||
// final String singleFileName) throws IOException {
|
||||
// String zipFileName;
|
||||
// // get all files
|
||||
// for (Certificate certificate : certificates) {
|
||||
// zipFileName = String.format("%s[%s].cer", singleFileName,
|
||||
// Integer.toHexString(certificate.getCertificateHash()));
|
||||
// // configure the zip entry, the properties of the 'file'
|
||||
// ZipEntry zipEntry = new ZipEntry(zipFileName);
|
||||
// zipEntry.setSize((long) certificate.getRawBytes().length * Byte.SIZE);
|
||||
// zipEntry.setTime(System.currentTimeMillis());
|
||||
// zipOut.putNextEntry(zipEntry);
|
||||
// // the content of the resource
|
||||
// StreamUtils.copy(certificate.getRawBytes(), zipOut);
|
||||
// zipOut.closeEntry();
|
||||
// }
|
||||
// zipOut.finish();
|
||||
// return zipOut;
|
||||
// }
|
||||
//}
|
@ -1,4 +1,4 @@
|
||||
<%@page contentType="text/html" pageEncoding="UTF-8"%>
|
||||
<!-- <%@page contentType="text/html" pageEncoding="UTF-8"%>
|
||||
|
||||
<%-- JSP TAGS --%>
|
||||
<%@taglib prefix="c" uri="jakarta.tags.core" %>
|
||||
@ -6,133 +6,143 @@
|
||||
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
|
||||
<%@taglib prefix="my" tagdir="/WEB-INF/tags"%>
|
||||
|
||||
<%-- CONTENT --%>
|
||||
<%-- CONTENT --%> -->
|
||||
<my:page>
|
||||
<jsp:attribute name="script">
|
||||
<script
|
||||
type="text/javascript"
|
||||
src="${lib}/jquery.spring-friendly/jquery.spring-friendly.js"
|
||||
></script>
|
||||
</jsp:attribute>
|
||||
<jsp:attribute name="pageHeaderTitle">Device Listing</jsp:attribute>
|
||||
|
||||
<jsp:attribute name="script">
|
||||
<script type="text/javascript" src="${lib}/jquery.spring-friendly/jquery.spring-friendly.js"></script>
|
||||
</jsp:attribute>
|
||||
<jsp:attribute name="pageHeaderTitle">Device Listing</jsp:attribute>
|
||||
<jsp:body>
|
||||
<!-- text and icon resource variables -->
|
||||
<c:set
|
||||
var="passIcon"
|
||||
value="${icons}/ic_checkbox_marked_circle_black_green_24dp.png"
|
||||
/>
|
||||
<c:set var="failIcon" value="${icons}/ic_error_red_24dp.png" />
|
||||
<c:set var="errorIcon" value=".${icons}/ic_error_black_24dp.png" />
|
||||
<c:set
|
||||
var="unknownIcon"
|
||||
value="${icons}/ic_questionmark_circle_orange_24dp.png"
|
||||
/>
|
||||
<c:set var="passText" value="Validation Passed" />
|
||||
<c:set var="failText" value="Validation Failed" />
|
||||
<c:set var="errorText" value="Validation Error" />
|
||||
<c:set var="unknownText" value="Unknown Validation Status" />
|
||||
|
||||
<jsp:body>
|
||||
<!-- text and icon resource variables -->
|
||||
<c:set var="passIcon" value="${icons}/ic_checkbox_marked_circle_black_green_24dp.png"/>
|
||||
<c:set var="failIcon" value="${icons}/ic_error_red_24dp.png"/>
|
||||
<c:set var="errorIcon" value=".${icons}/ic_error_black_24dp.png"/>
|
||||
<c:set var="unknownIcon" value="${icons}/ic_questionmark_circle_orange_24dp.png"/>
|
||||
<c:set var="passText" value="Validation Passed"/>
|
||||
<c:set var="failText" value="Validation Failed"/>
|
||||
<c:set var="errorText" value="Validation Error"/>
|
||||
<c:set var="unknownText" value="Unknown Validation Status"/>
|
||||
<div class="aca-data-table">
|
||||
<table id="deviceTable" class="display" width="100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th rowspan="2">Validation Status</th>
|
||||
<th rowspan="2">Hostname</th>
|
||||
<th colspan="3">Credentials</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Issued Attestation</th>
|
||||
<th>Platform</th>
|
||||
<th>Endorsement</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
</div>
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
let url = portal + "/devices/list";
|
||||
let columns = [
|
||||
{
|
||||
data: "supplyChainValidationStatus",
|
||||
searchable: false,
|
||||
render: function (data, type, full, meta) {
|
||||
let html = "";
|
||||
switch (full.device.supplyChainValidationStatus) {
|
||||
case "PASS":
|
||||
html = '<img src="${passIcon}" title="${passText}">';
|
||||
break;
|
||||
case "FAIL":
|
||||
html = '<img src="${failIcon}" title="${failText}"/>';
|
||||
break;
|
||||
case "ERROR":
|
||||
html = '<img src="${errorIcon}" title="${errorText}">';
|
||||
break;
|
||||
default:
|
||||
html = '<img src="${unknownIcon}" title="${unknownText}">';
|
||||
break;
|
||||
}
|
||||
return html;
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "name",
|
||||
data: "name",
|
||||
render: function (data, type, full, meta) {
|
||||
return full.device.name;
|
||||
},
|
||||
},
|
||||
{
|
||||
data: "id",
|
||||
orderable: false,
|
||||
searchable: false,
|
||||
render: function (data, type, full, meta) {
|
||||
//Display issued attestation certificate
|
||||
if (full.IssuedAttestationCertificate === undefined) return "";
|
||||
let size = full.IssuedAttestationCertificate.length;
|
||||
let html = "";
|
||||
|
||||
<div class="aca-data-table">
|
||||
<table id="deviceTable" class="display" width="100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th rowspan="2">Validation Status</th>
|
||||
<th rowspan="2">Hostname</th>
|
||||
<th colspan="3">Credentials</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Issued Attestation</th>
|
||||
<th>Platform</th>
|
||||
<th>Endorsement</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
</div>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
let url = portal + '/devices/list';
|
||||
let columns = [
|
||||
{
|
||||
data: 'supplyChainValidationStatus',
|
||||
searchable:false,
|
||||
render: function(data, type, full, meta) {
|
||||
let html = '';
|
||||
switch(full.device.supplyChainValidationStatus){
|
||||
case "PASS":
|
||||
html= '<img src="${passIcon}" title="${passText}">';
|
||||
break;
|
||||
case "FAIL":
|
||||
html = '<img src="${failIcon}" title="${failText}"/>';
|
||||
break;
|
||||
case "ERROR":
|
||||
html = '<img src="${errorIcon}" title="${errorText}">';
|
||||
break;
|
||||
default:
|
||||
html = '<img src="${unknownIcon}" title="${unknownText}">';
|
||||
break;
|
||||
}
|
||||
return html;
|
||||
}
|
||||
},
|
||||
{
|
||||
data: 'name',
|
||||
render: function (data, type, full, meta) {
|
||||
return full.device.name;
|
||||
}
|
||||
},
|
||||
{
|
||||
data: 'id',
|
||||
orderable: false,
|
||||
searchable:false,
|
||||
render: function (data, type, full, meta) {
|
||||
//Display issued attestation certificate
|
||||
if(full.IssuedAttestationCertificate === undefined) return '';
|
||||
let size = full.IssuedAttestationCertificate.length;
|
||||
let html = '';
|
||||
for (let i = 0; i < size; i++) {
|
||||
let id = full.IssuedAttestationCertificate[i].id;
|
||||
html += certificateDetailsLink("issued", id, false);
|
||||
}
|
||||
|
||||
for(let i = 0; i < size; i++) {
|
||||
let id = full.IssuedAttestationCertificate[i].id;
|
||||
html += certificateDetailsLink('issued', id, false);
|
||||
}
|
||||
return html;
|
||||
},
|
||||
},
|
||||
{
|
||||
data: "id",
|
||||
orderable: false,
|
||||
searchable: false,
|
||||
render: function (data, type, full, meta) {
|
||||
//Display platform credential
|
||||
if (full.PlatformCredential === undefined) return "";
|
||||
let size = full.PlatformCredential.length;
|
||||
let html = "";
|
||||
|
||||
return html;
|
||||
}
|
||||
},
|
||||
{
|
||||
data: 'id',
|
||||
orderable: false,
|
||||
searchable:false,
|
||||
render: function (data, type, full, meta) {
|
||||
//Display platform credential
|
||||
if(full.PlatformCredential === undefined) return '';
|
||||
let size = full.PlatformCredential.length;
|
||||
let html = '';
|
||||
for (let i = 0; i < size; i++) {
|
||||
let id = full.PlatformCredential[i].id;
|
||||
html +=
|
||||
certificateDetailsLink("platform", id, false) + " ";
|
||||
}
|
||||
|
||||
for(let i = 0; i < size; i++) {
|
||||
let id = full.PlatformCredential[i].id;
|
||||
html += certificateDetailsLink('platform', id, false) + ' ';
|
||||
}
|
||||
return html;
|
||||
},
|
||||
},
|
||||
{
|
||||
data: "id",
|
||||
orderable: false,
|
||||
searchable: false,
|
||||
render: function (data, type, full, meta) {
|
||||
//Display endorsement credential
|
||||
if (full.EndorsementCredential === undefined) return "";
|
||||
let size = full.EndorsementCredential.length;
|
||||
let html = "";
|
||||
|
||||
return html;
|
||||
}
|
||||
},
|
||||
{
|
||||
data: 'id',
|
||||
orderable: false,
|
||||
searchable:false,
|
||||
render: function (data, type, full, meta) {
|
||||
//Display endorsement credential
|
||||
if(full.EndorsementCredential === undefined) return '';
|
||||
let size = full.EndorsementCredential.length;
|
||||
let html = '';
|
||||
for (let i = 0; i < size; i++) {
|
||||
let id = full.EndorsementCredential[i].id;
|
||||
html +=
|
||||
certificateDetailsLink("endorsement", id, false) + " ";
|
||||
}
|
||||
|
||||
for(let i = 0; i < size; i++) {
|
||||
let id = full.EndorsementCredential[i].id;
|
||||
html += certificateDetailsLink('endorsement', id, false) +' ';
|
||||
}
|
||||
|
||||
return html;
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
//Set data tables
|
||||
setDataTables("#deviceTable", url, columns);
|
||||
});
|
||||
</script>
|
||||
</jsp:body>
|
||||
return html;
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
//Set data tables
|
||||
setDataTables("#deviceTable", url, columns);
|
||||
});
|
||||
</script>
|
||||
</jsp:body>
|
||||
</my:page>
|
||||
|
@ -1,4 +1,4 @@
|
||||
<%@page contentType="text/html" pageEncoding="UTF-8"%>
|
||||
<!-- <%@page contentType="text/html" pageEncoding="UTF-8"%>
|
||||
|
||||
<%-- JSP TAGS --%>
|
||||
<%@taglib prefix="c" uri="jakarta.tags.core" %>
|
||||
@ -6,8 +6,7 @@
|
||||
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
|
||||
<%@taglib prefix="my" tagdir="/WEB-INF/tags"%>
|
||||
|
||||
<%-- CONTENT --%>
|
||||
|
||||
<%-- CONTENT --%> -->
|
||||
<my:page>
|
||||
<jsp:attribute name="script">
|
||||
<script
|
||||
@ -34,9 +33,9 @@
|
||||
<input id="importFile" type="file" name="file" multiple="multiple" />
|
||||
</my:file-chooser>
|
||||
<a
|
||||
href="${portal}/certificate-request/endorsement-key-credentials/bulk"
|
||||
href="${portal}/certificate-request/endorsement-key-credentials/bulk-download"
|
||||
>
|
||||
<img src="${icons}/ic_file_download_black_24dp.png" title="Download All Endorsement Certificates">
|
||||
<!-- <img src="${icons}/ic_file_download_black_24dp.png" title="Download All Endorsement Certificates"> -->
|
||||
</a>
|
||||
</form:form>
|
||||
</div>
|
||||
@ -63,6 +62,7 @@
|
||||
let url = pagePath + "/list";
|
||||
let columns = [
|
||||
{
|
||||
name: "deviceName",
|
||||
data: "deviceName",
|
||||
searchable: true,
|
||||
orderable: true,
|
||||
@ -71,12 +71,28 @@
|
||||
return full.deviceName;
|
||||
},
|
||||
},
|
||||
{ data: "issuer", searchable: true, orderable: true },
|
||||
{ data: "credentialType", searchable: true, orderable: true },
|
||||
{ data: "manufacturer", searchable: true, orderable: true },
|
||||
{ data: "model", searchable: true, orderable: true },
|
||||
{ data: "version", searchable: true, orderable: true },
|
||||
{ name: "issuer", data: "issuer", searchable: true, orderable: true },
|
||||
{
|
||||
name: "credentialType",
|
||||
data: "credentialType",
|
||||
searchable: true,
|
||||
orderable: true,
|
||||
},
|
||||
{
|
||||
name: "manufacturer",
|
||||
data: "manufacturer",
|
||||
searchable: true,
|
||||
orderable: true,
|
||||
},
|
||||
{ name: "model", data: "model", searchable: true, orderable: true },
|
||||
{
|
||||
name: "version",
|
||||
data: "version",
|
||||
searchable: true,
|
||||
orderable: true,
|
||||
},
|
||||
{
|
||||
name: "beginValidity",
|
||||
data: "beginValidity",
|
||||
searchable: false,
|
||||
render: function (data, type, full, meta) {
|
||||
@ -84,6 +100,7 @@
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "endValidity",
|
||||
data: "endValidity",
|
||||
searchable: false,
|
||||
render: function (data, type, full, meta) {
|
||||
|
@ -8,78 +8,98 @@
|
||||
|
||||
<%-- CONTENT --%>
|
||||
<my:page>
|
||||
<jsp:attribute name="script">
|
||||
<script
|
||||
type="text/javascript"
|
||||
src="${lib}/jquery.spring-friendly/jquery.spring-friendly.js"
|
||||
></script>
|
||||
</jsp:attribute>
|
||||
<jsp:attribute name="pageHeaderTitle">IDevID Certificates</jsp:attribute>
|
||||
|
||||
<jsp:attribute name="script">
|
||||
<script type="text/javascript" src="${lib}/jquery.spring-friendly/jquery.spring-friendly.js"></script>
|
||||
</jsp:attribute>
|
||||
<jsp:attribute name="pageHeaderTitle">IDevID Certificates</jsp:attribute>
|
||||
<jsp:body>
|
||||
<div class="aca-input-box-header">
|
||||
<form:form
|
||||
method="POST"
|
||||
action="${portal}/certificate-request/idevid-certificates/upload"
|
||||
enctype="multipart/form-data"
|
||||
>
|
||||
Import IDevID Certificates
|
||||
<my:file-chooser id="idevid-editor" label="Import IDevID Certificates">
|
||||
<input id="importFile" type="file" name="file" multiple="multiple" />
|
||||
</my:file-chooser>
|
||||
<a href="${portal}/certificate-request/idevid-certificates/bulk-download">
|
||||
<img src="${icons}/ic_file_download_black_24dp.png" title="Download All IDevID Certificates">
|
||||
</a>
|
||||
</form:form>
|
||||
</div>
|
||||
<br />
|
||||
<div class="aca-data-table">
|
||||
<table id="idevidCertificateTable" class="display" width="100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Issuer</th>
|
||||
<th>Subject</th>
|
||||
<th>Valid (begin)</th>
|
||||
<th>Valid (end)</th>
|
||||
<th>Options</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
</div>
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
let url = pagePath + "/list";
|
||||
let columns = [
|
||||
{
|
||||
name: "issuer",
|
||||
data: "issuer",
|
||||
orderable: true,
|
||||
searchable: true,
|
||||
},
|
||||
{
|
||||
name: "subject",
|
||||
data: "subject",
|
||||
orderable: true,
|
||||
searchable: true,
|
||||
},
|
||||
{
|
||||
name: "beginValidity",
|
||||
data: "beginValidity",
|
||||
orderable: false,
|
||||
searchable: false,
|
||||
render: function (data, type, full, meta) {
|
||||
return formatCertificateDate(full.beginValidity);
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "endValidity",
|
||||
data: "endValidity",
|
||||
orderable: false,
|
||||
searchable: false,
|
||||
render: function (data, type, full, meta) {
|
||||
return formatCertificateDate(full.endValidity);
|
||||
},
|
||||
},
|
||||
{
|
||||
data: "id",
|
||||
orderable: false,
|
||||
searchable: false,
|
||||
render: function (data, type, full, meta) {
|
||||
// Set up a delete icon with link to handleDeleteRequest().
|
||||
// sets up a hidden input field containing the ID which is
|
||||
// used as a parameter to the REST POST call to delete
|
||||
let html = "";
|
||||
html += certificateDetailsLink("idevid", full.id, true);
|
||||
html += certificateDownloadLink(full.id, pagePath);
|
||||
html += certificateDeleteLink(full.id, pagePath);
|
||||
return html;
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
<jsp:body>
|
||||
<div class="aca-input-box-header">
|
||||
<form:form method="POST" action="${portal}/certificate-request/idevid-certificates/upload" enctype="multipart/form-data">
|
||||
Import IDevID Certificates
|
||||
<my:file-chooser id="idevid-editor" label="Import IDevID Certificates">
|
||||
<input id="importFile" type="file" name="file" multiple="multiple" />
|
||||
</my:file-chooser>
|
||||
<a href="${portal}/certificate-request/idevid-certificates/bulk">
|
||||
<img src="${icons}/ic_file_download_black_24dp.png" title="Download All IDevID Certificates">
|
||||
</a>
|
||||
</form:form>
|
||||
</div>
|
||||
<br/>
|
||||
<div class="aca-data-table">
|
||||
<table id="idevidCertificateTable" class="display" width="100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Issuer</th>
|
||||
<th>Subject</th>
|
||||
<th>Valid (begin)</th>
|
||||
<th>Valid (end)</th>
|
||||
<th>Options</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
</div>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
let url = pagePath +'/list';
|
||||
let columns = [
|
||||
{data: 'issuer'},
|
||||
{data: 'subject'},
|
||||
{
|
||||
data: 'beginValidity',
|
||||
searchable:false,
|
||||
render: function (data, type, full, meta) {
|
||||
return formatCertificateDate(full.beginValidity);
|
||||
}
|
||||
},
|
||||
{
|
||||
data: 'endValidity',
|
||||
searchable:false,
|
||||
render: function (data, type, full, meta) {
|
||||
return formatCertificateDate(full.endValidity);
|
||||
}
|
||||
},
|
||||
{
|
||||
data: 'id',
|
||||
orderable: false,
|
||||
searchable:false,
|
||||
render: function(data, type, full, meta) {
|
||||
// Set up a delete icon with link to handleDeleteRequest().
|
||||
// sets up a hidden input field containing the ID which is
|
||||
// used as a parameter to the REST POST call to delete
|
||||
let html = '';
|
||||
html += certificateDetailsLink('idevid', full.id, true);
|
||||
html += certificateDownloadLink(full.id, pagePath);
|
||||
html += certificateDeleteLink(full.id, pagePath);
|
||||
return html;
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
//Set data tables
|
||||
setDataTables("#idevidCertificateTable", url, columns);
|
||||
});
|
||||
</script>
|
||||
</jsp:body>
|
||||
</my:page>
|
||||
//Set data tables
|
||||
setDataTables("#idevidCertificateTable", url, columns);
|
||||
});
|
||||
</script>
|
||||
</jsp:body>
|
||||
</my:page>
|
||||
|
@ -19,7 +19,7 @@
|
||||
<jsp:body>
|
||||
<div class="aca-input-box-header">
|
||||
Issued Credentials
|
||||
<a href="${portal}/certificate-request/issued-certificates/bulk">
|
||||
<a href="${portal}/certificate-request/issued-certificates/bulk-download">
|
||||
<img src="${icons}/ic_file_download_black_24dp.png" title="Download All Issued Certificates">
|
||||
</a>
|
||||
</div>
|
||||
|
@ -32,7 +32,7 @@
|
||||
>
|
||||
<input id="importFile" type="file" name="file" multiple="multiple" />
|
||||
</my:file-chooser>
|
||||
<a href="${portal}/certificate-request/platform-credentials/bulk">
|
||||
<a href="${portal}/certificate-request/platform-credentials/bulk-download">
|
||||
<img src="${icons}/ic_file_download_black_24dp.png" title="Download All Platform Certificates">
|
||||
</a>
|
||||
</form:form>
|
||||
|
@ -8,71 +8,99 @@
|
||||
|
||||
<%-- CONTENT --%>
|
||||
<my:page>
|
||||
<jsp:attribute name="script">
|
||||
<script
|
||||
type="text/javascript"
|
||||
src="${lib}/jquery.spring-friendly/jquery.spring-friendly.js"
|
||||
></script>
|
||||
</jsp:attribute>
|
||||
<jsp:attribute name="pageHeaderTitle"
|
||||
>Reference Integrity Manifests</jsp:attribute
|
||||
>
|
||||
|
||||
<jsp:attribute name="script">
|
||||
<script type="text/javascript" src="${lib}/jquery.spring-friendly/jquery.spring-friendly.js"></script>
|
||||
</jsp:attribute>
|
||||
<jsp:attribute name="pageHeaderTitle">Reference Integrity Manifests</jsp:attribute>
|
||||
<jsp:body>
|
||||
<!-- text and icon resource variables -->
|
||||
<div class="aca-input-box-header">
|
||||
<form:form
|
||||
method="POST"
|
||||
action="${portal}/reference-manifests/upload"
|
||||
enctype="multipart/form-data"
|
||||
>
|
||||
Reference Integrity Manifests
|
||||
<my:file-chooser id="referenceManifestsEditor" label="Import RIMs">
|
||||
<input id="importFile" type="file" name="file" multiple="multiple" />
|
||||
</my:file-chooser>
|
||||
<a href="${portal}/reference-manifests/bulk-download">
|
||||
<img src="${icons}/ic_file_download_black_24dp.png" title="Download All RIMs">
|
||||
</a>
|
||||
</form:form>
|
||||
</div>
|
||||
<br />
|
||||
<div class="aca-data-table">
|
||||
<table id="referenceManifestTable" class="display" width="100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Tag ID</th>
|
||||
<th>Type</th>
|
||||
<th>Manufacturer</th>
|
||||
<th>Model</th>
|
||||
<th>Version</th>
|
||||
<th>Options</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<jsp:body>
|
||||
<!-- text and icon resource variables -->
|
||||
<div class="aca-input-box-header">
|
||||
<form:form method="POST" action="${portal}/reference-manifests/upload" enctype="multipart/form-data">
|
||||
Reference Integrity Manifests
|
||||
<my:file-chooser id="referenceManifestsEditor" label="Import RIMs">
|
||||
<input id="importFile" type="file" name="file" multiple="multiple" />
|
||||
</my:file-chooser>
|
||||
<a href="${portal}/reference-manifests/bulk">
|
||||
<img src="${icons}/ic_file_download_black_24dp.png" title="Download All RIMs">
|
||||
</a>
|
||||
</form:form>
|
||||
</div>
|
||||
<br/>
|
||||
<div class="aca-data-table">
|
||||
<table id="referenceManifestTable" class="display" width="100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Tag ID</th>
|
||||
<th>Type</th>
|
||||
<th>Manufacturer</th>
|
||||
<th>Model</th>
|
||||
<th>Version</th>
|
||||
<th>Options</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
</div>
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
let url = pagePath + "/list";
|
||||
let columns = [
|
||||
{ name: "tagId", data: "tagId", orderable: true, searchable: true },
|
||||
{
|
||||
name: "rimType",
|
||||
data: "rimType",
|
||||
orderable: true,
|
||||
searchable: true,
|
||||
},
|
||||
{
|
||||
name: "platformManufacturer",
|
||||
data: "platformManufacturer",
|
||||
orderable: true,
|
||||
searchable: true,
|
||||
},
|
||||
{
|
||||
name: "platformModel",
|
||||
data: "platformModel",
|
||||
orderable: true,
|
||||
searchable: true,
|
||||
},
|
||||
{
|
||||
name: "swidTagVersion",
|
||||
data: "swidTagVersion",
|
||||
orderable: true,
|
||||
searchable: true,
|
||||
},
|
||||
{
|
||||
data: "id",
|
||||
orderable: false,
|
||||
searchable: false,
|
||||
render: function (data, type, full, meta) {
|
||||
// Set up a delete icon with link to handleDeleteRequest().
|
||||
// sets up a hidden input field containing the ID which is
|
||||
// used as a parameter to the REST POST call to delete
|
||||
let html = "";
|
||||
html += rimDetailsLink(full.id);
|
||||
html += rimDownloadLink(full.id, pagePath);
|
||||
html += rimDeleteLink(full.id, pagePath);
|
||||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
let url = pagePath +'/list';
|
||||
let columns = [
|
||||
{data: 'tagId'},
|
||||
{data: 'rimType'},
|
||||
{data: 'platformManufacturer'},
|
||||
{data: 'platformModel'},
|
||||
{data: 'swidTagVersion'},
|
||||
{
|
||||
data: 'id',
|
||||
orderable: false,
|
||||
searchable: false,
|
||||
render: function(data, type, full, meta) {
|
||||
// Set up a delete icon with link to handleDeleteRequest().
|
||||
// sets up a hidden input field containing the ID which is
|
||||
// used as a parameter to the REST POST call to delete
|
||||
let html = '';
|
||||
html += rimDetailsLink(full.id);
|
||||
html += rimDownloadLink(full.id, pagePath);
|
||||
html += rimDeleteLink(full.id, pagePath);
|
||||
return html;
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
return html;
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
//Set data tables
|
||||
setDataTables("#referenceManifestTable", url, columns);
|
||||
});
|
||||
</script>
|
||||
</jsp:body>
|
||||
</my:page>
|
||||
//Set data tables
|
||||
setDataTables("#referenceManifestTable", url, columns);
|
||||
});
|
||||
</script>
|
||||
</jsp:body>
|
||||
</my:page>
|
||||
|
@ -1,4 +1,4 @@
|
||||
<%@page contentType="text/html" pageEncoding="UTF-8"%>
|
||||
<!-- <%@page contentType="text/html" pageEncoding="UTF-8"%>
|
||||
|
||||
<%-- JSP TAGS --%>
|
||||
<%@taglib prefix="c" uri="jakarta.tags.core" %>
|
||||
@ -6,70 +6,86 @@
|
||||
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
|
||||
<%@taglib prefix="my" tagdir="/WEB-INF/tags"%>
|
||||
|
||||
<%-- CONTENT --%>
|
||||
<%-- CONTENT --%> -->
|
||||
<my:page>
|
||||
<jsp:attribute name="script">
|
||||
<script
|
||||
type="text/javascript"
|
||||
src="${lib}/jquery.spring-friendly/jquery.spring-friendly.js"
|
||||
></script>
|
||||
</jsp:attribute>
|
||||
<jsp:attribute name="pageHeaderTitle">RIM Database</jsp:attribute>
|
||||
|
||||
<jsp:attribute name="script">
|
||||
<script type="text/javascript" src="${lib}/jquery.spring-friendly/jquery.spring-friendly.js"></script>
|
||||
</jsp:attribute>
|
||||
<jsp:attribute name="pageHeaderTitle">RIM Database</jsp:attribute>
|
||||
<jsp:body>
|
||||
<br />
|
||||
<div class="aca-data-table">
|
||||
<table id="digestValueTable" class="display" width="100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Manufacturer</th>
|
||||
<th>Model</th>
|
||||
<th>Event Type</th>
|
||||
<th>PCR Index</th>
|
||||
<th>Digest Value</th>
|
||||
<th>Base RIM</th>
|
||||
<th>Support RIM</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<jsp:body>
|
||||
<br/>
|
||||
<div class="aca-data-table">
|
||||
<table id="digestValueTable" class="display" width="100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Manufacturer</th>
|
||||
<th>Model</th>
|
||||
<th>Event Type</th>
|
||||
<th>PCR Index</th>
|
||||
<th>Digest Value</th>
|
||||
<th>Base RIM</th>
|
||||
<th>Support RIM</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
</div>
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
let url = pagePath + "/list";
|
||||
let columns = [
|
||||
{
|
||||
name: "manufacturer",
|
||||
data: "manufacturer",
|
||||
orderable: true,
|
||||
searchable: true,
|
||||
},
|
||||
{ name: "model", data: "model", orderable: false, searchable: true },
|
||||
{
|
||||
name: "eventType",
|
||||
data: "eventType",
|
||||
orderable: false,
|
||||
searchable: true,
|
||||
},
|
||||
{
|
||||
name: "pcrIndex",
|
||||
data: "pcrIndex",
|
||||
orderable: true,
|
||||
searchable: true,
|
||||
},
|
||||
{
|
||||
name: "digestValue",
|
||||
data: "digestValue",
|
||||
orderable: false,
|
||||
searchable: true,
|
||||
},
|
||||
{
|
||||
name: "baseRimId",
|
||||
data: "baseRimId",
|
||||
orderable: false,
|
||||
searchable: true,
|
||||
render: function (data, type, full, meta) {
|
||||
return rimDetailsLink(full.baseRimId);
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "supportRimId",
|
||||
data: "supportRimId",
|
||||
orderable: false,
|
||||
searchable: true,
|
||||
render: function (data, type, full, meta) {
|
||||
return rimDetailsLink(full.supportRimId);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
let url = pagePath +'/list';
|
||||
let columns = [
|
||||
{data: 'manufacturer',
|
||||
orderable: true,
|
||||
searchable:false},
|
||||
{data: 'model',
|
||||
orderable: false,
|
||||
searchable:false},
|
||||
{data: 'eventType',
|
||||
orderable: false,
|
||||
searchable:false,},
|
||||
{data: 'pcrIndex',
|
||||
orderable: true,
|
||||
searchable:false},
|
||||
{data: 'digestValue',
|
||||
orderable: false,
|
||||
searchable:false},
|
||||
{data: 'baseRimId',
|
||||
orderable: false,
|
||||
searchable: false,
|
||||
render: function(data, type, full, meta) {
|
||||
return rimDetailsLink(full.baseRimId);
|
||||
}
|
||||
},
|
||||
{data: 'supportRimId',
|
||||
orderable: false,
|
||||
searchable: false,
|
||||
render: function(data, type, full, meta) {
|
||||
return rimDetailsLink(full.supportRimId);
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
//Set data tables
|
||||
setDataTables("#digestValueTable", url, columns);
|
||||
});
|
||||
</script>
|
||||
</jsp:body>
|
||||
</my:page>
|
||||
//Set data tables
|
||||
setDataTables("#digestValueTable", url, columns);
|
||||
});
|
||||
</script>
|
||||
</jsp:body>
|
||||
</my:page>
|
||||
|
@ -1,4 +1,4 @@
|
||||
<%@page contentType="text/html" pageEncoding="UTF-8"%>
|
||||
<!-- <%@page contentType="text/html" pageEncoding="UTF-8"%>
|
||||
|
||||
<%-- JSP TAGS --%>
|
||||
<%@taglib prefix="c" uri="jakarta.tags.core" %>
|
||||
@ -6,7 +6,7 @@
|
||||
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
|
||||
<%@taglib prefix="my" tagdir="/WEB-INF/tags"%>
|
||||
|
||||
<%-- CONTENT --%>
|
||||
<%-- CONTENT --%> -->
|
||||
<my:page>
|
||||
<jsp:attribute name="script">
|
||||
<script
|
||||
@ -87,7 +87,7 @@
|
||||
</my:details-viewer>
|
||||
|
||||
<a href="${portal}/certificate-request/trust-chain/download-aca-cert">
|
||||
<img src="${baseURL}/images/icons/ic_file_download_black_24dp.png" title="Download ACA Certificate">
|
||||
<!-- <img src="${baseURL}/images/icons/ic_file_download_black_24dp.png" title="Download ACA Certificate"> -->
|
||||
</a>
|
||||
<div class="aca-input-box-header">
|
||||
<form:form
|
||||
@ -99,8 +99,8 @@
|
||||
<my:file-chooser id="tc-editor" label="Import Trust Chain Certificates">
|
||||
<input id="importFile" type="file" name="file" multiple="multiple" />
|
||||
</my:file-chooser>
|
||||
<a href="${portal}/certificate-request/trust-chain/bulk">
|
||||
<img src="${icons}/ic_file_download_black_24dp.png" title="Download All Trust Chain Certificates">
|
||||
<a href="${portal}/certificate-request/trust-chain/bulk-download">
|
||||
<!-- <img src="${icons}/ic_file_download_black_24dp.png" title="Download All Trust Chain Certificates"> -->
|
||||
</a>
|
||||
</form:form>
|
||||
</div>
|
||||
@ -119,69 +119,77 @@
|
||||
</table>
|
||||
</div>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
let url = pagePath +'/list';
|
||||
let signature = ${acaCertData.signature};
|
||||
$(document).ready(function () {
|
||||
let url = pagePath + "/list";
|
||||
let acaCertDataSignature = ${acaCertData.signature};
|
||||
|
||||
//Format validity time
|
||||
$("#validity span").each(function(){
|
||||
$(this).text(formatCertificateDate($(this).text()));
|
||||
});
|
||||
//Format validity time
|
||||
$("#validity span").each(function () {
|
||||
$(this).text(formatCertificateDate($(this).text()));
|
||||
});
|
||||
|
||||
//Convert byte array to string
|
||||
$("#signature").html(byteToHexString(signature));
|
||||
//Convert byte array to string
|
||||
$("#signature").html(byteToHexString(acaCertDataSignature));
|
||||
|
||||
<c:if test="${not empty acaCertData.encodedPublicKey}">
|
||||
//Change publick key byte to hex
|
||||
let publicKey = ${acaCertData.encodedPublicKey};
|
||||
$("#encodedPublicKey").html(byteToHexString(publicKey));
|
||||
</c:if>
|
||||
//Change public key byte to hex
|
||||
<c:if test="${not empty acaCertData.encodedPublicKey}">
|
||||
let publicKey = ${acaCertData.encodedPublicKey};
|
||||
$("#encodedPublicKey").html(byteToHexString(publicKey));
|
||||
</c:if>;
|
||||
|
||||
let columns = [
|
||||
{
|
||||
name: "issuer",
|
||||
data: "issuer",
|
||||
orderable: true,
|
||||
searchable: true,
|
||||
},
|
||||
{
|
||||
name: 'subject',
|
||||
data: 'subject'
|
||||
},
|
||||
{
|
||||
name: 'beginValidity',
|
||||
data: 'beginValidity',
|
||||
searchable:false,
|
||||
render: function (data, type, full, meta) {
|
||||
return formatCertificateDate(full.beginValidity);
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'endValidity',
|
||||
data: 'endValidity',
|
||||
searchable:false,
|
||||
render: function (data, type, full, meta) {
|
||||
return formatCertificateDate(full.endValidity);
|
||||
}
|
||||
},
|
||||
{
|
||||
data: 'id',
|
||||
orderable: false,
|
||||
searchable:false,
|
||||
render: function(data, type, full, meta) {
|
||||
// Set up a delete icon with link to handleDeleteRequest().
|
||||
// sets up a hidden input field containing the ID which is
|
||||
// used as a parameter to the REST POST call to delete
|
||||
let html = '';
|
||||
html += certificateDetailsLink('certificateauthority', full.id, true);
|
||||
html += certificateDownloadLink(full.id, pagePath);
|
||||
html += certificateDeleteLink(full.id, pagePath);
|
||||
return html;
|
||||
}
|
||||
}
|
||||
];
|
||||
//Set data tables
|
||||
setDataTables("#trustChainTable", url, columns);
|
||||
let columns = [
|
||||
{
|
||||
name: "issuer",
|
||||
data: "issuer",
|
||||
orderable: true,
|
||||
searchable: true,
|
||||
},
|
||||
{
|
||||
name: "subject",
|
||||
data: "subject",
|
||||
orderable: true,
|
||||
searchable: true,
|
||||
},
|
||||
{
|
||||
name: "beginValidity",
|
||||
data: "beginValidity",
|
||||
orderable: false,
|
||||
searchable: false,
|
||||
render: function (data, type, full, meta) {
|
||||
return formatCertificateDate(full.beginValidity);
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "endValidity",
|
||||
data: "endValidity",
|
||||
orderable: false,
|
||||
searchable: false,
|
||||
render: function (data, type, full, meta) {
|
||||
return formatCertificateDate(full.endValidity);
|
||||
},
|
||||
},
|
||||
{
|
||||
data: "id",
|
||||
orderable: false,
|
||||
searchable: false,
|
||||
render: function (data, type, full, meta) {
|
||||
// Set up a delete icon with link to handleDeleteRequest().
|
||||
// sets up a hidden input field containing the ID which is
|
||||
// used as a parameter to the REST POST call to delete
|
||||
let html = "";
|
||||
html += certificateDetailsLink(
|
||||
"certificateauthority",
|
||||
full.id,
|
||||
true
|
||||
);
|
||||
html += certificateDownloadLink(full.id, pagePath);
|
||||
html += certificateDeleteLink(full.id, pagePath);
|
||||
return html;
|
||||
},
|
||||
},
|
||||
];
|
||||
//Set data tables
|
||||
setDataTables("#trustChainTable", url, columns);
|
||||
});
|
||||
</script>
|
||||
</jsp:body>
|
||||
|
Loading…
x
Reference in New Issue
Block a user