Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added the ability to specify custom rules.json path #368

Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 14 additions & 7 deletions src/Analyzer.Cli/CommandLineParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,11 @@ private void SetupCommonOptionsForCommands(List<Command> commands)

new Option(
"--include-non-security-rules",
"Run all the rules against the templates, including non-security rules")
"Run all the rules against the templates, including non-security rules"),

new Option<FileInfo>(
"--custom-rules-json-path",
borisf94 marked this conversation as resolved.
Show resolved Hide resolved
"The rules JSON file to use against the templates. If not specified, will use the default rule set that is shipped with the tool.")
borisf94 marked this conversation as resolved.
Show resolved Hide resolved
};

commands.ForEach(c => options.ForEach(c.AddOption));
Expand All @@ -157,7 +161,8 @@ private int AnalyzeTemplateCommandHandler(
ReportFormat reportFormat,
FileInfo outputFilePath,
bool includeNonSecurityRules,
bool verbose)
bool verbose,
FileInfo customRulesJsonPath)
{
// Check that template file paths exist
if (!templateFilePath.Exists)
Expand All @@ -166,7 +171,7 @@ private int AnalyzeTemplateCommandHandler(
return (int)ExitCode.ErrorInvalidPath;
}

var setupResult = SetupAnalysis(configFilePath, directoryToAnalyze: null, reportFormat, outputFilePath, includeNonSecurityRules, verbose);
var setupResult = SetupAnalysis(configFilePath, directoryToAnalyze: null, reportFormat, outputFilePath, includeNonSecurityRules, verbose, customRulesJsonPath);
if (setupResult != ExitCode.Success)
{
return (int)setupResult;
Expand Down Expand Up @@ -203,15 +208,16 @@ private int AnalyzeDirectoryCommandHandler(
ReportFormat reportFormat,
FileInfo outputFilePath,
bool includeNonSecurityRules,
bool verbose)
bool verbose,
FileInfo customRulesJsonPath)
{
if (!directoryPath.Exists)
{
Console.Error.WriteLine("Invalid directory: {0}", directoryPath);
return (int)ExitCode.ErrorInvalidPath;
}

var setupResult = SetupAnalysis(configFilePath, directoryPath, reportFormat, outputFilePath, includeNonSecurityRules, verbose);
var setupResult = SetupAnalysis(configFilePath, directoryPath, reportFormat, outputFilePath, includeNonSecurityRules, verbose, customRulesJsonPath);
if (setupResult != ExitCode.Success)
{
return (int)setupResult;
Expand Down Expand Up @@ -278,7 +284,8 @@ private ExitCode SetupAnalysis(
ReportFormat reportFormat,
FileInfo outputFilePath,
bool includeNonSecurityRules,
bool verbose)
bool verbose,
FileInfo customRulesJsonPath)
{
// Output file path must be specified if SARIF was chosen as the report format
if (reportFormat == ReportFormat.Sarif && outputFilePath == null)
Expand All @@ -290,7 +297,7 @@ private ExitCode SetupAnalysis(
this.reportWriter = GetReportWriter(reportFormat, outputFilePath, directoryToAnalyze?.FullName);
CreateLoggers(verbose);

this.templateAnalyzer = TemplateAnalyzer.Create(includeNonSecurityRules, this.logger);
this.templateAnalyzer = TemplateAnalyzer.Create(includeNonSecurityRules, this.logger, customRulesJsonPath);

if (!TryReadConfigurationFile(configurationFile, out var config))
{
Expand Down
24 changes: 24 additions & 0 deletions src/Analyzer.Core.UnitTests/TemplateAnalyzerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,30 @@ public void FilterRules_ValidConfiguration_NoExceptionThrown()
TemplateAnalyzer.Create(false).FilterRules(new ConfigurationDefinition());
}

[TestMethod]
borisf94 marked this conversation as resolved.
Show resolved Hide resolved
public void CustomRulesFileIsProvided_NoExceptionThrown()
{
var rulesDir = Path.Combine(
Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
"Rules");
var rulesFile = Path.Combine(rulesDir, "BuiltInRules.json");
var movedFile = Path.Combine(rulesDir, "MovedRules.json");

// Move rules file
File.Move(rulesFile, movedFile);

var customRulesFile = new FileInfo(movedFile);

try
{
TemplateAnalyzer.Create(false, null, customRulesFile);
}
finally
{
File.Move(movedFile, rulesFile, overwrite: true);
}
}

[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void FilterRules_ConfigurationNull_ExceptionThrown()
Expand Down
15 changes: 10 additions & 5 deletions src/Analyzer.Core/TemplateAnalyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,14 @@ private TemplateAnalyzer(JsonRuleEngine jsonRuleEngine, PowerShellRuleEngine pow
/// </summary>
/// <param name="includeNonSecurityRules">Whether or not to run also non-security rules against the template.</param>
/// <param name="logger">A logger to report errors and debug information</param>
/// <param name="customRulesJsonPath">An optional custom rules json file path.</param>
/// <returns>A new <see cref="TemplateAnalyzer"/> instance.</returns>
public static TemplateAnalyzer Create(bool includeNonSecurityRules, ILogger logger = null)
public static TemplateAnalyzer Create(bool includeNonSecurityRules, ILogger logger = null, FileInfo customRulesJsonPath = null)
{
string rules;
try
{
rules = LoadRules();
rules = LoadRules(customRulesJsonPath);
}
catch (Exception e)
{
Expand Down Expand Up @@ -224,12 +225,16 @@ private IEnumerable<IEvaluation> AnalyzeAllIncludedTemplates(string populatedTem
}
}

private static string LoadRules()
private static string LoadRules(FileInfo rulesFile)
{
return File.ReadAllText(
Path.Combine(
rulesFile ??= new FileInfo(Path.Combine(
Path.GetDirectoryName(AppContext.BaseDirectory),
"Rules/BuiltInRules.json"));

using var fileStream = rulesFile.OpenRead();
using var streamReader = new StreamReader(fileStream);

return streamReader.ReadToEnd();
}

/// <summary>
Expand Down
Loading