Added Report Branding capability.

Html report now uses branding to pull current defaults for generator logo and title
This commit is contained in:
adam-m 2013-06-25 15:59:06 -04:00
parent 3ce116db53
commit 1e7580aca3
4 changed files with 218 additions and 8 deletions

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -79,12 +79,14 @@ public class ReportGenerator {
private String reportPath;
private ReportGenerationPanel panel = new ReportGenerationPanel();
static final String REPORTS_DIR = "Reports";
ReportGenerator(Map<TableReportModule, Boolean> tableModuleStates, Map<GeneralReportModule, Boolean> 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));

View File

@ -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("<div id=\"wrapper\">\n");
summary.append("<h1>Autopsy Forensic Report").append(running ? "<span>Warning, this report was run before ingest services completed!</span>" : "").append("</h1>\n");
summary.append("<h1>").append(reportTitle).append(running ? "<span>Warning, this report was run before ingest services completed!</span>" : "").append("</h1>\n");
summary.append("<p class=\"subheadding\">HTML Report Generated on ").append(datetime).append("</p>\n");
summary.append("<div class=\"title\">\n");
summary.append("<div class=\"left\">\n");