neetob 0.5.16 → 0.5.18

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 (70) hide show
  1. checksums.yaml +4 -4
  2. data/.env +4 -0
  3. data/.neetoci/default.yml +1 -1
  4. data/.ruby-version +1 -1
  5. data/Gemfile +1 -1
  6. data/Gemfile.lock +108 -109
  7. data/lib/neetob/cli/cloudflare/always_use_https.rb +7 -2
  8. data/lib/neetob/cli/cloudflare/bot_fight_mode.rb +7 -2
  9. data/lib/neetob/cli/cloudflare/dns_proxy_status.rb +8 -2
  10. data/lib/neetob/cli/cloudflare/min_tls_version.rb +8 -2
  11. data/lib/neetob/cli/cloudflare/ssl_mode.rb +4 -1
  12. data/lib/neetob/cli/cloudflare/verify_spf.rb +21 -8
  13. data/lib/neetob/cli/code/audit.rb +19 -7
  14. data/lib/neetob/cli/cronitor/base.rb +49 -0
  15. data/lib/neetob/cli/cronitor/get_all_monitors.rb +21 -0
  16. data/lib/neetob/cli/github/base.rb +3 -2
  17. data/lib/neetob/cli/github/brakeman.rb +7 -3
  18. data/lib/neetob/cli/github/bundle_audit.rb +52 -0
  19. data/lib/neetob/cli/github/make_pr/base.rb +10 -2
  20. data/lib/neetob/cli/github/repositories/get_security_details.rb +45 -0
  21. data/lib/neetob/cli/github/repositories/pull_requests.rb +34 -0
  22. data/lib/neetob/cli/github/yarn_audit.rb +47 -0
  23. data/lib/neetob/cli/monthly_audit/commands.rb +19 -0
  24. data/lib/neetob/cli/monthly_audit/databases/main.rb +29 -0
  25. data/lib/neetob/cli/monthly_audit/databases/users_unique_email_index.rb +40 -0
  26. data/lib/neetob/cli/monthly_audit/databases/uuid_primary_key.rb +45 -0
  27. data/lib/neetob/cli/monthly_audit/instances_and_addons/cloudflare/always_use_https_is_enabled.rb +32 -0
  28. data/lib/neetob/cli/monthly_audit/instances_and_addons/cloudflare/bot_protection_enabled.rb +32 -0
  29. data/lib/neetob/cli/monthly_audit/instances_and_addons/cloudflare/dns_entry_has_proxy_status.rb +41 -0
  30. data/lib/neetob/cli/monthly_audit/instances_and_addons/cloudflare/main.rb +38 -0
  31. data/lib/neetob/cli/monthly_audit/instances_and_addons/cloudflare/minimum_tls_version_is_one_point_two.rb +34 -0
  32. data/lib/neetob/cli/monthly_audit/instances_and_addons/cloudflare/spf_records_are_valid.rb +41 -0
  33. data/lib/neetob/cli/monthly_audit/instances_and_addons/cloudflare/ssl_tls_encryption_mode_set_to_full.rb +34 -0
  34. data/lib/neetob/cli/monthly_audit/instances_and_addons/cronitor/main.rb +29 -0
  35. data/lib/neetob/cli/monthly_audit/instances_and_addons/cronitor/setup_correctly_for_apps.rb +54 -0
  36. data/lib/neetob/cli/monthly_audit/instances_and_addons/cronitor/setup_correctly_for_help_center.rb +53 -0
  37. data/lib/neetob/cli/monthly_audit/instances_and_addons/cronitor/setup_correctly_for_landing_pages.rb +53 -0
  38. data/lib/neetob/cli/monthly_audit/instances_and_addons/honeybadger/main.rb +23 -0
  39. data/lib/neetob/cli/monthly_audit/instances_and_addons/honeybadger/setup_correctly_for_apps.rb +49 -0
  40. data/lib/neetob/cli/monthly_audit/instances_and_addons/main.rb +40 -0
  41. data/lib/neetob/cli/monthly_audit/instances_and_addons/neeto_deploy/auto_scaling_enabled.rb +46 -0
  42. data/lib/neetob/cli/monthly_audit/instances_and_addons/neeto_deploy/cloudfront_cdn_enabled.rb +56 -0
  43. data/lib/neetob/cli/monthly_audit/instances_and_addons/neeto_deploy/essential_environment_variables_set.rb +43 -0
  44. data/lib/neetob/cli/monthly_audit/instances_and_addons/neeto_deploy/main.rb +35 -0
  45. data/lib/neetob/cli/monthly_audit/instances_and_addons/neeto_deploy/scheduled_exports_enabled.rb +43 -0
  46. data/lib/neetob/cli/monthly_audit/instances_and_addons/neeto_deploy/ssl_certificates_over_thirty_days_from_expiry.rb +41 -0
  47. data/lib/neetob/cli/monthly_audit/misc/main.rb +32 -0
  48. data/lib/neetob/cli/monthly_audit/misc/redirections_working_correctly.rb +30 -0
  49. data/lib/neetob/cli/monthly_audit/misc/sparkpost_sub_account_used_for_all_apps.rb +32 -0
  50. data/lib/neetob/cli/monthly_audit/misc/ssl_certs_setup_for_auto_renewal.rb +29 -0
  51. data/lib/neetob/cli/monthly_audit/perform.rb +41 -0
  52. data/lib/neetob/cli/monthly_audit/security/code/brakeman.rb +38 -0
  53. data/lib/neetob/cli/monthly_audit/security/code/bundle_audit.rb +40 -0
  54. data/lib/neetob/cli/monthly_audit/security/code/main.rb +29 -0
  55. data/lib/neetob/cli/monthly_audit/security/code/yarn_audit.rb +44 -0
  56. data/lib/neetob/cli/monthly_audit/security/github/dependabot_prs_merged.rb +48 -0
  57. data/lib/neetob/cli/monthly_audit/security/github/dependabot_turned_on.rb +44 -0
  58. data/lib/neetob/cli/monthly_audit/security/github/main.rb +26 -0
  59. data/lib/neetob/cli/monthly_audit/security/main.rb +31 -0
  60. data/lib/neetob/cli/neeto_deploy/autoscaling_config.rb +6 -1
  61. data/lib/neetob/cli/neeto_deploy/certificates.rb +3 -0
  62. data/lib/neetob/cli/neeto_deploy/config_vars/list.rb +8 -2
  63. data/lib/neetob/cli/neeto_deploy/scheduled_exports.rb +6 -1
  64. data/lib/neetob/cli/redirections/check.rb +13 -3
  65. data/lib/neetob/cli/sre/base.rb +10 -0
  66. data/lib/neetob/cli/sre/check_essential_env.rb +18 -3
  67. data/lib/neetob/cli/ui.rb +43 -3
  68. data/lib/neetob/cli.rb +4 -0
  69. data/lib/neetob/version.rb +1 -1
  70. metadata +48 -5
