neetob 0.5.68 → 0.5.69

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +1 -1
  3. data/lib/neetob/cli/base.rb +32 -0
  4. data/lib/neetob/cli/github/issues/helpers.rb +27 -0
  5. data/lib/neetob/cli/monthly_audit/commands.rb +2 -1
  6. data/lib/neetob/cli/monthly_audit/databases/users_unique_email_index.rb +6 -1
  7. data/lib/neetob/cli/monthly_audit/databases/uuid_primary_key.rb +8 -0
  8. data/lib/neetob/cli/monthly_audit/github_issue_creation.rb +35 -0
  9. data/lib/neetob/cli/monthly_audit/instances_and_addons/cloudflare/always_use_https_is_enabled.rb +11 -0
  10. data/lib/neetob/cli/monthly_audit/instances_and_addons/cloudflare/bot_protection_enabled.rb +9 -0
  11. data/lib/neetob/cli/monthly_audit/instances_and_addons/cloudflare/dns_entry_has_proxy_status.rb +9 -0
  12. data/lib/neetob/cli/monthly_audit/instances_and_addons/cloudflare/minimum_tls_version_is_one_point_two.rb +11 -0
  13. data/lib/neetob/cli/monthly_audit/instances_and_addons/cloudflare/spf_records_are_valid.rb +9 -0
  14. data/lib/neetob/cli/monthly_audit/instances_and_addons/cloudflare/ssl_tls_encryption_mode_set_to_full.rb +9 -0
  15. data/lib/neetob/cli/monthly_audit/instances_and_addons/cronitor/setup_correctly_for_apps.rb +10 -0
  16. data/lib/neetob/cli/monthly_audit/instances_and_addons/cronitor/setup_correctly_for_help_center.rb +12 -0
  17. data/lib/neetob/cli/monthly_audit/instances_and_addons/cronitor/setup_correctly_for_landing_pages.rb +12 -0
  18. data/lib/neetob/cli/monthly_audit/instances_and_addons/neeto_deploy_or_heroku/auto_scaling_enabled.rb +7 -0
  19. data/lib/neetob/cli/monthly_audit/instances_and_addons/neeto_deploy_or_heroku/cloudfront_cdn_enabled.rb +11 -0
  20. data/lib/neetob/cli/monthly_audit/instances_and_addons/neeto_deploy_or_heroku/essential_environment_variables_set.rb +12 -0
  21. data/lib/neetob/cli/monthly_audit/instances_and_addons/neeto_deploy_or_heroku/scheduled_exports_enabled.rb +6 -0
  22. data/lib/neetob/cli/monthly_audit/instances_and_addons/neeto_deploy_or_heroku/ssl_certificates_over_thirty_days_from_expiry.rb +12 -0
  23. data/lib/neetob/cli/monthly_audit/misc/redirections_working_correctly.rb +14 -1
  24. data/lib/neetob/cli/monthly_audit/perform.rb +7 -2
  25. data/lib/neetob/cli/monthly_audit/security/code/active_record_doctor.rb +9 -4
  26. data/lib/neetob/cli/monthly_audit/security/code/brakeman.rb +5 -0
  27. data/lib/neetob/cli/monthly_audit/security/code/bundle_audit.rb +6 -2
  28. data/lib/neetob/cli/monthly_audit/security/code/checks_for_unused_assets.rb +5 -0
  29. data/lib/neetob/cli/monthly_audit/security/code/fasterer.rb +8 -0
  30. data/lib/neetob/cli/monthly_audit/security/code/yarn_audit.rb +5 -0
  31. data/lib/neetob/cli/monthly_audit/security/github/dependabot_prs_merged.rb +5 -0
  32. data/lib/neetob/version.rb +1 -1
  33. metadata +3 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7e552e130888b6f3315ca5eca7e6a17e9dc3e03d5c3330d21f98e5c45bc87416
4
- data.tar.gz: af535649338ce0ad4139b204027b08ffad842d261a29b0135e74e49202fe0545
3
+ metadata.gz: 1fe5407c19ee902b9471fcd4c0774823a93e43a84dbd6ca26d017a4f0fe300dc
4
+ data.tar.gz: 2c0f79f96f0bfe02b6c4bc4c2c755381556aef67f046282850f8854f5d0e1cc3
5
5
  SHA512:
