mirror of
https://github.com/nsacyber/HIRS.git
synced 2025-04-13 06:03:08 +00:00
v3_issue_811: search feature works pretty well for platform and trust chain management pages. Need to clean up a bit and it should be PR ready manana.
Some checks are pending
Dotnet Provisioner Unit Tests / Restore and Run Unit Tests (ubuntu-20.04) (push) Waiting to run
Dotnet Provisioner Unit Tests / Restore and Run Unit Tests (windows-2022) (push) Waiting to run
Dotnet Provisioner Unit Tests / Evaluate Tests (push) Blocked by required conditions
HIRS Build and Unit Test / ACA_Provisioner_Unit_Tests (push) Waiting to run
HIRS System Tests / DockerTests (push) Waiting to run
Some checks are pending
Dotnet Provisioner Unit Tests / Restore and Run Unit Tests (ubuntu-20.04) (push) Waiting to run
Dotnet Provisioner Unit Tests / Restore and Run Unit Tests (windows-2022) (push) Waiting to run
Dotnet Provisioner Unit Tests / Evaluate Tests (push) Blocked by required conditions
HIRS Build and Unit Test / ACA_Provisioner_Unit_Tests (push) Waiting to run
HIRS System Tests / DockerTests (push) Waiting to run
This commit is contained in:
parent
17802d2b44
commit
aaef31db9d
@ -0,0 +1,76 @@
|
||||
package hirs.attestationca.persist.service;
|
||||
|
||||
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 org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageImpl;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class CertificateService {
|
||||
|
||||
private final EntityManager entityManager;
|
||||
|
||||
@Autowired
|
||||
public CertificateService(EntityManager entityManager) {
|
||||
this.entityManager = entityManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 <T> generic entity class
|
||||
* @return
|
||||
*/
|
||||
public <T> Page<T> findBySearchableColumnsAndArchiveFlag(Class<T> entityClass,
|
||||
List<String> searchableColumns,
|
||||
String searchText,
|
||||
Boolean archiveFlag,
|
||||
Pageable pageable) {
|
||||
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
|
||||
CriteriaQuery<T> query = criteriaBuilder.createQuery(entityClass);
|
||||
Root<T> certificate = query.from(entityClass);
|
||||
|
||||
List<Predicate> predicates = new ArrayList<>();
|
||||
|
||||
// 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
|
||||
for (String columnName : searchableColumns) {
|
||||
Predicate predicate =
|
||||
criteriaBuilder.like(criteriaBuilder.lower(certificate.get(columnName)),
|
||||
"%" + searchText.toLowerCase() + "%");
|
||||
predicates.add(predicate);
|
||||
}
|
||||
}
|
||||
|
||||
Predicate likeConditions = criteriaBuilder.or(predicates.toArray(new Predicate[0]));
|
||||
|
||||
// Add archiveFlag condition if specified
|
||||
query.where(criteriaBuilder.and(likeConditions,
|
||||
criteriaBuilder.equal(certificate.get("archiveFlag"), archiveFlag)));
|
||||
|
||||
// Apply pagination
|
||||
TypedQuery<T> typedQuery = entityManager.createQuery(query);
|
||||
int totalRows = typedQuery.getResultList().size(); // Get the total count for pagination
|
||||
typedQuery.setFirstResult((int) pageable.getOffset());
|
||||
typedQuery.setMaxResults(pageable.getPageSize());
|
||||
|
||||
// Wrap the result in a Page object to return pagination info
|
||||
List<T> resultList = typedQuery.getResultList();
|
||||
return new PageImpl<>(resultList, pageable, totalRows);
|
||||
}
|
||||
}
|
@ -22,18 +22,20 @@ public class Column {
|
||||
/**
|
||||
* Column's data source.
|
||||
*
|
||||
* @see http://datatables.net/reference/option/columns.data
|
||||
* @see https://datatables.net/reference/option/columns.data
|
||||
*/
|
||||
@NotBlank
|
||||
private String data;
|
||||
|
||||
|
||||
/**
|
||||
* Column's name.
|
||||
*
|
||||
* @see https://datatables.net/reference/option/columns.name
|
||||
*/
|
||||
@NotBlank
|
||||
private String name;
|
||||
|
||||
|
||||
/**
|
||||
* Flag to indicate if this column is searchable (true) or not (false).
|
||||
*
|
||||
@ -55,14 +57,4 @@ public class Column {
|
||||
*/
|
||||
@NotNull
|
||||
private Search search;
|
||||
|
||||
/**
|
||||
* Set the search value to apply to this column.
|
||||
*
|
||||
* @param searchValue if any, the search value to apply
|
||||
*/
|
||||
public void setSearchValue(final String searchValue) {
|
||||
this.search.setValue(searchValue);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ public class Search {
|
||||
*/
|
||||
@NotNull
|
||||
private String value = "";
|
||||
|
||||
/**
|
||||
* true if the global filter should be treated as a regular expression for advanced searching,
|
||||
* false otherwise. Note that normally server-side processing scripts will not perform regular
|
||||
|
@ -19,6 +19,7 @@ import hirs.attestationca.persist.entity.userdefined.certificate.IssuedAttestati
|
||||
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;
|
||||
import hirs.attestationca.portal.datatables.DataTableInput;
|
||||
@ -28,10 +29,7 @@ import hirs.attestationca.portal.page.PageController;
|
||||
import hirs.attestationca.portal.page.PageMessages;
|
||||
import hirs.attestationca.portal.page.params.NoPageParams;
|
||||
import hirs.attestationca.portal.page.utils.CertificateStringMapBuilder;
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.criteria.Predicate;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.bouncycastle.util.encoders.DecoderException;
|
||||
@ -39,7 +37,6 @@ 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.data.jpa.domain.Specification;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
@ -62,7 +59,6 @@ import java.security.cert.CertificateEncodingException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
@ -70,6 +66,7 @@ import java.util.LinkedList;
|
||||
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;
|
||||
|
||||
@ -98,8 +95,7 @@ public class CertificatePageController extends PageController<NoPageParams> {
|
||||
private final IssuedCertificateRepository issuedCertificateRepository;
|
||||
private final CACredentialRepository caCredentialRepository;
|
||||
private final IDevIDCertificateRepository iDevIDCertificateRepository;
|
||||
@Autowired(required = false)
|
||||
private EntityManager entityManager;
|
||||
private final CertificateService certificateService;
|
||||
private CertificateAuthorityCredential certificateAuthorityCredential;
|
||||
|
||||
/**
|
||||
@ -122,6 +118,7 @@ public class CertificatePageController extends PageController<NoPageParams> {
|
||||
final IssuedCertificateRepository issuedCertificateRepository,
|
||||
final CACredentialRepository caCredentialRepository,
|
||||
final IDevIDCertificateRepository iDevIDCertificateRepository,
|
||||
final CertificateService certificateService,
|
||||
final X509Certificate acaCertificate) {
|
||||
super(Page.TRUST_CHAIN);
|
||||
this.certificateRepository = certificateRepository;
|
||||
@ -131,6 +128,7 @@ public class CertificatePageController extends PageController<NoPageParams> {
|
||||
this.issuedCertificateRepository = issuedCertificateRepository;
|
||||
this.caCredentialRepository = caCredentialRepository;
|
||||
this.iDevIDCertificateRepository = iDevIDCertificateRepository;
|
||||
this.certificateService = certificateService;
|
||||
|
||||
try {
|
||||
certificateAuthorityCredential
|
||||
@ -237,30 +235,16 @@ public class CertificatePageController extends PageController<NoPageParams> {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
* Helper method that returns a list of column names that are searchable.
|
||||
*
|
||||
* @return searchable column names
|
||||
*/
|
||||
private String buildSearchQuery(@NotNull String searchTerm, List<Column> columns) {
|
||||
private List<String> findSearchableColumnsNames(List<Column> columns) {
|
||||
|
||||
StringBuilder searchQuery = new StringBuilder();
|
||||
|
||||
if (!StringUtils.isBlank(searchTerm)) {
|
||||
// Iterate over columns and add search conditions for the ones that are searchable
|
||||
boolean firstCondition = true;
|
||||
|
||||
for (Column column : columns) {
|
||||
if (column.isSearchable()) {
|
||||
if (!firstCondition) {
|
||||
searchQuery.append(" OR ");
|
||||
}
|
||||
|
||||
searchQuery.append(column.getName()).append(" LIKE '%").append(searchTerm).append("%'");
|
||||
|
||||
firstCondition = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return searchQuery.toString();
|
||||
// grab all the columns that are searchable, then grab all of those columns names and
|
||||
// create a list of those string names
|
||||
return columns.stream().filter(Column::isSearchable).map(Column::getName)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -282,12 +266,14 @@ public class CertificatePageController extends PageController<NoPageParams> {
|
||||
|
||||
// attempt to get the column property based on the order index.
|
||||
String orderColumnName = input.getOrderColumnName();
|
||||
|
||||
log.debug("Ordering on column: {}", orderColumnName);
|
||||
|
||||
//String searchQuery = buildSearchQuery(input.getSearch().getValue(), input.getColumns());
|
||||
String searchText = input.getSearch().getValue();
|
||||
List<String> searchableColumns = findSearchableColumnsNames(input.getColumns());
|
||||
|
||||
int currentPage = input.getStart() / input.getLength();
|
||||
Pageable paging = PageRequest.of(currentPage, input.getLength(), Sort.by(orderColumnName));
|
||||
Pageable pageable = PageRequest.of(currentPage, input.getLength(), Sort.by(orderColumnName));
|
||||
|
||||
// special parsing for platform credential
|
||||
// Add the EndorsementCredential for each PlatformCredential based on the
|
||||
@ -296,30 +282,18 @@ public class CertificatePageController extends PageController<NoPageParams> {
|
||||
case PLATFORMCREDENTIAL -> {
|
||||
FilteredRecordsList<PlatformCredential> records = new FilteredRecordsList<>();
|
||||
|
||||
org.springframework.data.domain.Page<PlatformCredential> pagedResult = null;
|
||||
org.springframework.data.domain.Page<PlatformCredential> pagedResult;
|
||||
|
||||
if (StringUtils.isBlank(input.getSearch().getValue())) {
|
||||
if (StringUtils.isBlank(searchText)) {
|
||||
pagedResult =
|
||||
this.platformCertificateRepository.findByArchiveFlag(false, paging);
|
||||
this.platformCertificateRepository.findByArchiveFlag(false, pageable);
|
||||
} else {
|
||||
|
||||
Specification<PlatformCredential> spec = (root, query, criteriaBuilder) -> {
|
||||
List<Predicate> predicates = new ArrayList<>();
|
||||
|
||||
for (Column column : input.getColumns()) {
|
||||
if (column.isSearchable()) {
|
||||
predicates.add(criteriaBuilder.like(
|
||||
criteriaBuilder.lower(root.get(column.getName())),
|
||||
"%" + column.getSearch().getValue().toLowerCase() + "%"
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
// Combine predicates into a single query (AND all conditions)
|
||||
return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
|
||||
};
|
||||
|
||||
pagedResult = platformCertificateRepository.findAll(spec, paging);
|
||||
pagedResult =
|
||||
this.certificateService.findBySearchableColumnsAndArchiveFlag(
|
||||
PlatformCredential.class,
|
||||
searchableColumns,
|
||||
searchText,
|
||||
false, pageable);
|
||||
}
|
||||
|
||||
if (pagedResult.hasContent()) {
|
||||
@ -353,8 +327,19 @@ public class CertificatePageController extends PageController<NoPageParams> {
|
||||
}
|
||||
case ENDORSEMENTCREDENTIAL -> {
|
||||
FilteredRecordsList<EndorsementCredential> records = new FilteredRecordsList<>();
|
||||
org.springframework.data.domain.Page<EndorsementCredential> pagedResult =
|
||||
this.endorsementCredentialRepository.findByArchiveFlag(false, paging);
|
||||
|
||||
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());
|
||||
@ -370,8 +355,21 @@ public class CertificatePageController extends PageController<NoPageParams> {
|
||||
}
|
||||
case TRUSTCHAIN -> {
|
||||
FilteredRecordsList<CertificateAuthorityCredential> records = new FilteredRecordsList<>();
|
||||
org.springframework.data.domain.Page<CertificateAuthorityCredential> pagedResult =
|
||||
this.caCredentialRepository.findByArchiveFlag(false, paging);
|
||||
|
||||
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());
|
||||
@ -387,8 +385,19 @@ public class CertificatePageController extends PageController<NoPageParams> {
|
||||
}
|
||||
case ISSUEDCERTIFICATES -> {
|
||||
FilteredRecordsList<IssuedAttestationCertificate> records = new FilteredRecordsList<>();
|
||||
org.springframework.data.domain.Page<IssuedAttestationCertificate> pagedResult =
|
||||
this.issuedCertificateRepository.findByArchiveFlag(false, paging);
|
||||
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());
|
||||
@ -403,9 +412,20 @@ public class CertificatePageController extends PageController<NoPageParams> {
|
||||
return new DataTableResponse<>(records, input);
|
||||
}
|
||||
case IDEVIDCERTIFICATE -> {
|
||||
FilteredRecordsList<IDevIDCertificate> records = new FilteredRecordsList<IDevIDCertificate>();
|
||||
org.springframework.data.domain.Page<IDevIDCertificate> pagedResult =
|
||||
this.iDevIDCertificateRepository.findByArchiveFlag(false, paging);
|
||||
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());
|
||||
|
@ -7,94 +7,110 @@
|
||||
<%@taglib prefix="my" tagdir="/WEB-INF/tags"%>
|
||||
|
||||
<%-- 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"
|
||||
>Endorsement Key Credentials</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">Endorsement Key Credentials</jsp:attribute>
|
||||
<jsp:body>
|
||||
<div class="aca-input-box-header">
|
||||
<form:form
|
||||
method="POST"
|
||||
action="${portal}/certificate-request/endorsement-key-credentials/upload"
|
||||
enctype="multipart/form-data"
|
||||
>
|
||||
Import Endorsement Key Credentials
|
||||
<my:file-chooser
|
||||
id="ek-editor"
|
||||
label="Import Endorsement Key Credentials"
|
||||
>
|
||||
<input id="importFile" type="file" name="file" multiple="multiple" />
|
||||
</my:file-chooser>
|
||||
<a
|
||||
href="${portal}/certificate-request/endorsement-key-credentials/bulk"
|
||||
>
|
||||
<img src="${icons}/ic_file_download_black_24dp.png" title="Download All Endorsement Certificates">
|
||||
</a>
|
||||
</form:form>
|
||||
</div>
|
||||
<br />
|
||||
<div class="aca-data-table">
|
||||
<table id="endorsementKeyTable" class="display" width="100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Device</th>
|
||||
<th>Issuer</th>
|
||||
<th>Type</th>
|
||||
<th>Manufacturer</th>
|
||||
<th>Model</th>
|
||||
<th>Version</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: "deviceName",
|
||||
searchable: true,
|
||||
orderable: true,
|
||||
render: function (data, type, full, meta) {
|
||||
// if there's a device, display its name, otherwise
|
||||
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 },
|
||||
{
|
||||
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("endorsement", full.id, true);
|
||||
html += certificateDownloadLink(full.id, pagePath);
|
||||
html += certificateDeleteLink(full.id, pagePath);
|
||||
|
||||
<jsp:body>
|
||||
<div class="aca-input-box-header">
|
||||
<form:form method="POST" action="${portal}/certificate-request/endorsement-key-credentials/upload" enctype="multipart/form-data">
|
||||
Import Endorsement Key Credentials
|
||||
<my:file-chooser id="ek-editor" label="Import Endorsement Key Credentials">
|
||||
<input id="importFile" type="file" name="file" multiple="multiple" />
|
||||
</my:file-chooser>
|
||||
<a href="${portal}/certificate-request/endorsement-key-credentials/bulk">
|
||||
<img src="${icons}/ic_file_download_black_24dp.png" title="Download All Endorsement Certificates">
|
||||
</a>
|
||||
</form:form>
|
||||
</div>
|
||||
<br/>
|
||||
<div class="aca-data-table">
|
||||
<table id="endorsementKeyTable" class="display" width="100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Device</th>
|
||||
<th>Issuer</th>
|
||||
<th>Type</th>
|
||||
<th>Manufacturer</th>
|
||||
<th>Model</th>
|
||||
<th>Version</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: 'deviceName',
|
||||
render: function (data, type, full, meta) {
|
||||
// if there's a device, display its name, otherwise
|
||||
return full.deviceName;
|
||||
}
|
||||
},
|
||||
{data: 'issuer'},
|
||||
{data: 'credentialType'},
|
||||
{data: 'manufacturer'},
|
||||
{data: 'model'},
|
||||
{data: 'version'},
|
||||
{
|
||||
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('endorsement', full.id, true);
|
||||
html += certificateDownloadLink(full.id, pagePath);
|
||||
html += certificateDeleteLink(full.id, pagePath);
|
||||
return html;
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
return html;
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
//Set data tables
|
||||
setDataTables("#endorsementKeyTable", url, columns);
|
||||
});
|
||||
</script>
|
||||
</jsp:body>
|
||||
</my:page>
|
||||
//Set data tables
|
||||
setDataTables("#endorsementKeyTable", url, columns);
|
||||
});
|
||||
</script>
|
||||
</jsp:body>
|
||||
</my:page>
|
||||
|
@ -7,131 +7,153 @@
|
||||
<%@taglib prefix="my" tagdir="/WEB-INF/tags"%>
|
||||
|
||||
<%-- 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">Issued Certificates</jsp:attribute>
|
||||
<jsp:body>
|
||||
<div class="aca-input-box-header">
|
||||
Issued Credentials
|
||||
<a href="${portal}/certificate-request/issued-certificates/bulk">
|
||||
<img src="${icons}/ic_file_download_black_24dp.png" title="Download All Issued Certificates">
|
||||
</a>
|
||||
</div>
|
||||
<br />
|
||||
<div class="aca-data-table">
|
||||
<table id="issuedTable" class="display" width="100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th rowspan="2">Hostname</th>
|
||||
<th rowspan="2">Type</th>
|
||||
<th rowspan="2">Issuer</th>
|
||||
<th rowspan="2">Valid (begin)</th>
|
||||
<th rowspan="2">Valid (end)</th>
|
||||
<th colspan="2">Credentials</th>
|
||||
<th rowspan="2">Options</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Endorsement</th>
|
||||
<th>Platform</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
</div>
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
let url = pagePath + "/list";
|
||||
let columns = [
|
||||
{
|
||||
name: "deviceName",
|
||||
data: "deviceName",
|
||||
searchable: true,
|
||||
orderable: true,
|
||||
render: function (data, type, full, meta) {
|
||||
// if there's a device, display its name, otherwise
|
||||
// display nothing
|
||||
return full.deviceName;
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ldevID",
|
||||
data: "ldevID",
|
||||
searchable: false,
|
||||
orderable: false,
|
||||
render: function (data, type, full, meta) {
|
||||
if (data === true) {
|
||||
return "LDevID";
|
||||
}
|
||||
return "AK";
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "issuer",
|
||||
data: "issuer",
|
||||
searchable: true,
|
||||
orderable: true,
|
||||
},
|
||||
{
|
||||
name: "beginValidity",
|
||||
data: "beginValidity",
|
||||
searchable: false,
|
||||
orderable: true,
|
||||
render: function (data, type, full, meta) {
|
||||
return formatCertificateDate(data);
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "endValidity",
|
||||
data: "endValidity",
|
||||
searchable: false,
|
||||
orderable: true,
|
||||
render: function (data, type, full, meta) {
|
||||
return formatCertificateDate(data);
|
||||
},
|
||||
},
|
||||
{
|
||||
data: "id",
|
||||
orderable: false,
|
||||
searchable: false,
|
||||
render: function (data, type, full, meta) {
|
||||
//Display endorsement credential
|
||||
let html = "";
|
||||
if (
|
||||
full.endorsementCredential !== undefined &&
|
||||
full.endorsementCredential !== null
|
||||
) {
|
||||
let id = full.endorsementCredential.id;
|
||||
html +=
|
||||
certificateDetailsLink("endorsement", id, false) + " ";
|
||||
}
|
||||
return html;
|
||||
},
|
||||
},
|
||||
{
|
||||
data: "id",
|
||||
orderable: false,
|
||||
searchable: false,
|
||||
render: function (data, type, full, meta) {
|
||||
//Display platform credential
|
||||
let html = "";
|
||||
if (
|
||||
full.platformCredentials !== undefined &&
|
||||
full.platformCredentials !== null
|
||||
) {
|
||||
let size = full.platformCredentials.length;
|
||||
|
||||
<jsp:attribute name="script">
|
||||
<script type="text/javascript" src="${lib}/jquery.spring-friendly/jquery.spring-friendly.js"></script>
|
||||
</jsp:attribute>
|
||||
<jsp:attribute name="pageHeaderTitle">Issued Certificates</jsp:attribute>
|
||||
<jsp:body>
|
||||
<div class="aca-input-box-header">
|
||||
Issued Credentials
|
||||
<a href="${portal}/certificate-request/issued-certificates/bulk">
|
||||
<img src="${icons}/ic_file_download_black_24dp.png" title="Download All Issued Certificates">
|
||||
</a>
|
||||
</div>
|
||||
<br />
|
||||
<div class="aca-data-table">
|
||||
<table id="issuedTable" class="display" width="100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th rowspan="2">Hostname</th>
|
||||
<th rowspan="2">Type</th>
|
||||
<th rowspan="2">Issuer</th>
|
||||
<th rowspan="2">Valid (begin)</th>
|
||||
<th rowspan="2">Valid (end)</th>
|
||||
<th colspan="2">Credentials</th>
|
||||
<th rowspan="2">Options</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Endorsement</th>
|
||||
<th>Platform</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
</div>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
let url = pagePath + '/list';
|
||||
let columns = [
|
||||
{
|
||||
data: 'deviceName',
|
||||
render: function (data, type, full, meta) {
|
||||
// if there's a device, display its name, otherwise
|
||||
// display nothing
|
||||
return full.deviceName;
|
||||
}
|
||||
},
|
||||
{
|
||||
data: 'ldevID',
|
||||
searchable:false,
|
||||
render: function (data, type, full, meta) {
|
||||
if (data === true) {
|
||||
return "LDevID";
|
||||
}
|
||||
return "AK";
|
||||
}
|
||||
},
|
||||
{data: 'issuer'},
|
||||
{
|
||||
data: 'beginValidity',
|
||||
searchable:false,
|
||||
render: function (data, type, full, meta) {
|
||||
return formatCertificateDate(data);
|
||||
}
|
||||
},
|
||||
{
|
||||
data: 'endValidity',
|
||||
searchable:false,
|
||||
render: function (data, type, full, meta) {
|
||||
return formatCertificateDate(data);
|
||||
}
|
||||
},
|
||||
{
|
||||
data: 'id',
|
||||
orderable: false,
|
||||
searchable:false,
|
||||
render: function (data, type, full, meta) {
|
||||
//Display endorsement credential
|
||||
let html = '';
|
||||
if (full.endorsementCredential !== undefined
|
||||
&& full.endorsementCredential !== null){
|
||||
let id = full.endorsementCredential.id;
|
||||
html += certificateDetailsLink('endorsement', id, false) +' ';
|
||||
}
|
||||
return html;
|
||||
}
|
||||
},
|
||||
{
|
||||
data: 'id',
|
||||
orderable: false,
|
||||
searchable:false,
|
||||
render: function (data, type, full, meta) {
|
||||
//Display platform credential
|
||||
let html = '';
|
||||
if (full.platformCredentials !== undefined
|
||||
&& full.platformCredentials !== null) {
|
||||
let size = full.platformCredentials.length;
|
||||
for (let i = 0; i < size; i++) {
|
||||
let id = full.platformCredentials[i].id;
|
||||
html +=
|
||||
certificateDetailsLink("platform", id, false) + " ";
|
||||
}
|
||||
}
|
||||
|
||||
for(let i = 0; i < size; i++) {
|
||||
let id = full.platformCredentials[i].id;
|
||||
html += certificateDetailsLink('platform', id, false) +' ';
|
||||
}
|
||||
}
|
||||
return html;
|
||||
},
|
||||
},
|
||||
{
|
||||
data: "id",
|
||||
orderable: false,
|
||||
searchable: false,
|
||||
render: function (data, type, full, meta) {
|
||||
// set up link to details page
|
||||
let html = "";
|
||||
html += certificateDetailsLink("issued", full.id, true);
|
||||
html += certificateDownloadLink(full.id, pagePath);
|
||||
html += certificateDeleteLink(full.id, pagePath);
|
||||
|
||||
return html;
|
||||
}
|
||||
},
|
||||
{
|
||||
data: 'id',
|
||||
orderable: false,
|
||||
searchable:false,
|
||||
render: function(data, type, full, meta) {
|
||||
// set up link to details page
|
||||
let html = '';
|
||||
html += certificateDetailsLink('issued', full.id, true);
|
||||
html += certificateDownloadLink(full.id, pagePath);
|
||||
html += certificateDeleteLink(full.id, pagePath);
|
||||
|
||||
return html;
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
//Set data tables
|
||||
setDataTables("#issuedTable", url, columns);
|
||||
});
|
||||
</script>
|
||||
</jsp:body>
|
||||
return html;
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
//Set data tables
|
||||
setDataTables("#issuedTable", url, columns);
|
||||
});
|
||||
</script>
|
||||
</jsp:body>
|
||||
</my:page>
|
||||
|
@ -8,148 +8,181 @@
|
||||
|
||||
<%-- 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">Trust Chain Management</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">Trust Chain Management</jsp:attribute>
|
||||
|
||||
<jsp:body>
|
||||
<span class="aca-input-box-header">
|
||||
HIRS Attestation CA Certificate
|
||||
</span>
|
||||
<my:details-viewer id="aca-cert-viewer" label="HIRS Attestation CA Certificate">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-2 col-md-offset-1"><span class="colHeader">Issuer</span></div>
|
||||
<div id="issuer" class="col col-md-8">
|
||||
<!-- Display the issuer, and provide a link to the issuer details if provided -->
|
||||
<c:choose>
|
||||
<c:when test="${not empty acaCertData.issuerID}">
|
||||
<a href="${portal}/certificate-details?id=${acaCertData.issuerID}&type=certificateauthority">
|
||||
${acaCertData.issuer}
|
||||
</a>
|
||||
</c:when>
|
||||
<c:otherwise>
|
||||
${acaCertData.issuer}
|
||||
</c:otherwise>
|
||||
</c:choose>
|
||||
</div>
|
||||
</div>
|
||||
<c:if test="${not empty acaCertData.subject}">
|
||||
<div class="row">
|
||||
<div class="col-md-2 col-md-offset-1"><span class="colHeader">Subject</span></div>
|
||||
<div id="subject" class="col col-md-8">${acaCertData.subject}</div>
|
||||
</div>
|
||||
</c:if>
|
||||
<div class="row">
|
||||
<div class="col-md-2 col-md-offset-1"><span class="colHeader">Serial Number</span></div>
|
||||
<div id="serialNumber" class="col col-md-8">${acaCertData.serialNumber}</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-2 col-md-offset-1"><span class="colHeader">Validity</span></div>
|
||||
<div id="validity" class="col col-md-8">
|
||||
<div>Not Before: <span>${acaCertData.beginValidity}</span></div>
|
||||
<div>Not After: <span>${acaCertData.endValidity}</span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-2 col-md-offset-1"><span class="colHeader">Signature</span></div>
|
||||
<div id="signature" class="col col-md-8"></div>
|
||||
</div>
|
||||
<c:if test="${not empty acaCertData.encodedPublicKey}">
|
||||
<div class="row">
|
||||
<div class="col-md-2 col-md-offset-1"><span class="colHeader">Public Key</span></div>
|
||||
<div id="encodedPublicKey" class="col col-md-8"></div>
|
||||
</div>
|
||||
</c:if>
|
||||
<div class="spacer"></div>
|
||||
</div>
|
||||
</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">
|
||||
</a>
|
||||
<div class="aca-input-box-header">
|
||||
<form:form method="POST" action="${portal}/certificate-request/trust-chain/upload" enctype="multipart/form-data">
|
||||
Trust Chain CA Certificates
|
||||
<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">
|
||||
<jsp:body>
|
||||
<span class="aca-input-box-header"> HIRS Attestation CA Certificate </span>
|
||||
<my:details-viewer
|
||||
id="aca-cert-viewer"
|
||||
label="HIRS Attestation CA Certificate"
|
||||
>
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-2 col-md-offset-1">
|
||||
<span class="colHeader">Issuer</span>
|
||||
</div>
|
||||
<div id="issuer" class="col col-md-8">
|
||||
<!-- Display the issuer, and provide a link to the issuer details if provided -->
|
||||
<c:choose>
|
||||
<c:when test="${not empty acaCertData.issuerID}">
|
||||
<a
|
||||
href="${portal}/certificate-details?id=${acaCertData.issuerID}&type=certificateauthority"
|
||||
>
|
||||
${acaCertData.issuer}
|
||||
</a>
|
||||
</form:form>
|
||||
</c:when>
|
||||
<c:otherwise> ${acaCertData.issuer} </c:otherwise>
|
||||
</c:choose>
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
<div class="aca-data-table">
|
||||
<table id="trustChainTable" 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>
|
||||
<c:if test="${not empty acaCertData.subject}">
|
||||
<div class="row">
|
||||
<div class="col-md-2 col-md-offset-1">
|
||||
<span class="colHeader">Subject</span>
|
||||
</div>
|
||||
<div id="subject" class="col col-md-8">${acaCertData.subject}</div>
|
||||
</div>
|
||||
</c:if>
|
||||
<div class="row">
|
||||
<div class="col-md-2 col-md-offset-1">
|
||||
<span class="colHeader">Serial Number</span>
|
||||
</div>
|
||||
<div id="serialNumber" class="col col-md-8">
|
||||
${acaCertData.serialNumber}
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
let url = pagePath +'/list';
|
||||
let signature = ${acaCertData.signature};
|
||||
<div class="row">
|
||||
<div class="col-md-2 col-md-offset-1">
|
||||
<span class="colHeader">Validity</span>
|
||||
</div>
|
||||
<div id="validity" class="col col-md-8">
|
||||
<div>
|
||||
Not Before: <span>${acaCertData.beginValidity}</span>
|
||||
</div>
|
||||
<div>Not After: <span>${acaCertData.endValidity}</span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-2 col-md-offset-1">
|
||||
<span class="colHeader">Signature</span>
|
||||
</div>
|
||||
<div id="signature" class="col col-md-8"></div>
|
||||
</div>
|
||||
<c:if test="${not empty acaCertData.encodedPublicKey}">
|
||||
<div class="row">
|
||||
<div class="col-md-2 col-md-offset-1">
|
||||
<span class="colHeader">Public Key</span>
|
||||
</div>
|
||||
<div id="encodedPublicKey" class="col col-md-8"></div>
|
||||
</div>
|
||||
</c:if>
|
||||
<div class="spacer"></div>
|
||||
</div>
|
||||
</my:details-viewer>
|
||||
|
||||
//Format validity time
|
||||
$("#validity span").each(function(){
|
||||
$(this).text(formatCertificateDate($(this).text()));
|
||||
});
|
||||
<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">
|
||||
</a>
|
||||
<div class="aca-input-box-header">
|
||||
<form:form
|
||||
method="POST"
|
||||
action="${portal}/certificate-request/trust-chain/upload"
|
||||
enctype="multipart/form-data"
|
||||
>
|
||||
Trust Chain CA Certificates
|
||||
<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>
|
||||
</form:form>
|
||||
</div>
|
||||
<br />
|
||||
<div class="aca-data-table">
|
||||
<table id="trustChainTable" 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 signature = ${acaCertData.signature};
|
||||
|
||||
//Convert byte array to string
|
||||
$("#signature").html(byteToHexString(signature));
|
||||
//Format validity time
|
||||
$("#validity span").each(function(){
|
||||
$(this).text(formatCertificateDate($(this).text()));
|
||||
});
|
||||
|
||||
<c:if test="${not empty acaCertData.encodedPublicKey}">
|
||||
//Change publick key byte to hex
|
||||
let publicKey = ${acaCertData.encodedPublicKey};
|
||||
$("#encodedPublicKey").html(byteToHexString(publicKey));
|
||||
</c:if>
|
||||
//Convert byte array to string
|
||||
$("#signature").html(byteToHexString(signature));
|
||||
|
||||
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('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>
|
||||
<c:if test="${not empty acaCertData.encodedPublicKey}">
|
||||
//Change publick key byte to hex
|
||||
let publicKey = ${acaCertData.encodedPublicKey};
|
||||
$("#encodedPublicKey").html(byteToHexString(publicKey));
|
||||
</c:if>
|
||||
|
||||
</my:page>
|
||||
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);
|
||||
});
|
||||
</script>
|
||||
</jsp:body>
|
||||
</my:page>
|
||||
|
Loading…
x
Reference in New Issue
Block a user