@@ -16,8 +16,11 @@ module Neetob
16
16
 
17
17
  def run
18
18
  matching_apps = find_all_matching_apps_or_repos(apps, :github, sandbox)
19
- ui.info("\nListing apps and their tables that doesn't have uuid as primary key type:-")
19
+ ui.info(
20
+ "\nListing apps and their tables that doesn't have uuid as primary key type:-",
21
+ print_to_audit_log: false)
20
22
  has_found_tables_without_uuid = false
23
+ data = []
21
24
  matching_apps.each do |app|
22
25
  begin
23
26
  db_schema = Base64.decode64(client.contents(app, path: "./db/schema.rb").content)
@@ -26,14 +29,21 @@ module Neetob
26
29
  has_found_tables_without_uuid = true
27
30
  print_app_and_tables(app, tables_without_uuid)
28
31
  end
29
- verify_unique_email_index(db_schema)
32
+ unique_email_index_result = verify_unique_email_index(db_schema)
33
+ data << { tables_without_uuid:, unique_email_index_result: }
30
34
  rescue Octokit::NotFound
31
35
  ui.error("There is no \"db/schema.rb\" file in the \"#{app}\" app.")
36
+ data << { error: "There is no \"db/schema.rb\" file in the \"#{app}\" app." }
32
37
  rescue StandardError => e
33
38
  ExceptionHandler.new(e).process
34
39
  end
