From 1e7580aca362ff58d0661ff0aafa60a2a4c3a94d Mon Sep 17 00:00:00 2001 From: adam-m Date: Tue, 25 Jun 2013 15:59:06 -0400 Subject: [PATCH] Added Report Branding capability. Html report now uses branding to pull current defaults for generator logo and title --- .../autopsy/report/ReportBranding.java | 135 ++++++++++++++++++ .../report/ReportBrandingProviderI.java | 66 +++++++++ .../autopsy/report/ReportGenerator.java | 4 +- .../sleuthkit/autopsy/report/ReportHTML.java | 21 ++- 4 files changed, 218 insertions(+), 8 deletions(-) create mode 100644 Core/src/org/sleuthkit/autopsy/report/ReportBranding.java create mode 100644 Core/src/org/sleuthkit/autopsy/report/ReportBrandingProviderI.java diff --git a/Core/src/org/sleuthkit/autopsy/report/ReportBranding.java b/Core/src/org/sleuthkit/autopsy/report/ReportBranding.java new file mode 100644 index 0000000000..979dc43d45 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/report/ReportBranding.java @@ -0,0 +1,135 @@ + /* + * + * Autopsy Forensic Browser + * + * Copyright 2013 Basis Technology Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.report; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.openide.filesystems.FileUtil; +import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.coreutils.ModuleSettings; + +/** + * Manages settings configured report branding and their defaults. + * + * If configured branding is not present on the machine, uses defaults. + * + * Uses module settings property files to store customizations. + */ +public final class ReportBranding implements ReportBrandingProviderI { + + //property names + private static final String GENERATOR_LOGO_PATH_PROP = "GeneratorLogoPath"; + private static final String AGENCY_LOGO_PATH_PROP = "AgencyLogoPath"; + private static final String REPORT_TITLE_PROP = "ReportTitle"; + //default settings + private static final String DEFAULT_GENERATOR_LOGO = "/org/sleuthkit/autopsy/report/images/logo.png"; + private static final String DEFAULT_REPORT_TITLE = "Autopsy Forensic Report"; + private String reportsBrandingDir; //dir with extracted reports branding resources + private static final String MODULE_NAME = ReportBranding.class.getSimpleName(); + private static final Logger logger = Logger.getLogger(ReportBranding.class.getName()); + + public ReportBranding() { + + //initialize with extracting of resource files if needed, ensure 1 writer at a time + synchronized (ReportBranding.class) { + reportsBrandingDir = Case.getCurrentCase().getCaseDirectory() + File.separator + ReportGenerator.REPORTS_DIR + File.separator + + "branding"; + File brandingDir = new File(reportsBrandingDir); + if (!brandingDir.exists()) { + if (!brandingDir.mkdirs()) { + logger.log(Level.SEVERE, "Error creating report branding dir for the case, will use defaults"); + //TODO use defaults + } + } + getGeneratorLogoPath(); + getAgencyLogoPath(); + getReportTitle(); + } + } + + @Override + public String getGeneratorLogoPath() { + String curPath = null; + try { + curPath = ModuleSettings.getConfigSetting(MODULE_NAME, GENERATOR_LOGO_PATH_PROP); + if (curPath == null || curPath.isEmpty() || new File(curPath).canRead() == false) { + //use default + logger.log(Level.INFO, "Using default report branding for generator logo"); + curPath = reportsBrandingDir + File.separator + "logo.png"; + InputStream in = getClass().getResourceAsStream("/org/sleuthkit/autopsy/report/images/logo.png"); + OutputStream output = new FileOutputStream(new File(curPath)); + FileUtil.copy(in, output); + ModuleSettings.setConfigSetting(MODULE_NAME, GENERATOR_LOGO_PATH_PROP, curPath); + } + } catch (IOException e) { + logger.log(Level.SEVERE, "Error extracting report branding resources for generator logo", e); + } + return curPath; + } + + @Override + public void setGeneratorLogoPath(String path) { + ModuleSettings.setConfigSetting(MODULE_NAME, GENERATOR_LOGO_PATH_PROP, path); + } + + @Override + public String getAgencyLogoPath() { + String curPath = null; + + curPath = ModuleSettings.getConfigSetting(MODULE_NAME, AGENCY_LOGO_PATH_PROP); + //if has been set, validate it's correct, if not set, return null + if (curPath != null && new File(curPath).canRead() == false) { + //use default + logger.log(Level.INFO, "Custom report branding for agency logo is not valid: " + curPath); + curPath = null; + } + + return curPath; + } + + @Override + public void setAgencyLogoPath(String path) { + ModuleSettings.setConfigSetting(MODULE_NAME, AGENCY_LOGO_PATH_PROP, path); + } + + @Override + public String getReportTitle() { + String curTitle = null; + + curTitle = ModuleSettings.getConfigSetting(MODULE_NAME, REPORT_TITLE_PROP); + if (curTitle == null || curTitle.isEmpty()) { + //use default + logger.log(Level.INFO, "Using default report branding for report title"); + curTitle = DEFAULT_REPORT_TITLE; + ModuleSettings.setConfigSetting(MODULE_NAME, REPORT_TITLE_PROP, curTitle); + } + + return curTitle; + } + + @Override + public void setReportTitle(String title) { + ModuleSettings.setConfigSetting(MODULE_NAME, REPORT_TITLE_PROP, title); + } +} diff --git a/Core/src/org/sleuthkit/autopsy/report/ReportBrandingProviderI.java b/Core/src/org/sleuthkit/autopsy/report/ReportBrandingProviderI.java new file mode 100644 index 0000000000..6cc736fe0c --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/report/ReportBrandingProviderI.java @@ -0,0 +1,66 @@ + /* + * + * Autopsy Forensic Browser + * + * Copyright 2013 Basis Technology Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.report; + +/** + * Interface to implement by reports to add on custom branding, logos, etc + */ +public interface ReportBrandingProviderI { + + /** + * Get the generator logo path on the local disk (previously set or default). + * The file pointed by the path should exist. + * + * @return the generator logo path, or null if error occurred and path is not valid + */ + public String getGeneratorLogoPath(); + + /** + * Sets custom generator logo path + * @param path path to set + */ + public void setGeneratorLogoPath(String path); + + /** + * Get the agency logo path on the local disk (previously set or default), or NULL if unused + * (Note, this is optional, as opposed to the generator logo path) + * + * @return the agency logo path, or null if not provided or error occurred and path is not valid + */ + public String getAgencyLogoPath(); + + /** + * Sets custom agency logo path + * @param path path to set + */ + public void setAgencyLogoPath(String path); + + /** + * Get the report title (previously set or default) + * + * @return the report title + */ + public String getReportTitle(); + + /** + * Sets custom report title + * @param title title to set + */ + public void setReportTitle(String title); +} diff --git a/Core/src/org/sleuthkit/autopsy/report/ReportGenerator.java b/Core/src/org/sleuthkit/autopsy/report/ReportGenerator.java index 56c3c7d228..542bf4e2e6 100644 --- a/Core/src/org/sleuthkit/autopsy/report/ReportGenerator.java +++ b/Core/src/org/sleuthkit/autopsy/report/ReportGenerator.java @@ -79,12 +79,14 @@ public class ReportGenerator { private String reportPath; private ReportGenerationPanel panel = new ReportGenerationPanel(); + static final String REPORTS_DIR = "Reports"; + ReportGenerator(Map tableModuleStates, Map generalModuleStates) { // Setup the reporting directory to be [CASE DIRECTORY]/Reports/[Case name] [Timestamp]/ DateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy-HH-mm-ss"); Date date = new Date(); String datenotime = dateFormat.format(date); - this.reportPath = currentCase.getCaseDirectory() + File.separator + "Reports" + File.separator + currentCase.getName() + " " + datenotime + File.separator; + this.reportPath = currentCase.getCaseDirectory() + File.separator + REPORTS_DIR + File.separator + currentCase.getName() + " " + datenotime + File.separator; // Create the reporting directory try { FileUtil.createFolder(new File(this.reportPath)); diff --git a/Core/src/org/sleuthkit/autopsy/report/ReportHTML.java b/Core/src/org/sleuthkit/autopsy/report/ReportHTML.java index 6b40763def..24830b1f51 100644 --- a/Core/src/org/sleuthkit/autopsy/report/ReportHTML.java +++ b/Core/src/org/sleuthkit/autopsy/report/ReportHTML.java @@ -28,6 +28,7 @@ import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.io.FileInputStream; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; @@ -43,9 +44,7 @@ import org.openide.filesystems.FileUtil; import org.openide.util.Exceptions; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.autopsy.coreutils.PlatformUtil; import org.sleuthkit.autopsy.ingest.IngestManager; -import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE; import org.sleuthkit.datamodel.Image; import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.TskCoreException; @@ -62,6 +61,8 @@ public class ReportHTML implements TableReportModule { private Integer rowCount; // number of rows (aka artifacts or tags) for the current data type private Writer out; + private ReportBranding reportBranding; + // Get the default instance of this report public static synchronized ReportHTML getDefault() { if (instance == null) { @@ -72,6 +73,7 @@ public class ReportHTML implements TableReportModule { // Hidden constructor private ReportHTML() { + reportBranding = new ReportBranding(); } // Refesh the member variables @@ -453,12 +455,15 @@ public class ReportHTML implements TableReportModule { InputStream in = null; OutputStream output = null; try { - in = getClass().getResourceAsStream("/org/sleuthkit/autopsy/report/images/favicon.ico"); - output = new FileOutputStream(new File(path + File.separator + "favicon.ico")); + + //pull generator logo from branding, and the remaining resources from the core jar + String generatorLogoPath = reportBranding.getGeneratorLogoPath(); + in = new FileInputStream(generatorLogoPath); + output = new FileOutputStream(new File(path + File.separator + "logo.png")); FileUtil.copy(in, output); - in = getClass().getResourceAsStream("/org/sleuthkit/autopsy/report/images/logo.png"); - output = new FileOutputStream(new File(path + File.separator + "logo.png")); + in = getClass().getResourceAsStream("/org/sleuthkit/autopsy/report/images/favicon.ico"); + output = new FileOutputStream(new File(path + File.separator + "favicon.ico")); FileUtil.copy(in, output); in = getClass().getResourceAsStream("/org/sleuthkit/autopsy/report/images/summary.png"); @@ -577,8 +582,10 @@ public class ReportHTML implements TableReportModule { running = true; } + final String reportTitle = reportBranding.getReportTitle(); + summary.append("
\n"); - summary.append("

Autopsy Forensic Report").append(running ? "Warning, this report was run before ingest services completed!" : "").append("

\n"); + summary.append("

").append(reportTitle).append(running ? "Warning, this report was run before ingest services completed!" : "").append("

\n"); summary.append("

HTML Report Generated on ").append(datetime).append("

\n"); summary.append("
\n"); summary.append("
\n");