6
- metadata.gz: 45dabca79cf9eb38ca6bae03b0ac9a56a42bab6d820c1b0f6045d7e53c35f967bf2a1b539780bd5f72df3db5fc924d2f24b1323a91412bd123df14cd2eafef5e
7
- data.tar.gz: e854b32638603388a3673622ee0dc248ce4fbc5a4179a05c4fb1237535124318a5c8ac872cce8ab84523a31831ac09b334c265336dda91389d4ba9bd84dfb889
6
+ metadata.gz: b9e1fe5ca8b58144913a7635fc3376b6197f0851659b002cc5403b7c3dbb4d2ee3ee40e624193c81081f43138f23370c174a23dc00c32abef17a783f622283cb
7
+ data.tar.gz: 4c98377780c60fa3873155d025353bdddbb96a50329c78c797047c1f97f452ad33368bc52a292284efbb23926855a54dd8a6899ad53569451f3ce8e44bbc0e90
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- neetob (0.5.68)
4
+ neetob (0.5.69)
5
5
  actionview
6
6
  activesupport
7
7
  brakeman (~> 5.0)
@@ -19,6 +19,38 @@ module Neetob
19
19
 
20
20
  private
21
21
 
22
+ def strip_ansi_codes(str)
23
+ str.gsub(/\e\[[\d;]*m/, "")
24
+ end
25
+
26
+ def domain_to_repo(domain)
27
+ domain = domain.gsub(".com", "")
28
+
29
+ if domain == "neeto"
30
+ return "neeto-website"
31
+ end
32
+
33
+ if domain == "bigbinary"
34
+ return "bigbinary-website"
35
+ end
36
+
37
+ if domain.start_with?("neeto")
38
+ app = domain.sub("neeto", "neeto-")
39
+ else
40
+ app = domain
41
+ end
42
+ "#{app}-web"
43
+ end
44
+
45
+ def app_to_repo(app_name)
46
+ app_name = app_name.downcase
47
+
48
+ if app_name.start_with?("neeto")
49
+ app = app_name.sub("neeto", "neeto-")
50
+ end
51
+ "#{app}-web"
52
+ end
53
+
22
54
  def find_all_matching_apps_or_repos(apps, platform_name, sandbox_mode, quiet = false)
23
55
  all_neeto_repos = apps == ["all"]
24
56
  inform_about_current_working_mode(sandbox_mode, quiet)
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../base"
4
+
5
+ module Neetob
6
+ class CLI
7
+ module Github
8
+ module Issues
9
+ class Helpers < Base
10
+ def initialize
11
+ super()
12
+ end
13
+
14
+ def get_issue_with_title(repo, title)
15
+ begin
16
+ issues = client.issues(repo, state: "open")
17
+ issue = issues.find { |issue| issue.title == title }
18
+ issue
19
+ rescue StandardError => e
20
+ ExceptionHandler.new(e).process
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -9,9 +9,10 @@ module Neetob
9
9
  class Commands < Thor
10
10
  desc "perform", "Perform the audit"
11
11
  option :month, type: :string, aliases: "-m", required: true, desc: "Month. Example: June-2024"
12
+ option :skip_issue, type: :boolean, default: false, desc: "Skip creating GitHub issues"
12
13
 
13
14
  def perform
14
- Perform.new(options[:month], options[:sandbox]).run
15
+ Perform.new(options[:month], options[:sandbox], options[:skip_issue]).run
15
16
  end
16
17
  end
17
18
  end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "../github_issue_creation"
3
4
  module Neetob
4
5
  class CLI
5
6
  module MonthlyAudit
@@ -28,7 +29,11 @@ module Neetob
28
29
  if unique_email_index_result
29
30
  repo_data << [repo, "Yes", nil, "Yes"]
30
31
  else
31
- repo_data << [repo, "No", "Unique email index is not present for the users table", "No"]
32
+ issue_url = GithubIssueCreation.new.create_issue(
33
+ repo:, title: "Add unique index on users email",
34
+ description: "Unique email index is not present for the users table")
35
+ audit_passed = "No" + " #{issue_url}"
36
+ repo_data << [repo, "No", "Unique email index is not present for the users table", audit_passed]
32
37
  end
33
38
  end
34
39
  ui.print_table(repo_data)
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "../github_issue_creation"
4
+
3
5
  module Neetob
4
6
  class CLI
5
7
  module MonthlyAudit
@@ -40,6 +42,12 @@ module Neetob
40
42
  all_tables_have_uuid_primary_keys = tables_without_uuid.empty? ? "Yes" : "No"
41
43
  audit_passed = all_tables_have_uuid_primary_keys == "Yes" ? "Yes" : "No"
42
44
  comments = tables_without_uuid.empty? ? nil : "Tables without UUID primary keys: #{tables_without_uuid.join(', ')}"
45
+ if audit_passed == "No"
46
+ issue_url = GithubIssueCreation.new.create_issue(
47
+ repo:, title: "Use UUID primary keys for all tables",
48
+ description: comments)
49
+ audit_passed += " #{issue_url}"
50
+ end
43
51
  same_as_last_comment = audit_passed == "No" && comments == last_comment
44
52
  last_comment = comments
45
53
  if same_as_last_comment
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../github/base"
4
+ require_relative "../github/issues/helpers"
5
+ class GithubIssueCreation < Neetob::CLI::Github::Base
6
+ def initialize
7
+ super()
8
+ @helpers = Neetob::CLI::Github::Issues::Helpers.new
9
+ end
10
+
11
+ def create_issue(repo:, title:, description:, labels: "")
12
+ return if Thread.current[:skip_issue]
13
+
14
+ month = Thread.current[:month].capitalize.gsub("-", " ")
15
+ title = "#{month} Audit - #{title}"
16
+
17
+ # Checking if the issue already exists
18
+ issue = @helpers.get_issue_with_title("bigbinary/#{repo}", title)
19
+ if issue
20
+ return issue.html_url
21
+ end
22
+
23
+ begin
24
+ issue = client.create_issue(
25
+ "bigbinary/#{repo}",
26
+ title,
27
+ "## #{title} \n #{description}",
28
+ { labels: }
29
+ )
30
+ issue.html_url
31
+ rescue StandardError => e
32
+ ExceptionHandler.new(e).process
33
+ end
34
+ end
35
+ end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "../../github_issue_creation"
4
+
3
5
  module Neetob
4
6
  class CLI
5
7
  module MonthlyAudit
@@ -20,6 +22,15 @@ module Neetob
20
22
  ui.info("Checking Always use HTTPS value for #{domain}", print_to_audit_log: false)
21
23
  always_use_https_value = Neetob::CLI::Cloudflare::AlwaysUseHttps.new(domain).run
22
24
  audit_passed = always_use_https_value.to_s == "on" ? "Yes" : "No"
25
+
26
+ if audit_passed == "No"
27
+ repo = domain_to_repo(domain.to_s)
28
+ issue_url = GithubIssueCreation.new.create_issue(
29
+ repo:, title: "Enable HTTPS for domain",
30
+ description: "HTTPs is not enabled for #{domain}.")
31
+ audit_passed += " #{issue_url}"
32
+ end
33
+
23
34
  domains_data << [domain, always_use_https_value, audit_passed]
24
35
  end
25
36
  ui.print_table(domains_data)
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "../../github_issue_creation"
3
4
  module Neetob
4
5
  class CLI
5
6
  module MonthlyAudit
@@ -20,6 +21,14 @@ module Neetob
20
21
  bot_fight_mode = Neetob::CLI::Cloudflare::BotFightMode.new(domain).run
21
22
  ui.info("Checking Bot fight mode for #{domain}", print_to_audit_log: false)
22
23
  audit_passed = bot_fight_mode == "on" ? "Yes" : "No"
24
+
25
+ if audit_passed == "No"
26
+ repo = domain_to_repo(domain.to_s)
27
+ issue_url = GithubIssueCreation.new.create_issue(
28
+ repo:, title: "Enable bot protection for #{domain}",
29
+ description: "Bot Protection is not enabled for #{domain}.")
30
+ audit_passed += " #{issue_url}"
31
+ end
23
32
  domains_data << [domain, bot_fight_mode, audit_passed]
24
33
  end
25
34
  ui.print_table(domains_data)
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "../../github_issue_creation"
4
+
3
5
  module Neetob
4
6
  class CLI
5
7
  module MonthlyAudit
@@ -39,6 +41,13 @@ module Neetob
39
41
  dns_proxy_status = "* record has proxying turned #{proxy_status}"
40
42
  same_as_last_dns_proxy_status = dns_proxy_status == last_dns_proxy_status
41
43
  last_dns_proxy_status = dns_proxy_status
44
+ if audit_passed == "No"
45
+ repo = domain_to_repo(domain.to_s)
46
+ issue_url = GithubIssueCreation.new.create_issue(
47
+ repo:, title: "Enable proxying for wildcard DNS on #{domain}",
48
+ description: dns_proxy_status)
49
+ audit_passed += " #{issue_url}"
50
+ end
42
51
  if same_as_last_dns_proxy_status
43
52
  dns_proxy_status = "''"
44
53
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "../../../cloudflare/min_tls_version"
4
+ require_relative "../../github_issue_creation"
4
5
 
5
6
  module Neetob
6
7
  class CLI
@@ -22,6 +23,16 @@ module Neetob
22
23
  ui.info("Checking Minimum TLS version for #{domain}", print_to_audit_log: false)
23
24
  min_tls_version = Neetob::CLI::Cloudflare::MinTlsVersion.new(domain).run
24
25
  audit_passed = min_tls_version.to_s == "1.2" ? "Yes" : "No"
26
+
27
+ if audit_passed == "No"
28
+ repo = domain_to_repo(domain.to_s)
29
+ issue_url = GithubIssueCreation.new.create_issue(
30
+ repo:, title: "Set minimum TLS version to 1.2 for #{domain}",
31
+ description: "Minimum TLS version for #{domain} is set to #{min_tls_version}. It should be set to '1.2'."
32
+ )
33
+ audit_passed += " #{issue_url}"
34
+ end
35
+
25
36
  domains_data << [domain, min_tls_version, audit_passed]
26
37
  end
27
38
  ui.print_table(domains_data)
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "../../github_issue_creation"
3
4
  module Neetob
4
5
  class CLI
5
6
  module MonthlyAudit
@@ -29,6 +30,14 @@ module Neetob
29
30
  data = spf_records_verification_data[:spf_txt_records].map { |record|
30
31
  "#{record[:name]} => #{record[:content]}"
31
32
  }.join(", ")
33
+
34
+ if audit_passed == "No"
35
+ repo = domain_to_repo(domain.to_s)
36
+ issue_url = GithubIssueCreation.new.create_issue(
37
+ repo:, title: "Fix invalid SPF records for #{domain}",
38
+ description: "#{comments} \n\n SPF records data: #{data}")
39
+ audit_passed += " #{issue_url}"
40
+ end
32
41
  domains_data << [domain, data, comments, audit_passed]
33
42
  end
34
43
  ui.print_table(domains_data)
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "../../../cloudflare/ssl_mode"
4
+ require_relative "../../github_issue_creation"
4
5
 
5
6
  module Neetob
6
7
  class CLI
@@ -22,6 +23,14 @@ module Neetob
22
23
  ui.info("Checking SSL/TLS encryption mode for #{domain}", print_to_audit_log: false)
23
24
  ssl_mode = Neetob::CLI::Cloudflare::SSLMode.new(domain).run
24
25
  audit_passed = ssl_mode.to_s == "full" ? "Yes" : "No"
26
+ repo = domain_to_repo(domain.to_s)
27
+ if audit_passed == "No"
28
+ comments = "SSL/TLS encryption mode is set to #{ssl_mode}. It should be set to 'Full'."
29
+ issue_url = GithubIssueCreation.new.create_issue(
30
+ repo:, title: "Set SSL TLS mode to Full for #{domain}",
31
+ description: comments)
32
+ audit_passed += " #{issue_url}"
33
+ end
25
34
  domains_data << [domain, ssl_mode, audit_passed]
26
35
  end
27
36
  ui.print_table(domains_data)
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "../../../cronitor/get_all_monitors"
4
+ require_relative "../../github_issue_creation"
4
5
 
5
6
  module Neetob
6
7
  class CLI
@@ -42,6 +43,15 @@ module Neetob
42
43
  end
43
44
  end
44
45
 
46
+ if audit_passed == "No"
47
+ repo = app_to_repo(app.to_s)
48
+ issue_url = GithubIssueCreation.new.create_issue(
49
+ repo:, title: "Fix missing or paused Cronitor monitor for #{app}",
50
+ description: " Monitor for Application present:#{monitor_for_app_present}
51
+ \n Monitor for Application enabled:#{monitor_for_app_enabled} \n #{comments}")
52
+ audit_passed += " #{issue_url}"
53
+ end
54
+
45
55
  apps_data << [app, monitor_for_app_present, monitor_for_app_enabled, comments, audit_passed]
46
56
  end
47
57
 
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "../../github_issue_creation"
4
+
3
5
  module Neetob
4
6
  class CLI
5
7
  module MonthlyAudit
@@ -47,6 +49,16 @@ module Neetob
47
49
  audit_passed = "Ignored"
48
50
  end
49
51
 
52
+ if audit_passed == "No"
53
+ repo = app_to_repo(app.to_s)
54
+ issue_url = GithubIssueCreation.new.create_issue(
55
+ repo:, title: "Fix missing or paused Cronitor monitor for #{app} help center",
56
+ description: " Monitor for Application help center present:#{monitor_for_app_help_center_present}
57
+ \n Monitor for Application help center enabled:#{monitor_for_app_help_center_enabled} \n #{comments}"
58
+ )
59
+ audit_passed += " #{issue_url}"
60
+ end
61
+
50
62
  apps_data << [app, monitor_for_app_help_center_present, monitor_for_app_help_center_enabled, comments,
51
63
  audit_passed]
52
64
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "../../github_issue_creation"
4
+
3
5
  module Neetob
4
6
  class CLI
5
7
  module MonthlyAudit
@@ -49,6 +51,16 @@ module Neetob
49
51
  audit_passed = "Ignored"
50
52
  end
51
53
 
54
+ if audit_passed == "No"
55
+ repo = app_to_repo(app.to_s)
56
+ issue_url = GithubIssueCreation.new.create_issue(
57
+ repo:, title: "Fix missing or paused Cronitor monitor for #{app} landing page",
58
+ description: " Monitor for Application landing page present:#{monitor_for_app_landing_page_present}
59
+ \n Monitor for Application landing page enabled:#{monitor_for_app_landing_page_enabled} \n #{comments}"
60
+ )
61
+ audit_passed += " #{issue_url}"
62
+ end
63
+
52
64
  apps_data << [app, monitor_for_app_landing_page_present, monitor_for_app_landing_page_enabled,
53
65
  comments, audit_passed]
54
66
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "../../github_issue_creation"
4
+
3
5
  module Neetob
4
6
  class CLI
5
7
  module MonthlyAudit
@@ -22,6 +24,7 @@ module Neetob
22
24
  audit_passed = nil
23
25
  comments = nil
24
26
  autoscaling_config = nil
27
+ repo = app.gsub("-production", "")
25
28
  if autoscaling_config_result.is_a?(Hash) && autoscaling_config_result["error"] == "Forbidden"
26
29
  audit_passed = "No"
27
30
  comments = "You do not have permission to access the config for this app."
@@ -32,6 +35,10 @@ module Neetob
32
35
  audit_passed = autoscaling_turned_on_for_web ? "Yes" : "No"
33
36
  if audit_passed == "No"
34
37
  comments = "Auto-scaling is not enabled for web dynos."
38
+ issue_url = GithubIssueCreation.new.create_issue(
39
+ repo:, title: "Enable auto scaling for web dynos",
40
+ description: comments)
41
+ audit_passed += " #{issue_url}"
35
42
  same_as_last_comment = comments == last_comment
36
43
  last_comment = comments
37
44
  comments = "''" if same_as_last_comment
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "../../github_issue_creation"
3
4
  module Neetob
4
5
  class CLI
5
6
  module MonthlyAudit
@@ -26,6 +27,7 @@ module Neetob
26
27
  audit_passed = nil
27
28
  comments = nil
28
29
  asset_host_value = nil
30
+ repo = app.gsub("-production", "")
29
31
  if config_vars.is_a?(Hash) && config_vars["error"] == "Forbidden"
30
32
  audit_passed = "No"
31
33
  comments = "You do not have permission to access the config vars for this app."
@@ -34,6 +36,10 @@ module Neetob
34
36
  if asset_host_line.nil?
35
37
  audit_passed = "No"
36
38
  comments = "ASSET_HOST value not found."
39
+ issue_url = GithubIssueCreation.new.create_issue(
40
+ repo:, title: "Cloudfront CDN audit failed",
41
+ description: comments)
42
+ audit_passed += " #{issue_url}"
37
43
  else
38
44
  asset_host_value = asset_host_line.split("|")[2].strip
39
45
  is_direct_cloudfront_asset_host = asset_host_value.include?("cloudfront.net")
@@ -41,9 +47,14 @@ module Neetob
41
47
  audit_passed = is_direct_cloudfront_asset_host || is_cdn_subdomain_asset_host ? "Yes" : "No"
42
48
  if audit_passed == "No"
43
49
  comments = "ASSET_HOST value is not a Cloudfront CDN URL or a CDN subdomain URL."
50
+ issue_url = GithubIssueCreation.new.create_issue(
51
+ repo:, title: "Set ASSET_HOST to a valid Cloudfront CDN URL",
52
+ description: comments)
53
+ audit_passed += " #{issue_url}"
44
54
  end
45
55
  end
46
56
  end
57
+
47
58
  apps_data << [app, asset_host_value, comments, audit_passed]
48
59
  end
49
60
  Neetob::CLI::Sre::Base::APPS_LIST[:heroku].select { |app| app.include?("production") }.each do |app|
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "../../github_issue_creation"
3
4
  module Neetob
4
5
  class CLI
5
6
  module MonthlyAudit
@@ -15,12 +16,14 @@ module Neetob
15
16
 
16
17
  apps_data = [["App", "All essential env variables set", "Comments", "Audit Passed"]]
17
18
  ui.info("\n", print_to_audit_log: false)
19
+
18
20
  Neetob::CLI::Sre::Base::APPS_LIST[:neetodeploy].select { |app| app.include?("production") }.each do |app|
19
21
  ui.info("Checking essential env variables for #{app}", print_to_audit_log: false)
20
22
  essential_env_variables_result = Neetob::CLI::Sre::CheckEssentialEnv.new(app).run
21
23
  audit_passed = nil
22
24
  comments = nil
23
25
  all_essential_env_variables_set = nil
26
+ repo = app.gsub("-production", "")
24
27
  if essential_env_variables_result["error"] == "Forbidden"
25
28
  audit_passed = "No"
26
29
  comments = "You do not have permission to access the config vars for this app."
@@ -29,6 +32,10 @@ module Neetob
29
32
  audit_passed = all_essential_env_variables_set ? "Yes" : "No"
30
33
  if audit_passed == "No"
31
34
  comments = "Missing keys: #{essential_env_variables_result[:missing_keys].join(", ")}"
35
+ issue_url = GithubIssueCreation.new.create_issue(
36
+ repo:, title: "Missing essential environment variables",
37
+ description: comments)
38
+ audit_passed += " #{issue_url}"
32
39
  end
33
40
  end
34
41
  apps_data << [app, all_essential_env_variables_set, comments, audit_passed]
@@ -38,8 +45,13 @@ module Neetob
38
45
  essential_env_variables_result = Neetob::CLI::Sre::CheckEssentialEnv.new(app).run
39
46
  all_essential_env_variables_set = essential_env_variables_result[:all_keys_present]
40
47
  audit_passed = all_essential_env_variables_set ? "Yes" : "No"
48
+ repo = app.gsub("-production", "")
41
49
  if audit_passed == "No"
42
50
  comments = "Missing keys: #{essential_env_variables_result[:missing_keys].join(", ")}"
51
+ issue_url = GithubIssueCreation.new.create_issue(
52
+ repo:, title: "Add missing essential environment variables",
53
+ description: comments)
54
+ audit_passed += " #{issue_url}"
43
55
  end
44
56
  apps_data << [app, all_essential_env_variables_set, comments, audit_passed]
45
57
  end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "../../github_issue_creation"
3
4
  module Neetob
4
5
  class CLI
5
6
  module MonthlyAudit
@@ -22,6 +23,7 @@ module Neetob
22
23
  audit_passed = nil
23
24
  comments = nil
24
25
  scheduled_exports_config = nil
26
+ repo = app.gsub("-production", "")
25
27
  if scheduled_exports_result.include? "Forbidden"
26
28
  audit_passed = "No"
27
29
  comments = "You do not have permission to access the config for this app."
@@ -34,6 +36,10 @@ module Neetob
34
36
  audit_passed = scheduled_exports_config.include?("turned on") ? "Yes" : "No"
35
37
  if audit_passed == "No"
36
38
  comments = scheduled_exports_config
39
+ issue_url = GithubIssueCreation.new.create_issue(
40
+ repo:, title: "Enable scheduled exports",
41
+ description: strip_ansi_codes(comments))
42
+ audit_passed += " #{issue_url}"
37
43
  end
38
44
  same_as_last_scheduled_export_config = scheduled_exports_config == last_scheduled_exports_config
39
45
  last_scheduled_exports_config = scheduled_exports_config
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "../../github_issue_creation"
4
+
3
5
  module Neetob
4
6
  class CLI
5
7
  module MonthlyAudit
@@ -53,6 +55,11 @@ module Neetob
53
55
  "#{certificate["name"]}(#{certificate["domains"].map { |domain| domain["hostname"] }.join(", ")})"
54
56
  }
55
57
  comments = "Certificates #{certificates_failing_audit.join(", ")} are expiring in less than 30 days."
58
+ repo = app.gsub("-production", "")
59
+ issue_url = GithubIssueCreation.new.create_issue(
60
+ repo:, title: "SSL certificates over 30 days from expiry",
61
+ description: comments)
62
+ audit_passed += " #{issue_url}"
56
63
  end
57
64
  end
58
65
  apps_data << [app, certificates_expiring_in_less_than_30_days, comments, audit_passed]
@@ -68,6 +75,11 @@ module Neetob
68
75
  audit_passed = "Yes"
69
76
  else
70
77
  comments = "Certificates #{certificates_expiring_in_less_than_30_days.map { |certificate| certificate[:name] }.join(", ")} are expiring in less than 30 days."
78
+ repo = app.gsub("-production", "")
79
+ issue_url = GithubIssueCreation.new.create_issue(
80
+ repo:, title: "Renew SSL certificates expiring in less than 30 days",
81
+ description: comments)
82
+ audit_passed += " #{issue_url}"
71
83
  certificates_expiring_in_less_than_30_days_present = "Yes"
72
84
  end
73
85
  apps_data << [app, certificates_expiring_in_less_than_30_days_present, comments, audit_passed]
@@ -1,12 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "../github_issue_creation"
4
+
3
5
  module Neetob
4
6
  class CLI
5
7
  module MonthlyAudit
6
8
  module Misc
7
9
  class RedirectionsWorkingCorrectly < CLI::Base
8
10
  REDIRECTIONS_LIST = [
9
- { source: "https://academy.bigbinary.com", destination: "https://bigbinaryacademy.com" }
11
+ {
12
+ source: "https://academy.bigbinary.com", destination: "https://bigbinaryacademy.com",
13
+ repo: "bigbinary-website"
14
+ },
10
15
  ]
11
16
  def initialize
12
17
  super()
@@ -19,6 +24,14 @@ module Neetob
19
24
  status = check.run ? "Working" : "Not working"
20
25
  audit_passed = status == "Working" ? "Yes" : "No"
21
26
 
27
+ if audit_passed == "No"
28
+ issue_url = GithubIssueCreation.new.create_issue(
29
+ repo: redirection[:repo], title: "Fix broken redirection",
30
+ description: "Redirection from #{redirection[:source]} to #{redirection[:destination]} is not working."
31
+ )
32
+ audit_passed += " #{issue_url}"
33
+ end
34
+
22
35
  table_data << [redirection[:source], redirection[:destination], status, audit_passed]
23
36
  end
24
37
  ui.print_table(table_data)
@@ -9,20 +9,25 @@ module Neetob
9
9
  class CLI
10
10
  module MonthlyAudit
11
11
  class Perform < CLI::Base
12
- attr_accessor :sandbox, :month
12
+ attr_accessor :sandbox, :month, :skip_issue
13
13
 
14
- def initialize(month, sandbox = false)
14
+ def initialize(month, sandbox = false, skip_issue = false)
15
15
  super()
16
16
  @month = month
17
17
  @sandbox = sandbox
18
+ @skip_issue = skip_issue
18
19
  end
19
20
 
20
21
  def run
22
+ Thread.current[:month] = month
23
+ Thread.current[:skip_issue] = skip_issue
21
24
  Thread.current[:audit_mode] = true
22
25
  markdown_file_name = "audit-report-#{DateTime.now.to_i}.md"
23
26
  Thread.current[:markdown_file_name] = markdown_file_name
24
27
  ui.success("## Starting the audit for #{month}")
25
28
  ui.info "\n"
29
+ ui.say("## Issue creation is #{skip_issue ? 'disabled' : 'enabled'}")
30
+ ui.info "\n"
26
31
  Security::Main.new.run
27
32
  ui.info "\n"
28
33
  Databases::Main.new.run
@@ -16,18 +16,23 @@ module Neetob
16
16
  ui.success("### 1.1.4. Checking whether running `rake active_record_doctor` throws any vulnerabilities")
17
17
  repo_data = [["Repository", "Issues Found", "Comments", "Audit Passed"]]
18
18
  ui.info "\n"
19
- NeetoCompliance::NeetoRepos.products.keys.take(5).each do |repo|
19
+ NeetoCompliance::NeetoRepos.products.keys.each do |repo|
20
20
  ui.info("Checking ActiveRecordDoctor run results for #{repo}", print_to_audit_log: false)
21
21
  active_record_doctor_run_result = Neetob::CLI::Github::ActiveRecordDoctor.new([repo]).run
22
-
22
+ audit_passed = "No"
23
23
  if active_record_doctor_run_result.blank?
24
- issues_found = "No"
24
+ audit_passed = "Yes"
25
25
  comments = nil
26
26
  else
27
27
  issues_found = "Yes"
28
28
  comments = "#{active_record_doctor_run_result.lines.first.strip} ..."
29
+
30
+ issue_url = GithubIssueCreation.new.create_issue(
31
+ repo:, title: "Fix issues reported by active_record_doctor",
32
+ description: comments)
33
+ audit_passed += " #{issue_url}"
29
34
  end
30
- audit_passed = issues_found == "No" ? "Yes" : "No"
35
+
31
36
  repo_data << [repo, issues_found, comments, audit_passed]
32
37
  end
33
38
  ui.print_table(repo_data)
@@ -25,6 +25,11 @@ module Neetob
25
25
  else
26
26
  vulnerabilities_found = "Yes"
27
27
  comments = brakeman_run_result.gsub("\n", "<br>")
28
+
29
+ issue_url = GithubIssueCreation.new.create_issue(
30
+ repo:, title: "Fix vulnerabilities reported by Brakeman",
31
+ description: comments)
32
+ audit_passed += " #{issue_url}"
28
33
  end
29
34
  repo_data << [repo, vulnerabilities_found, comments, audit_passed]
30
35
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "../../../github/bundle_audit"
4
-
4
+ require_relative "../../github_issue_creation"
5
5
  module Neetob
6
6
  class CLI
7
7
  module MonthlyAudit
@@ -26,9 +26,13 @@ module Neetob
26
26
  if bundle_audit_result && bundle_audit_result.include?("No vulnerabilities found")
27
27
  audit_passed = "Yes"
28
28
  else
29
+
29
30
  vulnerabilities_found = "Yes"
30
31
  comments = bundle_audit_result.gsub("\n", "<br>").gsub("~", "\\~")
31
-
32
+ issue_url = GithubIssueCreation.new.create_issue(
33
+ repo:, title: "Fix vulnerabilities reported by bundle-audit",
34
+ description: comments)
35
+ audit_passed += " #{issue_url}"
32
36
  same_as_last_vulnerabilities = comments == last_comment
33
37
  last_comment = comments
34
38
  if same_as_last_vulnerabilities
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "../../../github/unused_assets_audit"
4
+ require_relative "../../github_issue_creation"
4
5
 
5
6
  module Neetob
6
7
  class CLI
@@ -24,6 +25,10 @@ module Neetob
24
25
  unused_assets_found = "Yes"
25
26
  audit_passed = "No"
26
27
  comments = unused_files.join("<br>")
28
+ issue_url = GithubIssueCreation.new.create_issue(
29
+ repo:, title: "Remove unused assets",
30
+ description: comments)
31
+ audit_passed += " #{issue_url}"
27
32
  else
28
33
  unused_assets_found = "No"
29
34
  audit_passed = "Yes"
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "../../../github/fasterer_audit"
4
+ require_relative "../../github_issue_creation"
4
5
 
5
6
  module Neetob
6
7
  class CLI
@@ -27,6 +28,13 @@ module Neetob
27
28
  comments = "Vulnerabilities not detected"
28
29
  else
29
30
  optimizations_needed = "Yes"
31
+ comments = strip_ansi_codes(fasterer_exec_result).gsub("\n", "<br>")
32
+
33
+ issue_url = GithubIssueCreation.new.create_issue(
34
+ repo:, title: "Fasterer suggestions to improve performance",
35
+ description: comments)
36
+ audit_passed += " #{issue_url}"
37
+
30
38
  comments = "Vulnerabilities detected"
31
39
  end
32
40
  repo_data << [repo, optimizations_needed, comments, audit_passed]
@@ -31,6 +31,11 @@ line.include?("Severity:") }.first&.strip&.gsub("|", ",")
31
31
  vulnerabilities = yarn_audit_result.split("\n").select { |line|
32
32
  line.include?("vulnerabilities found") }.first&.strip