35
40
  end
36
- ui.info("No apps found to have tables without uuid as primary key type") if !has_found_tables_without_uuid
41
+ ui.info(
42
+ "No apps found to have tables without uuid as primary key type",
43
+ print_to_audit_log: false) if !has_found_tables_without_uuid
44
+ if Thread.current[:audit_mode]
45
+ data
46
+ end
37
47
  end
38
48
 
39
49
  private
@@ -62,15 +72,17 @@ module Neetob
62
72
  )
63
73
  /mx
64
74
 
65
- if db_schema.match(index_pattern)
66
- ui.success("\nUsers are indexed properly")
75
+ index_pattern_matched = db_schema.match(index_pattern)
76
+ if index_pattern_matched
77
+ ui.success("\nUsers are indexed properly", print_to_audit_log: false)
67
78
  else
68
- ui.error("\nUsers are not indexed")
79
+ ui.error("\nUsers are not indexed", print_to_audit_log: false)
69
80
  end
81
+ index_pattern_matched
70
82
  end
71
83
 
72
84
  def print_app_and_tables(app, tables)
73
- ui.info("\n#{app}:-")
85
+ ui.info("\n#{app}:-", print_to_audit_log: false)
74
86
  tables.each do |table|
75
87
  ui.say(" ↳#{table}")
76
88
  end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../base"
4
+
5
+ module Neetob
6
+ class CLI
7
+ module Cronitor
8
+ class Base < CLI::Base
9
+ MONITORS_URL = "https://cronitor.io/api/monitors"
10
+
11
+ def initialize
12
+ super()
13
+ end
14
+
15
+ def process(*args)
16
+ raise(StandardError, "CRONITOR_ONE_API_KEY is not given") if ENV["CRONITOR_ONE_API_KEY"].nil?
17
+ raise(StandardError, "CRONITOR_THREE_API_KEY is not given") if ENV["CRONITOR_THREE_API_KEY"].nil?
18
+
19
+ run(*args)
20
+ end
21
+
22
+ private
23
+
24
+ def parse_response(http_result)
25
+ case http_result
26
+ when Net::HTTPSuccess
27
+ JSON.parse(http_result.body, symbolize_names: true)
28
+ else
29
+ error_message = JSON.parse(http_result.body)["errors"][0]["message"]
30
+ raise(StandardError, "Request failed with status code #{http_result.code}: #{error_message}")
31
+ end
32
+ end
33
+
34
+ def get(username:, password:, headers: { "Accept" => "application/json" })
35
+ uri = URI(MONITORS_URL)
36
+ request = Net::HTTP::Get.new(uri)
37
+ headers.each { |key, value| request[key] = value }
38
+ request.basic_auth(username, password)
39
+
40
+ response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == "https") do |http|
41
+ http.request(request)
42
+ end
43
+
44
+ parse_response(response)
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "./base"
4
+
5
+ module Neetob
6
+ class CLI
7
+ module Cronitor
8
+ class GetAllMonitors < Base
9
+ def initialize
10
+ super()
11
+ end
12
+
13
+ def run
14
+ cronitor_one_monitors = get(username: ENV["CRONITOR_ONE_API_KEY"], password: "")[:monitors]
15
+ cronitor_three_monitors = get(username: ENV["CRONITOR_THREE_API_KEY"], password: "")[:monitors]
16
+ cronitor_one_monitors + cronitor_three_monitors
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -12,7 +12,7 @@ module Neetob
12
12
  module Github
13
13
  class Base < CLI::Base
14
14
  include Utils
15
- attr_accessor :client
15
+ attr_accessor :client, :access_token
16
16
 
17
17
  def initialize
18
18
  super()
@@ -20,7 +20,8 @@ module Neetob
20
20
  unless auth_client.token_persisted?
21
21
  auth_client.start_oauth2_device_flow
22
22
  end
23
- @client = Octokit::Client.new(access_token: auth_client.access_token)
23
+ @access_token = auth_client.access_token
24
+ @client = Octokit::Client.new(access_token:)
24
25
  end
25
26
 
26
27
  private
@@ -17,15 +17,16 @@ module Neetob
17
17
 
18
18
  def run
