From a3c9f53bc3d8526797ff4f28f9d929f343f3bd58 Mon Sep 17 00:00:00 2001 From: Azeem Sajid Date: Mon, 24 Apr 2023 12:52:09 +0500 Subject: [PATCH] Update action --- action.yml | 12 +++---- scripts/analyze.bash | 75 +++++++++++++++++++++++++++---------------- scripts/validate.bash | 3 +- 3 files changed, 56 insertions(+), 34 deletions(-) diff --git a/action.yml b/action.yml index 265020c..f12fad8 100644 --- a/action.yml +++ b/action.yml @@ -14,15 +14,15 @@ inputs: description: 'Domain or URL to analyze HTTP response headers' required: true follow-redirects: - description: 'Enable/disable following redirects' + description: 'Follow redirect status codes' required: false default: 'true' hide-results-on-homepage: - description: 'Enable/disable hiding results on homepage' + description: 'Hide results on homepage' required: false default: 'true' api-timeout-in-seconds: - description: 'API timeout in seconds (must be +ve, -ve value means default)' + description: 'API request timeout in seconds (must be +ve, -ve value means default)' required: false default: '30' max-retries-on-api-error: @@ -30,7 +30,7 @@ inputs: required: false default: '0' expected-grade: - description: 'Expected grade [A+ to F; or maybe R if `follow-redirects: false`] (invalid grade means default)' + description: 'Expected grade [A+ to F; or maybe R if `follow-redirects: false`] (invalid value means default)' required: false default: '' @@ -56,8 +56,8 @@ runs: INPUT_DOMAIN_OR_URL: '${{ inputs.domain-or-url }}' INPUT_FOLLOW_REDIRECTS: ${{ (inputs.follow-redirects == 'true') && 'on' || 'off' }} INPUT_HIDE_RESULTS_ON_HOMEPAGE: ${{ (inputs.hide-results-on-homepage == 'true') && 'on' || 'off' }} - INPUT_API_TIMEOUT_IN_SECONDS: ${{ (inputs.api-timeout-in-seconds > 0) && inputs.timeout-in-seconds || '30' }} - INPUT_MAX_RETRIES_ON_API_ERROR: ${{ (inputs.max-retries-on-api-error > 0) && inputs.retries-on-api-error || '0' }} + INPUT_API_TIMEOUT_IN_SECONDS: ${{ (inputs.api-timeout-in-seconds >= 0) && inputs.api-timeout-in-seconds || '30' }} + INPUT_MAX_RETRIES_ON_API_ERROR: ${{ (inputs.max-retries-on-api-error > 0) && inputs.max-retries-on-api-error || '0' }} INPUT_EXPECTED_GRADE: ${{ contains(fromJSON('["A+","A","B","C","D","E","F","R"]'), inputs.expected-grade) && inputs.expected-grade || '' }} OUTPUT_RESULTS_AS_JSON: 'results-as-json' OUTPUT_SUMMARY_AS_JSON: 'summary-as-json' diff --git a/scripts/analyze.bash b/scripts/analyze.bash index 4e04e32..c5dee0e 100755 --- a/scripts/analyze.bash +++ b/scripts/analyze.bash @@ -19,50 +19,71 @@ trap 'fatal "$LINENO" "$BASH_COMMAND"' ERR analyze() { echo "::group::Analyzing [$INPUT_DOMAIN_OR_URL]" - # INPUT_MAX_RETRIES_ON_API_ERROR + if [[ $INPUT_FOLLOW_REDIRECTS == "off" ]]; then + echo + echo "NOTE: Following of redirect status codes is disabled." + echo " You may get an 'R' grade." + echo " Set \`follow-redirects: true\` to get full resutls." + echo + fi local API_URL="https://api.securityheaders.com/?q=$INPUT_DOMAIN_OR_URL&followRedirects=$INPUT_FOLLOW_REDIRECTS&hide=$INPUT_HIDE_RESULTS_ON_HOMEPAGE" - echo "Making API request [$API_URL]" - local API_RESPONSE="$(curl -s -m "$INPUT_API_TIMEOUT_IN_SECONDS" -H "x-api-key: $INPUT_API_KEY" "$API_URL" 2>&1)" - if [[ -z $API_RESPONSE ]]; then - echo "Empty response!" - exit 1 - elif ! jq '.' <<<"$API_RESPONSE" >/dev/null 2>&1; then - echo "Invalid respone!" - echo "$API_RESPONSE" - exit 1 - fi + echo "API URL: [$API_URL]" - echo "Checking status" - local STATUS="$(jq -r '.status | ascii_downcase' <<<"$API_RESPONSE")" - if [[ $STATUS != "good" ]]; then - echo "Invalid response status received! [$STATUS]" - jq -r '.' <<<"$API_RESPONSE" - exit 1 - else - echo "STATUS: [$STATUS]" - fi + for ((RETRY = 0; RETRY <= INPUT_MAX_RETRIES_ON_API_ERROR; RETRY++)); do + echo "- Making API request [$RETRY / $INPUT_MAX_RETRIES_ON_API_ERROR]" + local API_RESPONSE="$(curl -sS -m "$INPUT_API_REQUEST_TIMEOUT_IN_SECONDS" -H "x-api-key: $INPUT_API_KEY" "$API_URL" 2>&1)" + local IS_ERROR=false + if [[ -z $API_RESPONSE ]]; then + echo " Empty response!" + IS_ERROR=true + elif ! jq '.' <<<"$API_RESPONSE" >/dev/null 2>&1; then + echo " Invalid respone!" + echo "$API_RESPONSE" + IS_ERROR=true + else + echo " Checking status" + local STATUS="$(jq -r '.status | ascii_downcase' <<<"$API_RESPONSE")" + if [[ $STATUS != "good" ]]; then + echo " Invalid status received! [$STATUS]" + jq -r '.' <<<"$API_RESPONSE" + IS_ERROR=true + else + echo " STATUS: [$STATUS]" + fi + fi + if [[ $IS_ERROR == true ]]; then + if ((INPUT_MAX_RETRIES_ON_API_ERROR)); then + echo " Retrying..." + else + echo " Exiting..." + exit 1 + fi + fi + done + local GRADE="$(jq -r '.summary.grade | ascii_upcase' <<<"$API_RESPONSE")" if [[ -n $INPUT_EXPECTED_GRADE ]]; then - echo "Checking expected grade [$INPUT_EXPECTED_GRADE]" - local GRADE="$(jq -r '.summary.grade | ascii_upcase' <<<"$API_RESPONSE")" - echo "Expected: [$INPUT_EXPECTED_GRADE], Found: [$GRADE]" + echo "- Checking expected grade [$INPUT_EXPECTED_GRADE]" if [[ $INPUT_EXPECTED_GRADE != "$GRADE" ]]; then - echo "Unexpected grade found!" + echo " Unexpected grade found!" + echo " Expected: [$INPUT_EXPECTED_GRADE], Found: [$GRADE]" exit 1 else - echo "Expected grade found! [$INPUT_EXPECTED_GRADE]" + echo " Expected grade found! [$INPUT_EXPECTED_GRADE]" fi fi - echo "Setting output parameters" + echo "- Setting output parameters" { echo "$OUTPUT_RESULTS_AS_JSON=$(jq -rc '.' <<<"$API_RESPONSE")" echo "$OUTPUT_SUMMARY_AS_JSON=$(jq -rc '.summary' <<<"$API_RESPONSE")" - echo "$OUTPUT_GRADE=$(jq -r '.summary.grade | ascii_upcase' <<<"$API_RESPONSE")" + echo "$OUTPUT_GRADE=$GRADE" } | tee -a "$GITHUB_OUTPUT" + echo " Output parameters set successfully!" + echo "::endgroup::" } diff --git a/scripts/validate.bash b/scripts/validate.bash index 7409c7f..dab09d7 100755 --- a/scripts/validate.bash +++ b/scripts/validate.bash @@ -17,10 +17,11 @@ validate_environment() { echo "::group::Validating environment" echo "BASH_VERSION: [$BASH_VERSION]" + echo echo "Validating required commands" local FOUND=true - for CMD in curl jq; do + for CMD in curl jq tee; do echo -n "- [$CMD] " if which "$CMD" >/dev/null 2>&1; then echo "[FOUND]"