33
33
  comments = "#{vulnerabilities}<br>#{severity}"
34
+
35
+ issue_url = GithubIssueCreation.new.create_issue(
36
+ repo:, title: "Yarn audit: High/Critical vulnerabilities found",
37
+ description: comments)
38
+ audit_passed += " #{issue_url}"
34
39
  end
35
40
  repo_data << [repo, vulnerabilities_found, comments, audit_passed]
36
41
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "../../../github/repositories/pull_requests"
4
+ require_relative "../../github_issue_creation"
4
5
 
5
6
  module Neetob
6
7
  class CLI
@@ -35,6 +36,10 @@ module Neetob
35
36
  audit_passed = dependabot_prs_older_than_2_days_merged = "Yes"
36
37
  else
37
38
  comments = "PRs older than 2 days: #{dependabot_prs_older_than_2_days.map { |pr| pr[:number] }.join(', ')}"
39
+ issue_url = GithubIssueCreation.new.create_issue(
40
+ repo:, title: "Merge Dependabot PRs older than 2 days",
41
+ description: comments)
42
+ audit_passed += " #{issue_url}"
38
43
  end
39
44
  repo_data << [repo, dependabot_prs_older_than_2_days_merged, comments, audit_passed]
40
45
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Neetob
4
- VERSION = "0.5.68"
4
+ VERSION = "0.5.69"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: neetob
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.68
4
+ version: 0.5.69
5
5
  platform: ruby
