Skip to content

Commit

Permalink
POL-1365 Update Policy Permissions Automation - support for crossed-d…
Browse files Browse the repository at this point in the history
…agger symbol (#2678)

* updated fail message for AWS, Azure, Google Cloud, and Flexera permissions that should have a footnote

* updated condition to support dagger and cross-dagger symbol when looking for permission lines that end with a footnote symbol

* updated condition to support dagger and crossed dagger symbol when checking the permission/s footnote/s themselves

* remove references to asterix and replace with footnote_symbol to be more generic

* updated ruby script for generating policy master permissions to support crossed dagger symbol

* test footnote symbol

* test footnote symbol 2

* test footnote symbol 3

* test footnote symbol 4

* test footnote symbol 5

* attempt again

* attempt 2 with dagger symbol only

* replace dagger symbol with unicode

* update the perm testers to support the new symbols using unicode

* attempt 2 with dagger symbol only, but now without the footnote

* attempt 2 with cross-dagger symbol only, also change to unicode in dangerfile readme script

* attempt 2 with both dagger and cross-dagger, however, dagger is missing footnote

* update readme script to account for different scenarios of missing footnotes

* change permission action logic

* test both dagger and crossed dagger with footnotes (expecting all checks to pass)

* change permission action logic for Azure

* revert changes made to Schedule EC2 events policy readme

* change permission action logic for Google Cloud

* change permission action logic for Flexera provider

* add code to support 3 additional symbols - section, double-vertical bar, pilcrow

* change to Google policy readme to test dangerfile check

* revert changes

* add changes to Microsoft policy readme to test dangerfile check

* footnote asterisk instead of section symbol

* now testing double-veritcal bar and pilcrow symbols

* minor change to language in error message with regards to missing footnotes

* now testing error message to see if it includes one for a missing asterisk footnote

* revert changes to policy template readme

* add support for section, double-vertical bar and pilcrow symbols in the master permissions script

* fixed if statement
  • Loading branch information
nia-vf1 authored Oct 10, 2024
1 parent 75775d8 commit 5ce80c3
Show file tree
Hide file tree
Showing 2 changed files with 135 additions and 42 deletions.
162 changes: 122 additions & 40 deletions .dangerfile/readme_tests.rb
Original file line number Diff line number Diff line change
Expand Up @@ -264,8 +264,10 @@ def readme_invalid_credentials?(file, file_lines)
fail_message += "```- [**AWS Credential**](https://docs.flexera.com/flexera/EN/Automation/ProviderCredentials.htm#automationadmin_1982464505_1121575) (*provider=aws*) which has the following permissions:```\n\n"
end

aws_perm_tester = /`[a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)*:[a-zA-Z0-9]+`(?:\*)?$/
asterix_found = 0
aws_perm_tester = /`[a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)*:[a-zA-Z0-9]+`(?:[\*\u2020\u2021\u00a7\u2016\u00b6])?$/

# Hash to track the presence of each footnote symbol in the permission list
footnote_symbols = { "*" => false, "†" => false, "‡" => false, "§" => false, "‖" => false, "¶" => false }
permission_list_found = 0

aws_permission_text.each_with_index do |line, index|
Expand All @@ -277,31 +279,51 @@ def readme_invalid_credentials?(file, file_lines)
if !line.start_with?(" - ")
permission_list_found = 2
else
asterix_found = 1 if line.strip.end_with?("*")

if !line.split(" - ")[1].match?(aws_perm_tester)
footnote_symbols["*"] = true if line.strip.end_with?("*")
footnote_symbols["†"] = true if line.strip.end_with?("\u2020")
footnote_symbols["‡"] = true if line.strip.end_with?("\u2021")
footnote_symbols["§"] = true if line.strip.end_with?("\u00a7")
footnote_symbols["‖"] = true if line.strip.end_with?("\u2016")
footnote_symbols["¶"] = true if line.strip.end_with?("\u00b6")

permission_action = line.split(" - ")[1]
if permission_action.nil? || !permission_action.match?(aws_perm_tester)
fail_message += "Line #{line_number.to_s}: AWS permission list item formatted incorrectly. Please make sure all list items are formatted like the following examples:\n\n"
fail_message += "``` - `rds:DeleteDBSnapshot`*```\n"
fail_message += "``` - `ec2:TerminateInstances`†```\n"
fail_message += "``` - `sts:GetCallerIdentity` ```\n"
fail_message += "``` - `cloudtrail:LookupEvents` ```\n\n"
end
end
end
end

asterix_found = 2 if asterix_found == 1 && line.start_with?(' \* ')
# Check for missing footnotes for any symbols that were found in the permissions list
footnote_symbols.each do |symbol, found|
next unless found # Only check if the symbol was found in the permission list

# Search for corresponding footnote explanation
if symbol == "*"
if !aws_permission_text.any? { |line| line.strip.start_with?("\\*") }
fail_message += "Permission list contains a permission with an asterisk (*), but no corresponding footnote explaining it. Please add a footnote starting with ` \\* ` like so:\n\n"
fail_message += "``` \\* Only required for taking action; the policy will still function in a read-only capacity without these permissions.```\n"
end
else
if !aws_permission_text.any? { |line| line.strip.start_with?(symbol) }
fail_message += "Permission list contains a permission with a #{symbol} symbol, but no corresponding footnote explaining it. Please add a footnote starting with ` #{symbol} ` like so:\n\n"
fail_message += "``` #{symbol} Only required for taking action; the policy will still function in a read-only capacity without these permissions.```\n"
end
end
end

# Check if no permission list was found
if permission_list_found == 0
fail_message += "AWS permission list missing or formatted incorrectly. Please ensure there is a list of permissions beneath the AWS permission statement. Each list item should begin with [space][space][hyphen][space] like so:\n\n"
fail_message += "``` - `rds:DeleteDBSnapshot`*```\n"
fail_message += "``` - `ec2:TerminateInstances`†```\n"
fail_message += "``` - `sts:GetCallerIdentity` ```\n"
fail_message += "``` - `cloudtrail:LookupEvents` ```\n\n"
end

if asterix_found == 1
fail_message += "AWS permission list contains a permission with an asterix but no footnote explaning why or the footnote is formatted incorrectly. The footnote should indicate what is special about these permissions; in most cases, this will be an explanation that the permission is optional and only needed for policy actions. Please add a footnote that begins with [space][space][backslash][asterix][space] like so:\n\n"
fail_message += "``` \\* Only required for taking action; the policy will still function in a read-only capacity without these permissions.```\n\n"
end
end

if azure_permission_line
Expand All @@ -310,8 +332,10 @@ def readme_invalid_credentials?(file, file_lines)
fail_message += "```- [**Azure Resource Manager Credential**](https://docs.flexera.com/flexera/EN/Automation/ProviderCredentials.htm#automationadmin_109256743_1124668) (*provider=azure_rm*) which has the following permissions:```\n\n"
end

azure_perm_tester = /^`Microsoft\.[a-zA-Z]+\/[a-zA-Z]+\/[a-zA-Z]+(?:\/[a-zA-Z]+)*`(?:\*)?$/
asterix_found = 0
azure_perm_tester = /^`Microsoft\.[a-zA-Z]+\/[a-zA-Z]+\/[a-zA-Z]+(?:\/[a-zA-Z]+)*`(?:[\*\u2020\u2021\u00a7\u2016\u00b6])?$/

# Hash to track the presence of each footnote symbol in the permission list
footnote_symbols = { "*" => false, "†" => false, "‡" => false, "§" => false, "‖" => false, "¶" => false }
permission_list_found = 0

azure_permission_text.each_with_index do |line, index|
Expand All @@ -323,31 +347,49 @@ def readme_invalid_credentials?(file, file_lines)
if !line.start_with?(" - ")
permission_list_found = 2
else
asterix_found = 1 if line.strip.end_with?("*")

if !line.split(" - ")[1].match?(azure_perm_tester)
footnote_symbols["*"] = true if line.strip.end_with?("*")
footnote_symbols["†"] = true if line.strip.end_with?("\u2020")
footnote_symbols["‡"] = true if line.strip.end_with?("\u2021")
footnote_symbols["§"] = true if line.strip.end_with?("\u00a7")
footnote_symbols["‖"] = true if line.strip.end_with?("\u2016")
footnote_symbols["¶"] = true if line.strip.end_with?("\u00b6")

permission_action = line.split(" - ")[1]
if permission_action.nil? || !permission_action.match?(azure_perm_tester)
fail_message += "Line #{line_number.to_s}: Azure permission list item formatted incorrectly. Please make sure all list items are formatted like the following examples:\n\n"
fail_message += "``` - `Microsoft.Compute/snapshots/delete`*```\n"
fail_message += "``` - `Microsoft.Compute/snapshots/read` ```\n"
fail_message += "``` - `Microsoft.Insights/metrics/read` ```\n\n"
end
end
end
end

# Check for missing footnotes for any symbols that were found in the permissions list
footnote_symbols.each do |symbol, found|
next unless found # Only check if the symbol was found in the permission list

asterix_found = 2 if asterix_found == 1 && line.start_with?(' \* ')
# Search for corresponding footnote explanation
if symbol == "*"
if !azure_permission_text.any? { |line| line.strip.start_with?("\\*") }
fail_message += "Permission list contains a permission with an asterisk (*), but no corresponding footnote explaining it. Please add a footnote starting with ` \\* ` like so:\n\n"
fail_message += "``` \\* Only required for taking action; the policy will still function in a read-only capacity without these permissions.```\n"
end
else
if !azure_permission_text.any? { |line| line.strip.start_with?(symbol) }
fail_message += "Permission list contains a permission with a #{symbol} symbol, but no corresponding footnote explaining it. Please add a footnote starting with ` #{symbol} ` like so:\n\n"
fail_message += "``` #{symbol} Only required for taking action; the policy will still function in a read-only capacity without these permissions.```\n"
end
end
end

# Check if no permission list was found
if permission_list_found == 0
fail_message += "Azure permission list missing or formatted incorrectly. Please ensure there is a list of permissions beneath the Azure permission statement. Each list item should begin with [space][space][hyphen][space] like so:\n\n"
fail_message += "``` - `Microsoft.Compute/snapshots/delete`*```\n"
fail_message += "``` - `Microsoft.Compute/snapshots/read` ```\n"
fail_message += "``` - `Microsoft.Insights/metrics/read` ```\n\n"
end

if asterix_found == 1
fail_message += "Azure permission list contains a permission with an asterix but no footnote explaning why or the footnote is formatted incorrectly. The footnote should indicate what is special about these permissions; in most cases, this will be an explanation that the permission is optional and only needed for policy actions. Please add a footnote that begins with [space][space][backslash][asterix][space] like so:\n\n"
fail_message += "``` \\* Only required for taking action; the policy will still function in a read-only capacity without these permissions.```\n\n"
end
end

if google_permission_line
Expand All @@ -356,8 +398,10 @@ def readme_invalid_credentials?(file, file_lines)
fail_message += "```- [**Google Cloud Credential**](https://docs.flexera.com/flexera/EN/Automation/ProviderCredentials.htm#automationadmin_4083446696_1121577) (*provider=gce*) which has the following:```\n\n"
end

google_perm_tester = /^`[a-zA-Z]+\.[a-zA-Z]+\.[a-zA-Z]+(?:\.[a-zA-Z]+)*`(?:\*)?$/
asterix_found = 0
google_perm_tester = /^`[a-zA-Z]+\.[a-zA-Z]+\.[a-zA-Z]+(?:\.[a-zA-Z]+)*`(?:[\*\u2020\u2021\u00a7\u2016\u00b6])?$/

# Hash to track the presence of each footnote symbol in the permission list
footnote_symbols = { "*" => false, "†" => false, "‡" => false, "§" => false, "‖" => false, "¶" => false }
permission_list_found = 0

google_permission_text.each_with_index do |line, index|
Expand All @@ -369,31 +413,50 @@ def readme_invalid_credentials?(file, file_lines)
if !line.start_with?(" - ")
permission_list_found = 2
else
asterix_found = 1 if line.strip.end_with?("*")
footnote_symbols["*"] = true if line.strip.end_with?("*")
footnote_symbols["†"] = true if line.strip.end_with?("\u2020")
footnote_symbols["‡"] = true if line.strip.end_with?("\u2021")
footnote_symbols["§"] = true if line.strip.end_with?("\u00a7")
footnote_symbols["‖"] = true if line.strip.end_with?("\u2016")
footnote_symbols["¶"] = true if line.strip.end_with?("\u00b6")

if !line.split(" - ")[1].match?(google_perm_tester)
fail_message += "Line #{line_number.to_s}: Google permission list item formatted incorrectly. Please make sure all list items are formatted like the following examples:\n\n"
fail_message += "``` - `resourcemanager.projects.get`*```\n"
fail_message += "``` - `recommender.computeInstanceMachineTypeRecommendations.list`†```\n"
fail_message += "``` - `compute.regions.list` ```\n"
fail_message += "``` - `billing.resourceCosts.get` ```\n\n"
end
end
end
end

asterix_found = 2 if asterix_found == 1 && line.start_with?(' \* ')
# Check for missing footnotes for any symbols that were found in the permissions list
footnote_symbols.each do |symbol, found|
next unless found # Only check if the symbol was found in the permission list

# Search for corresponding footnote explanation
if symbol == "*"
if !google_permission_text.any? { |line| line.strip.start_with?("\\*") }
fail_message += "Permission list contains a permission with an asterisk (*), but no corresponding footnote explaining it. Please add a footnote starting with ` \\* ` like so:\n\n"
fail_message += "``` \\* Only required for taking action; the policy will still function in a read-only capacity without these permissions.```\n"
end
else
if !google_permission_text.any? { |line| line.strip.start_with?(symbol) }
fail_message += "Permission list contains a permission with a #{symbol} symbol, but no corresponding footnote explaining it. Please add a footnote starting with ` #{symbol} ` like so:\n\n"
fail_message += "``` #{symbol} Only required for taking action; the policy will still function in a read-only capacity without these permissions.```\n"
end
end
end

# Check if no permission list was found
if permission_list_found == 0
fail_message += "Google permission list missing or formatted incorrectly. Please ensure there is a list of permissions beneath the Google permission statement. Each list item should begin with [space][space][hyphen][space] like so:\n\n"
fail_message += "``` - `resourcemanager.projects.get`*```\n"
fail_message += "``` - `recommender.computeInstanceMachineTypeRecommendations.list`†```\n"
fail_message += "``` - `compute.regions.list` ```\n"
fail_message += "``` - `billing.resourceCosts.get` ```\n\n"
end

if asterix_found == 1
fail_message += "Google permission list contains a permission with an asterix but no footnote explaning why or the footnote is formatted incorrectly. The footnote should indicate what is special about these permissions; in most cases, this will be an explanation that the permission is optional and only needed for policy actions. Please add a footnote that begins with [space][space][backslash][asterix][space] like so:\n\n"
fail_message += "``` \\* Only required for taking action; the policy will still function in a read-only capacity without these permissions.```\n\n"
end
end

if flexera_permission_line
Expand All @@ -402,8 +465,10 @@ def readme_invalid_credentials?(file, file_lines)
fail_message += "```- [**Flexera Credential**](https://docs.flexera.com/flexera/EN/Automation/ProviderCredentials.htm) (*provider=flexera*) which has the following roles:```\n\n"
end

flexera_perm_tester = /^`[a-zA-Z0-9\-_\.]+`(?:\*)?$/
asterix_found = 0
flexera_perm_tester = /^`[a-zA-Z0-9\-_\.]+`(?:[\*\u2020\u2021\u00a7\u2016\u00b6])?$/

# Hash to track the presence of each footnote symbol in the permission list
footnote_symbols = { "*" => false, "†" => false, "‡" => false, "§" => false, "‖" => false, "¶" => false }
permission_list_found = 0

flexera_permission_text.each_with_index do |line, index|
Expand All @@ -415,27 +480,44 @@ def readme_invalid_credentials?(file, file_lines)
if !line.start_with?(" - ")
permission_list_found = 2
else
asterix_found = 1 if line.strip.end_with?("*")
footnote_symbols["*"] = true if line.strip.end_with?("*")
footnote_symbols["†"] = true if line.strip.end_with?("\u2020")
footnote_symbols["‡"] = true if line.strip.end_with?("\u2021")
footnote_symbols["§"] = true if line.strip.end_with?("\u00a7")
footnote_symbols["‖"] = true if line.strip.end_with?("\u2016")
footnote_symbols["¶"] = true if line.strip.end_with?("\u00b6")

if !line.split(" - ")[1].match?(flexera_perm_tester)
fail_message += "Line #{line_number.to_s}: Flexera permission list item formatted incorrectly. Please make sure all list items are formatted like the following examples:\n\n"
fail_message += "``` - `billing_center_viewer`*```\n\n"
end
end
end
end

asterix_found = 2 if asterix_found == 1 && line.start_with?(' \* ')
# Check for missing footnotes for any symbols that were found in the permissions list
footnote_symbols.each do |symbol, found|
next unless found # Only check if the symbol was found in the permission list

# Search for corresponding footnote explanation
if symbol == "*"
if !flexera_permission_text.any? { |line| line.strip.start_with?("\\*") }
fail_message += "Permission list contains a permission with an asterisk (*), but no corresponding footnote explaining it. Please add a footnote starting with ` \\* ` like so:\n\n"
fail_message += "``` \\* Only required for taking action; the policy will still function in a read-only capacity without these permissions.```\n"
end
else
if !flexera_permission_text.any? { |line| line.strip.start_with?(symbol) }
fail_message += "Permission list contains a permission with a #{symbol} symbol, but no corresponding footnote explaining it. Please add a footnote starting with ` #{symbol} ` like so:\n\n"
fail_message += "``` #{symbol} Only required for taking action; the policy will still function in a read-only capacity without these permissions.```\n"
end
end
end

# Check if no permission list was found
if permission_list_found == 0
fail_message += "Flexera permission list missing or formatted incorrectly. Please ensure there is a list of permissions beneath the Flexera permission statement. Each list item should begin with [space][space][hyphen][space] like so:\n\n"
fail_message += "``` - `billing_center_viewer`*```\n\n"
end

if asterix_found == 1
fail_message += "Flexera permission list contains a permission with an asterix but no footnote explaning why or the footnote is formatted incorrectly. The footnote should indicate what is special about these permissions; in most cases, this will be an explanation that the permission is optional and only needed for policy actions. Please add a footnote that begins with [space][space][backslash][asterix][space] like so:\n\n"
fail_message += "``` \\* Only required for taking action; the policy will still function in a read-only capacity without these permissions.```\n\n"
end
end

fail_message = "README.md has problems with how credential permissions are presented:\n\n" + fail_message if !fail_message.empty?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,8 @@ def extract_permissions_from_readme(readme_content)
# Extract the text from this section
section_text = readme_content[section_start..-1]

# Find the line starting with '/*' or '' to get any specific notes around permissions from the README
# Find the line starting with '/*', '†', '‡', '§', '‖' or '' to get any specific notes around permissions from the README
list_of_notes = []
# note = ""
section_text.each_line do |line|
break if line.strip.start_with?( "##", "###", "- [**") && !line.strip.start_with?(section)

Expand All @@ -111,6 +110,18 @@ def extract_permissions_from_readme(readme_content)
elsif line.strip.start_with?("\u2020")
dagger_note = line.strip.sub(/^\†\s*/, '')
list_of_notes << { symbol: "†", detail: dagger_note }
elsif line.strip.start_with?("\u2021")
cross_dagger_note = line.strip.sub(/^\‡\s*/, '')
list_of_notes << { symbol: "‡", detail: cross_dagger_note }
elsif line.strip.start_with?("\u00a7")
section_note = line.strip.sub(/^\s*/, '')
list_of_notes << { symbol: "§", detail: section_note }
elsif line.strip.start_with?("\u2016")
vertical_bar_note = line.strip.sub(/^\‖\s*/, '')
list_of_notes << { symbol: "‖", detail: vertical_bar_note }
elsif line.strip.start_with?("\u00b6")
pilcrow_note = line.strip.sub(/^\s*/, '')
list_of_notes << { symbol: "¶", detail: pilcrow_note }
end
end

Expand Down

0 comments on commit 5ce80c3

Please sign in to comment.