diff --git a/pom.xml b/pom.xml index 6a7f914bc..e81a40003 100644 --- a/pom.xml +++ b/pom.xml @@ -243,6 +243,9 @@ along with DependencyCheck. If not, see . target/data/cpe + + **/*IntegrationTest.java + diff --git a/src/main/java/org/codesecure/dependencycheck/App.java b/src/main/java/org/codesecure/dependencycheck/App.java index 48dfa0f31..ca24abc73 100644 --- a/src/main/java/org/codesecure/dependencycheck/App.java +++ b/src/main/java/org/codesecure/dependencycheck/App.java @@ -28,6 +28,7 @@ import java.util.logging.LogManager; import java.util.logging.Logger; import javax.xml.parsers.ParserConfigurationException; import org.apache.commons.cli.ParseException; +import org.codesecure.dependencycheck.analyzer.AnalysisPhase; import org.codesecure.dependencycheck.data.cpe.xml.Importer; import org.codesecure.dependencycheck.reporting.ReportGenerator; import org.codesecure.dependencycheck.dependency.Dependency; @@ -158,9 +159,9 @@ public class App { scanner.analyzeDependencies(); List dependencies = scanner.getDependencies(); - ReportGenerator report = new ReportGenerator(); + ReportGenerator report = new ReportGenerator(applicationName, dependencies, scanner.getAnalyzers()); try { - report.generateReports(reportDirectory, applicationName, dependencies); + report.generateReports(reportDirectory); } catch (IOException ex) { Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex); } catch (Exception ex) { diff --git a/src/main/java/org/codesecure/dependencycheck/Engine.java b/src/main/java/org/codesecure/dependencycheck/Engine.java index 9895a32e6..11a8a1b42 100644 --- a/src/main/java/org/codesecure/dependencycheck/Engine.java +++ b/src/main/java/org/codesecure/dependencycheck/Engine.java @@ -195,7 +195,8 @@ public class Engine { try { a.initialize(); } catch (Exception ex) { - Logger.getLogger(Engine.class.getName()).log(Level.SEVERE, "Exception occured initializing " + a.getName() + ".", ex); + Logger.getLogger(Engine.class.getName()).log(Level.SEVERE, + "Exception occured initializing " + a.getName() + ".", ex); try { a.close(); } catch (Exception ex1) { @@ -254,8 +255,23 @@ public class Engine { try { source.update(); } catch (UpdateException ex) { - Logger.getLogger(Engine.class.getName()).log(Level.SEVERE, "Unable to update " + source.getClass().getName(), ex); + Logger.getLogger(Engine.class.getName()).log(Level.SEVERE, + "Unable to update " + source.getClass().getName(), ex); } } } + + /** + * Returns a full list of all of the analyzers. This is useful + * for reporting which analyzers where used. + * @return a list of Analyzers + */ + public List getAnalyzers() { + List ret = new ArrayList(); + for (AnalysisPhase phase : AnalysisPhase.values()) { + List analyzerList = analyzers.get(phase); + ret.addAll(analyzerList); + } + return ret; + } } diff --git a/src/main/java/org/codesecure/dependencycheck/reporting/ReportGenerator.java b/src/main/java/org/codesecure/dependencycheck/reporting/ReportGenerator.java index 7de535375..909dd196a 100644 --- a/src/main/java/org/codesecure/dependencycheck/reporting/ReportGenerator.java +++ b/src/main/java/org/codesecure/dependencycheck/reporting/ReportGenerator.java @@ -18,15 +18,15 @@ package org.codesecure.dependencycheck.reporting; * Copyright (c) 2012 Jeremy Long. All Rights Reserved. */ +import java.io.FileInputStream; import java.io.BufferedWriter; import java.io.File; +import java.io.FileNotFoundException; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import org.apache.velocity.app.VelocityEngine; @@ -35,66 +35,110 @@ import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader; import org.apache.velocity.tools.ToolManager; import org.apache.velocity.tools.config.EasyFactoryConfiguration; +import org.codesecure.dependencycheck.analyzer.Analyzer; import org.codesecure.dependencycheck.dependency.Dependency; /** + * The ReportGenerator is used to, as the name implies, generate reports. Internally + * the generator uses the Velocity Templating Engine. The ReportGenerator exposes + * a list of Dependencies to the template when generating the report. * * @author Jeremy Long (jeremy.long@gmail.com) */ public class ReportGenerator { + /** + * The Velocity Engine. + */ + private VelocityEngine engine = null; + /** + * The Velocity Engine Context. + */ + private Context context = null; + + /** + * Constructs a new ReportGenerator. + * + * @param applicationName the application name being analyzed + * @param dependencies the list of dependencies + * @param analyzers the list of analyzers used. + */ + public ReportGenerator(String applicationName, List dependencies, List analyzers) { + engine = createVelocityEngine(); + context = createContext(); + + engine.init(); + + context.put("applicationName", applicationName); + context.put("dependencies", dependencies); + context.put("analyzers", analyzers); + } + + /** + * Creates a new Velocity Engine. + * @return a velocity engine. + */ + private VelocityEngine createVelocityEngine() { + VelocityEngine ve = new VelocityEngine(); + ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath"); + ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName()); + return ve; + } + + /** + * Creates a new Velocity Context initialized with escape and date tools. + * @return a Velcotiy Context. + */ + private Context createContext() { + ToolManager manager = new ToolManager(); + Context c = manager.createContext(); + EasyFactoryConfiguration config = new EasyFactoryConfiguration(); + config.addDefaultTools(); + config.toolbox("application") + .tool("esc", "org.apache.velocity.tools.generic.EscapeTool") + .tool("org.apache.velocity.tools.generic.DateTool"); + manager.configure(config); + return c; + } + /** * Generates the Dependency Reports for the identified dependencies. * * @param outputDir the path where the reports should be written. - * @param applicationName the name of the application that was scanned. - * @param dependencies a list of dependencies to include in the report. * @throws IOException is thrown when the template file does not exist. * @throws Exception is thrown if there is an error writting out the * reports. */ - public void generateReports(String outputDir, String applicationName, List dependencies) throws IOException, Exception { - - Map properties = new HashMap(); - properties.put("dependencies", dependencies); - properties.put("applicationName", applicationName); - - String reportName = applicationName.replaceAll("[^a-zA-Z0-9-_ \\.]+", ""); - String filename = outputDir + File.separatorChar + reportName; - generateReport("HtmlReport", filename + ".html", properties); - //generateReport("XmlReport",filename + ".xml",properties); - + public void generateReports(String outputDir) throws IOException, Exception { + generateReport("HtmlReport", outputDir + File.separator + "DependencyCheck-Report.html"); + //generateReport("XmlReport", outputDir + File.separator + "DependencyCheck-Report.xml"); } /** - * much of this code is from - * http://stackoverflow.com/questions/2931516/loading-velocity-template-inside-a-jar-file + * Generates a report from a given Velocity Template. The template name + * provided can be the name of a template contained in the jar file, such as + * 'XmlReport' or 'HtmlReport', or the template name can be the path to a template file. * * @param templateName the name of the template to load. - * @param outFileName The filename and path to write the report to. - * @param properties a map of properties to load into the velocity context. + * @param outFileName the filename and path to write the report to. * @throws IOException is thrown when the template file does not exist. * @throws Exception is thrown when an exception occurs. */ - protected void generateReport(String templateName, String outFileName, - Map properties) throws IOException, Exception { - - VelocityEngine ve = new VelocityEngine(); - ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath"); - ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName()); - - ToolManager manager = new ToolManager(); - Context context = manager.createContext(); - EasyFactoryConfiguration config = new EasyFactoryConfiguration(); - config.addDefaultTools(); - config.toolbox("application").tool("esc", "org.apache.velocity.tools.generic.EscapeTool").tool("org.apache.velocity.tools.generic.DateTool"); - - manager.configure(config); - - ve.init(); - - final String templatePath = "templates/" + templateName + ".vsl"; - InputStream input = this.getClass().getClassLoader().getResourceAsStream(templatePath); + public void generateReport(String templateName, String outFileName) throws IOException, Exception { + InputStream input = null; + String templatePath = null; + File f = new File(templateName); + if (f.exists() && f.isFile()) { + try { + templatePath = templateName; + input = new FileInputStream(f); + } catch (FileNotFoundException ex) { + Logger.getLogger(ReportGenerator.class.getName()).log(Level.SEVERE, null, ex); + } + } else { + templatePath = "templates/" + templateName + ".vsl"; + input = this.getClass().getClassLoader().getResourceAsStream(templatePath); + } if (input == null) { throw new IOException("Template file doesn't exist"); } @@ -102,19 +146,10 @@ public class ReportGenerator { InputStreamReader reader = new InputStreamReader(input); BufferedWriter writer = null; - //VelocityContext context = new VelocityContext(); - - //load the data into the context - if (properties != null) { - for (Map.Entry property : properties.entrySet()) { - context.put(property.getKey(), property.getValue()); - } - } - try { writer = new BufferedWriter(new FileWriter(new File(outFileName))); - if (!ve.evaluate(context, writer, templatePath, reader)) { + if (!engine.evaluate(context, writer, templatePath, reader)) { throw new Exception("Failed to convert the template into html."); } writer.flush(); diff --git a/src/main/resources/templates/HtmlReport.vsl b/src/main/resources/templates/HtmlReport.vsl index 67b92d17e..9316b6586 100644 --- a/src/main/resources/templates/HtmlReport.vsl +++ b/src/main/resources/templates/HtmlReport.vsl @@ -285,8 +285,12 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
Report Generated On: $date

Dependencies Scanned: $dependencies.size()

- #foreach($dependency in $dependencies) - $esc.html($dependency.FileName)
+ #foreach($dependency in $dependencies) + #if($dependency.getVulnerabilities().size()>0) + $esc.html($dependency.FileName) 
+ #else + $esc.html($dependency.FileName)
+ #end #end

Dependencies

diff --git a/src/test/java/org/codesecure/dependencycheck/EngineIntegrationTest.java b/src/test/java/org/codesecure/dependencycheck/EngineIntegrationTest.java index 584b93cad..ed4ed7d58 100644 --- a/src/test/java/org/codesecure/dependencycheck/EngineIntegrationTest.java +++ b/src/test/java/org/codesecure/dependencycheck/EngineIntegrationTest.java @@ -51,7 +51,8 @@ public class EngineIntegrationTest { instance.scan(path); assertTrue(instance.getDependencies().size() > 0); instance.analyzeDependencies(); - ReportGenerator rg = new ReportGenerator(); - rg.generateReports("./target/", "DependencyCheck", instance.getDependencies()); + ReportGenerator rg = new ReportGenerator("DependencyCheck", + instance.getDependencies(), instance.getAnalyzers()); + rg.generateReports("./target/"); } }