6
6
  authors:
7
7
  - Udai Gupta
@@ -245,6 +245,7 @@ files:
245
245
  - lib/neetob/cli/github/issues/commands.rb
246
246
  - lib/neetob/cli/github/issues/create.rb
247
247
  - lib/neetob/cli/github/issues/create_product_sub_issues.rb
248
+ - lib/neetob/cli/github/issues/helpers.rb
248
249
  - lib/neetob/cli/github/issues/list.rb
249
250
  - lib/neetob/cli/github/labels/commands.rb
250
251
  - lib/neetob/cli/github/labels/delete.rb
@@ -287,6 +288,7 @@ files:
287
288
  - lib/neetob/cli/monthly_audit/databases/main.rb
288
289
  - lib/neetob/cli/monthly_audit/databases/users_unique_email_index.rb
289
290
  - lib/neetob/cli/monthly_audit/databases/uuid_primary_key.rb
291
+ - lib/neetob/cli/monthly_audit/github_issue_creation.rb
290
292
  - lib/neetob/cli/monthly_audit/instances_and_addons/cloudflare/always_use_https_is_enabled.rb
291
293
  - lib/neetob/cli/monthly_audit/instances_and_addons/cloudflare/bot_protection_enabled.rb
292
294
  - lib/neetob/cli/monthly_audit/instances_and_addons/cloudflare/dns_entry_has_proxy_status.rb