From 59dff64af48cdc870281736e1c0625ebbf077f0e Mon Sep 17 00:00:00 2001 From: chubtub <43381989+chubtub@users.noreply.github.com> Date: Wed, 19 May 2021 17:48:10 -0400 Subject: [PATCH] Support for -j|--json option to output validation report data in JSON format. Add shorthand options for script parameters and update help menu. --- .../ValidationReportsPageController.java | 142 +++++++++++++----- scripts/download_validation_reports.sh | 41 +++-- 2 files changed, 129 insertions(+), 54 deletions(-) diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ValidationReportsPageController.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ValidationReportsPageController.java index 8883d6a7..b984d260 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ValidationReportsPageController.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/page/controllers/ValidationReportsPageController.java @@ -1,18 +1,23 @@ package hirs.attestationca.portal.page.controllers; +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import hirs.FilteredRecordsList; import hirs.attestationca.portal.datatables.DataTableInput; import hirs.attestationca.portal.datatables.DataTableResponse; import hirs.attestationca.portal.datatables.OrderedListQueryDataTableAdapter; import hirs.attestationca.portal.page.PageController; import hirs.attestationca.portal.page.params.NoPageParams; +import hirs.data.persist.SupplyChainValidationSummary; import hirs.data.persist.certificate.Certificate; import hirs.data.persist.certificate.PlatformCredential; import hirs.data.persist.certificate.attributes.ComponentIdentifier; import hirs.data.persist.certificate.attributes.V2.ComponentIdentifierV2; import hirs.persist.CertificateManager; +import hirs.persist.CriteriaModifier; +import hirs.persist.CrudManager; import hirs.persist.DeviceManager; import org.apache.logging.log4j.Logger; -import static org.apache.logging.log4j.LogManager.getLogger; import org.hibernate.Criteria; import org.hibernate.criterion.Restrictions; import org.springframework.beans.factory.annotation.Autowired; @@ -24,12 +29,6 @@ import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.servlet.ModelAndView; -import static hirs.attestationca.portal.page.Page.VALIDATION_REPORTS; -import hirs.FilteredRecordsList; -import hirs.data.persist.SupplyChainValidationSummary; -import hirs.persist.CriteriaModifier; -import hirs.persist.CrudManager; - import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.BufferedWriter; @@ -47,6 +46,9 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; +import static hirs.attestationca.portal.page.Page.VALIDATION_REPORTS; +import static org.apache.logging.log4j.LogManager.getLogger; + /** * Controller for the Validation Reports page. */ @@ -141,7 +143,7 @@ public class ValidationReportsPageController extends PageController> parsedComponents = parseComponents(pc); - for (ArrayList component : parsedComponents) { - for (String data : component) { - reportData.append(data + ","); + if (systemOnly && componentOnly) { + systemOnly = false; + componentOnly = false; + } + if ((filterManufacturer.isEmpty() || filterManufacturer.equals( + pc.getManufacturer())) + && (filterSerial.isEmpty() || filterSerial.equals( + pc.getPlatformSerial()))) { + if (!componentOnly) { + reportData.append(pc.getManufacturer() + "," + + pc.getModel() + "," + + pc.getPlatformSerial() + "," + + LocalDateTime.now().toString() + "," + + pc.getDevice().getSupplyChainStatus() + ","); + } + if (!systemOnly) { + ArrayList> parsedComponents = parseComponents(pc); + for (ArrayList component : parsedComponents) { + for (String data : component) { + reportData.append(data + ","); + } + reportData.deleteCharAt(reportData.length() - 1); + reportData.append("\n"); + if (!componentOnly) { + reportData.append(",,,,,"); + } } - reportData.deleteCharAt(reportData.length() - 1); - reportData.append("\n,,,,,"); } } + reportData.append("\n"); } } } - if (columnHeaders.isEmpty()) { - columnHeaders = systemColumnHeaders + componentColumnHeaders; + if (!jsonVersion) { + if (columnHeaders.isEmpty()) { + columnHeaders = systemColumnHeaders + componentColumnHeaders; + } + bufferedWriter.append(columnHeaders + "\n"); + bufferedWriter.append(reportData.toString()); + } else { + bufferedWriter.append(jsonReportData.toString()); } - bufferedWriter.append(columnHeaders + "\n"); - bufferedWriter.append(reportData.toString() + "\n"); bufferedWriter.flush(); } + /** + * This method builds a JSON object from the system and component data in a + * validation report. + * @param pc the platform credential used to validate. + * @param parsedComponents component data parsed from the platform credential. + * @param company company name. + * @param contractNumber contract number. + * @return the JSON object in String format. + */ + @SuppressWarnings({"checkstyle:magicnumber" }) + private JsonObject assembleJsonContent(final PlatformCredential pc, + final ArrayList> parsedComponents, + final String company, + final String contractNumber) { + JsonObject systemData = new JsonObject(); + + systemData.addProperty("Company", company); + systemData.addProperty("Contract number", contractNumber); + systemData.addProperty("Verified Manufacturer", pc.getManufacturer()); + systemData.addProperty("Model", pc.getModel()); + systemData.addProperty("SN", pc.getPlatformSerial()); + systemData.addProperty("Verification Date", LocalDateTime.now().toString()); + systemData.addProperty("Device Status", pc.getDevice().getSupplyChainStatus().toString()); + + JsonArray components = new JsonArray(); + for (ArrayList componentData : parsedComponents) { + JsonObject component = new JsonObject(); + component.addProperty("Component name", componentData.get(0)); + component.addProperty("Component manufacturer", componentData.get(1)); + component.addProperty("Component model", componentData.get(2)); + component.addProperty("Component SN", componentData.get(3)); + component.addProperty("Issuer", componentData.get(4)); + component.addProperty("Component status", componentData.get(5)); + components.add(component); + } + systemData.add("Components", components); + + return systemData; + } + /** * This method parses the following ComponentIdentifier fields into an ArrayList of ArrayLists. * - ComponentClass diff --git a/scripts/download_validation_reports.sh b/scripts/download_validation_reports.sh index 95fc752e..06d74774 100644 --- a/scripts/download_validation_reports.sh +++ b/scripts/download_validation_reports.sh @@ -15,8 +15,8 @@ else fi #set parameter names and call getopts on inputsi, then parse/assign arguments -SHORTOPTS=m:s:h -LONGOPTS=start-date:,end-date:,ip:,system-only,component-only,manufacturer:,serial:,help +SHORTOPTS=d:e:i:ypm:s:jh +LONGOPTS=start-date:,end-date:,ip:,system-only,component-only,manufacturer:,serial:,json,help PARSED=$(getopt --options=$SHORTOPTS --longoptions=$LONGOPTS --name "$0" -- "$@") if [[ ${PIPESTATUS[0]} -ne 0 ]] then @@ -30,35 +30,37 @@ system= component= manufacturer= serial= +json= -helpText="\n\n\nHELP MENU\n\nThe following options are available:\n--start-date\t\t\tDefault: 1970-01-01\tThe earliest date to return validation reports from.\n" -helpText+="--end-date\t\t\tDefault: current time\tThe latest date to return validation reports from.\n" -helpText+="--ip\t\t\t\tDefault: localhost\tThe IP address where the ACA is located.\n" -helpText+="--system-only\t\t\t\t\t\t\tReturn only system information from validation reports.\n" -helpText+="--component-only\t\t\t\t\t\tReturn only component information from validation reports.\n" +helpText="\n\n\nHELP MENU\n\nThe following options are available:\n-d|--start-date\t\t\tDefault: 1970-01-01\tThe earliest date to return validation reports from.\n" +helpText+="-e|--end-date\t\t\tDefault: current time\tThe latest date to return validation reports from.\n" +helpText+="-i|--ip\t\t\t\tDefault: localhost\tThe IP address where the ACA is located.\n" +helpText+="-y|--system-only\t\t\t\t\t\tReturn only system information from validation reports.\n" +helpText+="-p|--component-only\t\t\t\t\t\tReturn only component information from validation reports.\n" helpText+="-m|--manufacturer\t\t\t\tReturn only the validation report of the device from this manufacturer.\n" helpText+="-s|--serial\t\t\t\t\t\tReturn only the validation report of the device with this serial number.\n" +helpText+="-j|--json\t\t\t\t\t\t\tReturn output in JSON format. Only --start-date, --end-date,\n\t\t\t\t\t\t\t\tand --ip parameters are read with this option, all others are ignored.\n" while true do case "$1" in - --start-date) + -d|--start-date) startDate="$2" shift 2 ;; - --end-date) + -e|--end-date) endDate="$2" shift 2 ;; - --ip) + -i|--ip) ip="$2" shift 2 ;; - --system-only) + -y|--system-only) system=true shift ;; - --component-only) + -p|--component-only) component=true shift ;; @@ -70,6 +72,10 @@ do serial="$2" shift 2 ;; + -j|--json) + json=true + shift + ;; -h|--help) printf "$helpText" exit 0 @@ -85,8 +91,6 @@ do esac done -#echo "start date: $startDate, end date: $endDate, ip: $ip, system: $system, component: $component, manufacturer: $manufacturer, serial: $serial" - #call ACA for validation report endpoint="https://$ip:8443/HIRS_AttestationCAPortal/portal/validation-reports" echo "$endpoint" @@ -103,4 +107,11 @@ deviceNames=$(jq -r '.data | map(.device.name) | join(",")' <<< "$content") echo "Create times: $createTimes" echo "Device names: $deviceNames" -curl --data "dateStart=$startDate&dateEnd=$endDate&createTimes=$createTimes&deviceNames=$deviceNames&system=$system&component=$component&manufacturer=$manufacturer&serial=$serial" --insecure $endpoint/download +curlData="dateStart=$startDate&dateEnd=$endDate&createTimes=$createTimes&deviceNames=$deviceNames" +if [[ "$json" = true ]] +then + curlData+="&json=true" +else + curlData+="&system=$system&component=$component&manufacturer=$manufacturer&serial=$serial" +fi +curl --data "$curlData" --insecure $endpoint/download