19
19
  matching_repos = find_all_matching_apps_or_repos(repos, :github, sandbox)
20
+ report = nil
20
21
  matching_repos.each do |repo|
21
22
  begin
22
- ui.info("\nWorking on repo #{repo}")
23
+ ui.info("\nWorking on repo #{repo}", print_to_audit_log: false)
23
24
  clone_repo_in_tmp_dir(repo)
24
25
  bundle_install!(repo)
25
26
  report = run_brakeman(repo)
26
- ui.success("Successfully executed brakeman for #{repo}")
27
+ ui.success("Successfully executed brakeman for #{repo}", print_to_audit_log: false)
27
28
  warnings = report.split("\n\n== Warnings ==\n\n").last&.split("\n\n")
28
- if !report.include?("No warnings found") && !report.blank?
29
+ if !report.include?("No warnings found") && !report.blank? && !Thread.current[:audit_mode]
29
30
  issue = client.create_issue(repo, DESCRIPTION, parse_description(warnings))
30
31
  ui.success("Issue created at #{issue.html_url}")
31
32
  end
@@ -34,6 +35,9 @@ module Neetob
34
35
  end
35
36
  end
36
37
  `rm -rf /tmp/neetob`
38
+ if Thread.current[:audit_mode]
39
+ report
40
+ end
37
41
  end
38
42
 
39
43
  private
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "./make_pr/base"
4
+ require "pry"
5
+
6
+ module Neetob
7
+ class CLI
8
+ module Github
9
+ class BundleAudit < MakePr::Base
10
+ DESCRIPTION = "Fix security vulnerabilities reported by bundle audit"
11
+ attr_accessor :repos, :sandbox
12
+
13
+ def initialize(repos, sandbox = false)
14
+ super()
15
+ @repos = repos
16
+ @sandbox = sandbox
17
+ end
18
+
19
+ def run
20
+ matching_repos = find_all_matching_apps_or_repos(repos, :github, sandbox)
21
+ report = nil
22
+ matching_repos.each do |repo|
23
+ begin
24
+ ui.info("\nWorking on repo #{repo}", print_to_audit_log: false)
25
+ clone_repo_in_tmp_dir(repo)
26
+ gemfile_path = File.join(tmp_repo_path(repo), "Gemfile")
27
+ until File.exist?(gemfile_path)
28
+ ui.info("Waiting for clone to finish", print_to_audit_log: false)
29
+ sleep(1)
30
+ end
31
+ bundle_install!(repo)
32
+ report = run_bundle_audit(repo)
33
+ ui.success("Successfully executed bundle audit for #{repo}", print_to_audit_log: false)
34
+ rescue StandardError => e
35
+ ExceptionHandler.new(e).process
36
+ end
37
+ end
38
+ `rm -rf /tmp/neetob`
39
+ if Thread.current[:audit_mode]
40
+ report
41
+ end
42
+ end
43
+
44
+ private
45
+
46
+ def run_bundle_audit(repo)
47
+ `#{cd_to_repo(repo)} & rbenv local 3.3.5 & bundle-audit check`
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -19,8 +19,12 @@ module Neetob
19
19
 
20
20
  private
21
21
 
22
- def bundle_install!(repo, local_repo)
23
- execute_command!("#{cd_to_repo(repo, local_repo)} && bundle install")
22
+ def bundle_install!(repo, local_repo = false)
23
+ execute_command!("#{cd_to_repo(repo, local_repo)} & rbenv local 3.3.5 & bundle install")
24
+ end
25
+
26
+ def yarn_install!(repo, local_repo = false)
27
+ execute_command!("#{cd_to_repo(repo, local_repo)} & yarn install")
24
28
  end
25
29
 
26
30
  def delete_and_create_temp_neetob_dir
@@ -42,6 +46,10 @@ module Neetob
42
46
  `git clone --quiet git@github.com:#{repo}.git /tmp/neetob/#{repo_name_without_org_suffix(repo)}`
43
47
  end
44
48
 
49
+ def tmp_repo_path(repo)
50
+ "/tmp/neetob/#{repo_name_without_org_suffix(repo)}"
51
+ end
52
+
45
53
  def add_commmit_and_push_changes!(repo, local_repo = false)
