require 'thor' require 'paraxial' require 'net/http' require 'uri' require 'json' require 'time' require 'yaml' require_relative 'helpers' module Paraxial class CLI < Thor desc 'scan', 'Run scan' option :github_app, type: :boolean, default: false, desc: 'Use GitHub app' option :install_id, type: :numeric, desc: 'GitHub App installation ID' option :repo_owner, type: :string, desc: 'Repository owner' option :repo_name, type: :string, desc: 'Repository name' option :pr_number, type: :numeric, desc: 'Pull request number' def scan puts '[Paraxial] Scan starting...' if Paraxial::Helpers.get_api_key.nil? puts '[Paraxial] Environment variable PARAXIAL_API_KEY not found' else github_app = options[:github_app] install_id = options[:install_id] repo_owner = options[:repo_owner] repo_name = options[:repo_name] pr_number = options[:pr_number] cops = 'Paraxial,Security/Eval,Security/IoMethods,Security/JSONLoad,Security/MarshalLoad,Security/Open,Security/YAMLLoad' rubocop = `rubocop --require paraxial --only #{cops} --disable-pending-cops --format json` lockfile = File.read('./Gemfile.lock') api_key = ENV['PARAXIAL_API_KEY'] uri = URI.parse(Paraxial::Helpers.get_paraxial_url + '/api/ruby_scan') headers = { 'Content-Type': 'application/json' } body = { rubocop: rubocop, lockfile: lockfile, api_key: api_key, timestamp: Paraxial.get_timestamp } response = Net::HTTP.post(uri, body.to_json, headers) m = JSON.parse(response.body) findings = m['ok']['findings'] puts puts "[Paraxial] Scan count #{findings.length}" puts findings.each do |finding| puts finding puts end puts "[Paraxial] Scan UUID #{m['ok']['scan_uuid']}" puts "[Paraxial] Scan URL #{m['ok']['scan_url']}" github_valid = (!!github_app and !!install_id and !!repo_owner and !!repo_name and !!pr_number) if github_app and github_valid == false puts '[Paraxial] --github_app missing arguments' puts '[Paraxial] Required: --github_app, --install_id, --repo_owner, --repo_name, --pr_number' elsif github_app and github_valid # uuid_regex = /UUID\s+(\S+)/ # match = response.body.match(uuid_regex) # uuid = match[1] if match uuid = m['ok']['scan_uuid'] if uuid final_uuid = uuid.chomp('.') censored_backend_map = { 'installation_id' => install_id, 'repository_owner' => repo_owner, 'repository_name' => repo_name, 'pull_request_number' => pr_number, 'scan_uuid' => final_uuid, 'api_key' => 'REDACTED' } cbms = JSON.pretty_generate(censored_backend_map) puts "[Paraxial] GitHub hash: #{cbms}" censored_backend_map['api_key'] = api_key backend_map = censored_backend_map parax_uri = URI.parse(Paraxial::Helpers.get_paraxial_url + '/api/github_app') github_pr_url = "https://github.com/#{repo_owner}/#{repo_name}/pull/#{pr_number}" rr = Net::HTTP.post(parax_uri, backend_map.to_json, headers) puts "[Paraxial] parax_uri response: #{rr.body}" puts "[Paraxial] #{github_pr_url}" else puts '[Paraxial] No scan UUID found' end else :ok end end end end end