46
54
  create_commit!(repo, local_repo)
47
55
  push_changes!(repo, local_repo)
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../base"
4
+
5
+ module Neetob
6
+ class CLI
7
+ module Github
8
+ module Repositories
9
+ class GetSecurityDetails < Base
10
+ attr_accessor :repos, :sandbox
11
+
12
+ def initialize(repos, sandbox = false)
13
+ super()
14
+ @repos = repos
15
+ @sandbox = sandbox
16
+ end
17
+
18
+ def run
19
+ matching_repos = find_all_matching_apps_or_repos(repos, :github, sandbox)
20
+ data = []
21
+ matching_repos.each do |repo|
22
+ begin
23
+ uri = URI("https://api.github.com/repos/#{repo}/code-security-configuration")
24
+ request = Net::HTTP::Get.new(uri)
25
+ headers = {
26
+ "Accept" => "application/vnd.github+json",
27
+ "Authorization" => "Bearer #{@access_token}"
28
+ }
29
+ headers.each { |key, value| request[key] = value }
30
+
31
+ response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == "https") do |http|
32
+ http.request(request)
33
+ end
34
+ JSON.parse(response.body, symbolize_names: true)
35
+ rescue StandardError => e
36
+ ExceptionHandler.new(e).process
37
+ end
38
+ end
39
+ data
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../base"
4
+
5
+ module Neetob
6
+ class CLI
7
+ module Github
8
+ module Repositories
9
+ class PullRequests < Base
10
+ attr_accessor :repos, :sandbox
11
+
12
+ def initialize(repos, sandbox = false)
13
+ super()
14
+ @repos = repos
15
+ @sandbox = sandbox
16
+ end
17
+
18
+ def run
19
+ matching_repos = find_all_matching_apps_or_repos(repos, :github, sandbox)
20
+ data = []
21
+ matching_repos.each do |repo|
22
+ begin
23
+ data << client.pull_requests(repo)
24
+ rescue StandardError => e
25
+ ExceptionHandler.new(e).process
26
+ end
27
+ end
28
+ data
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "./make_pr/base"
4
+ require "pry"
5
+
6
+ module Neetob
7
+ class CLI
8
+ module Github
9
+ class YarnAudit < MakePr::Base
10
+ DESCRIPTION = "Fix security vulnerabilities reported by yarn audit"
11
+ attr_accessor :repos, :sandbox
12
+
13
+ def initialize(repos, sandbox = false)
14
+ super()
15
+ @repos = repos
16
+ @sandbox = sandbox
17
+ end
18
+
19
+ def run
20
+ matching_repos = find_all_matching_apps_or_repos(repos, :github, sandbox)
21
+ report = nil
22
+ matching_repos.each do |repo|
23
+ begin
24
+ ui.info("\nWorking on repo #{repo}", print_to_audit_log: false)
25
+ clone_repo_in_tmp_dir(repo)
26
+ yarn_install!(repo)
27
+ report = run_yarn_audit(repo)
28
+ ui.success("Successfully executed yarn audit for #{repo}", print_to_audit_log: false)
29
+ rescue StandardError => e
30
+ ExceptionHandler.new(e).process
31
+ end
32
+ end
33
+ `rm -rf /tmp/neetob`
34
+ if Thread.current[:audit_mode]
35
+ report
36
+ end
37
+ end
38
+
39
+ private
40
+
41
+ def run_yarn_audit(repo)
42
+ `#{cd_to_repo(repo)} && yarn audit`
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "thor"
4
+ require_relative "perform"
5
+
6
+ module Neetob
7
+ class CLI
8
+ module MonthlyAudit
9
+ class Commands < Thor
10
+ desc "perform", "Perform the audit"
11
+ option :month, type: :string, aliases: "-m", required: true, desc: "Month. Example: June-2024"
12
+
13
+ def perform
14
+ Perform.new(options[:month], options[:sandbox]).run
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "uuid_primary_key"
4
+ require_relative "users_unique_email_index"
5
+
6
+ module Neetob
7
+ class CLI
8
+ module MonthlyAudit
9
+ module Databases
10
+ class Main < CLI::Base
11
+ def initialize
12
+ super()
13
+ end
14
+
15
+ def run
16
+ ui.success("# 2. Running databases audit")
17
+ ui.info "\n"
18
+ ui.success("## 2.1. Checking whether all database tables use UUID as the primary key type")
19
+ ui.info "\n"
20
+ UuidPrimaryKey.new.run
21
+ ui.success("## 2.2. Checking whether unique email index is present for the users table")
22
+ ui.info "\n"
23
+ UsersUniqueEmailIndex.new.run
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neetob
4
+ class CLI
5
+ module MonthlyAudit
6
+ module Databases
7
+ class UsersUniqueEmailIndex < CLI::Base
8
+ def initialize
9
+ super()
10
+ end
11
+
12
+ def run
13
+ repo_data = [[
14
+ "Repository",
15
+ "User table is indexed properly",
16
+ "Comments",
17
+ "Audit Passed"
18
+ ]
19
+ ]
20
+ NeetoCompliance::NeetoRepos.products.keys.each do |repo|
21
+ ui.info "Checking #{repo}...", print_to_audit_log: false
22
+ code_audit_result = Neetob::CLI::Code::Audit.new([repo]).run[0]
23
+ if code_audit_result[:error]
24
+ repo_data << [repo, nil, code_audit_result[:error], "No"]
25
+ next
26
+ end
27
+ unique_email_index_result = code_audit_result[:unique_email_index_result]
28
+ if unique_email_index_result
29
+ repo_data << [repo, "Yes", nil, "Yes"]
30
+ else
31
+ repo_data << [repo, "No", "Unique email index is not present for the users table", "No"]
32
+ end
33
+ end
34
+ ui.print_table(repo_data)
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neetob
4
+ class CLI
5
+ module MonthlyAudit
6
+ module Databases
7
+ class UuidPrimaryKey < CLI::Base
8
+ def initialize
9
+ super()
10
+ end
11
+
12
+ def run
13
+ repo_data = [[
14
+ "Repository",
15
+ "All tables have UUID primary keys",
16
+ "Comments",
17
+ "Audit Passed"
18
+ ]
19
+ ]
20
+ NeetoCompliance::NeetoRepos.products.keys.each do |repo|
21
+ ui.info "Checking #{repo}...", print_to_audit_log: false
22
+ code_audit_result = Neetob::CLI::Code::Audit.new([repo]).run[0]
23
+ if code_audit_result[:error]
24
+ repo_data << [repo, nil, code_audit_result[:error], "No"]
25
+ next
26
+ end
27
+ tables_without_uuid = code_audit_result[:tables_without_uuid]
28
+ tables_without_uuid.reject! { |table|
29
+ table == "data_migrations" ||
30
+ table == "server_side_sessions" ||
31
+ table.include?("solid_queue") ||
32
+ table.include?("active_storage")
33
+ }
34
+ all_tables_have_uuid_primary_keys = tables_without_uuid.empty? ? "Yes" : "No"
35
+ audit_passed = all_tables_have_uuid_primary_keys == "Yes" ? "Yes" : "No"
36
+ comments = tables_without_uuid.empty? ? nil : "Tables without UUID primary keys: #{tables_without_uuid.join(', ')}"
37
+ repo_data << [repo, all_tables_have_uuid_primary_keys, comments, audit_passed]
38
+ end
39
+ ui.print_table(repo_data)
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neetob
4
+ class CLI
5
+ module MonthlyAudit
6
+ module InstancesAndAddons
7
+ module Cloudflare
8
+ class AlwaysUseHttpsIsEnabled < CLI::Base
9
+ def initialize
10
+ super()
11
+ end
12
+
13
+ def run
14
+ ui.success "### 3.2.4. Checking whether always use HTTPS is enabled"
15
+
16
+ domains_data = [["Domain", "Always use HTTPS", "Audit Passed"]]
17
+ ui.info("\n", print_to_audit_log: false)
18
+ Neetob::CLI::Cloudflare::Base::ZONE_IDS.keys.select { |domain|
19
+ domain.to_s.include?(".com") }.map do |domain|
20
+ ui.info("Checking Always use HTTPS value for #{domain}", print_to_audit_log: false)
21
+ always_use_https_value = Neetob::CLI::Cloudflare::AlwaysUseHttps.new(domain).run
22
+ audit_passed = always_use_https_value.to_s == "on" ? "Yes" : "No"
23
+ domains_data << [domain, always_use_https_value, audit_passed]
24
+ end
25
+ ui.print_table(domains_data)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neetob
4
+ class CLI
5
+ module MonthlyAudit
6
+ module InstancesAndAddons
7
+ module Cloudflare
8
+ class BotProtectionEnabled < CLI::Base
9
+ def initialize
10
+ super()
11
+ end
12
+
13
+ def run
14
+ ui.success "### 3.2.6. Checking whether Bot Protection is enabled"
15
+
16
+ domains_data = [["Domain", "Bot protection", "Audit Passed"]]
17
+ ui.info("\n", print_to_audit_log: false)
18
+ Neetob::CLI::Cloudflare::Base::ZONE_IDS.keys.select { |domain|
19
+ domain.to_s.include?(".com") }.map do |domain|
20
+ bot_fight_mode = Neetob::CLI::Cloudflare::BotFightMode.new(domain).run
21
+ ui.info("Checking Bot fight mode for #{domain}", print_to_audit_log: false)
22
+ audit_passed = bot_fight_mode == "on" ? "Yes" : "No"
23
+ domains_data << [domain, bot_fight_mode, audit_passed]
24
+ end
25
+ ui.print_table(domains_data)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Neetob
4
+ class CLI
5
+ module MonthlyAudit
6
+ module InstancesAndAddons
7
+ module Cloudflare
8
+ class DnsEntryHasProxyStatus < CLI::Base
9
+ def initialize
10
+ super()
11
+ end
12
+
13
+ def run
14
+ ui.success "### 3.2.2. Checking whether DNS entry has proxy status"
15
+
16
+ domains_data = [["Domain", "DNS proxy status", "Audit Passed"]]
17
+ ui.info("\n", print_to_audit_log: false)
18
+ Neetob::CLI::Cloudflare::Base::ZONE_IDS.keys.select { |domain|
19
+ domain.to_s.include?(".com") }.map do |domain|
20
+ ui.info("Checking proxy status for DNS entries for #{domain}", print_to_audit_log: false)
21
+ domain = domain.to_s
22
+ proxiable_records = Neetob::CLI::Cloudflare::DnsProxyStatus.new(domain).run
23
+ record_to_check = proxiable_records.select { |record| record[:name] == "*.#{domain}" }.first
24
+ if record_to_check.nil?
25
+ domains_data << [domain, "No * records found", "No"]
26
+ else
27
+ is_wildcard_subdomain_proxied = record_to_check[:proxied]
28
+ audit_passed = is_wildcard_subdomain_proxied ? "Yes" : "No"
29
+ proxy_status = is_wildcard_subdomain_proxied ? "on" : "off"
30
+ domains_data << [domain, "#{record_to_check[:name]} has proxying turned #{proxy_status}",
31
+ audit_passed]
32
+ end
33
+ end
34
+ ui.print_table(domains_data)
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "ssl_tls_encryption_mode_set_to_full"
4
+ require_relative "dns_entry_has_proxy_status"
5
+ require_relative "minimum_tls_version_is_one_point_two"
6
+ require_relative "always_use_https_is_enabled"
7
+ require_relative "spf_records_are_valid"
8
+ require_relative "bot_protection_enabled"
9
+
10
+ module Neetob
11
+ class CLI
12
+ module MonthlyAudit
13
+ module InstancesAndAddons
14
+ module Cloudflare
15
+ class Main < CLI::Base
16
+ def initialize
17
+ super()
18
+ end
19
+
20
+ def run
21
+ SslTlsEncryptionModeSetToFull.new.run
22
+ ui.info "\n"
23
+ DnsEntryHasProxyStatus.new.run
24
+ ui.info "\n"
25
+ MinimumTlsVersionIsOnePointTwo.new.run
26
+ ui.info "\n"
27
+ AlwaysUseHttpsIsEnabled.new.run
28
+ ui.info "\n"
29
+ SpfRecordsAreValid.new.run
30
+ ui.info "\n"
31
+ BotProtectionEnabled.new.run
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end