diff --git a/.workflow/brakeman.yml b/.workflow/brakeman.yml index e2e74724a96535866332f7a889908d27277315af..d48db6f78a87e0408fee790b26eda3ee2f1fab5e 100644 --- a/.workflow/brakeman.yml +++ b/.workflow/brakeman.yml @@ -1,10 +1,10 @@ version: '1.0' -name: rubocop-check-run-test -displayName: rubocop_check_run +name: brakeman-check-run-test +displayName: brakeman_check_run stages: - stage: '' - name: brakeman_1 - displayName: brakeman_1 + name: brakeman + displayName: brakeman steps: - step: build@ruby name: build_ruby_31 diff --git a/app/models/brakeman_analysis.rb b/app/models/brakeman_analysis.rb new file mode 100644 index 0000000000000000000000000000000000000000..8e8ccb3c7968726b00d38eac0d17c880fe024b51 --- /dev/null +++ b/app/models/brakeman_analysis.rb @@ -0,0 +1,108 @@ +require 'rest-client' +require 'json' +require 'base64' + +class BrakemanAnalysis + def initialize(repo, head_sha, bare_sha, access_token_str) + + @repo = repo + @access_token = Base64.decode64(access_token_str)[0...32] + @head_sha = head_sha + @bare_sha = bare_sha + end + + def exec + create_brakeman + initiate_check_run + end + + def create_brakeman + data = { + details_url: 'https://gitee.com/liwen', + name: 'Brakeman 安全检测', + head_sha: @head_sha + } + url = "https://gitee.com/api/v5/repos/#{@repo}/check-runs" + @response_json = RestClient.post url, data, { 'Private-Token' => @access_token } + @response = JSON.parse(@response_json) + @check_run_id = @response['id'] + puts "@check_run_id => #{@check_run_id}" + end + + def initiate_check_run + url = "https://gitee.com/api/v5/repos/#{@repo}/check-runs/#{@check_run_id}" + data = { + access_token: @access_token, + status: 'in_progress' + } + RestClient.patch url, data + + diff_paths = `git diff --name-only #{@head_sha} #{@bare_sha}` + puts "diff_paths: #{diff_paths}" + @report = `brakeman -f json --only-files #{diff_paths.split($/).join(',')}` + @output = JSON.parse @report + + annotations = [] + + if @output['errors'] == 0 + conclusion = 'success' + else + conclusion = 'success' + annotation_level_map = {"High": 'failure', "Medium": 'warning', "Weak": 'notice'} + + @output['warning'].each do |warning| + + end + start_line = end_line = warning['line'] + title = "#{warning["confidence"]} - #{warning["warning_type"]}" + message = warning["message"] + file = warning["file"] + annotation_level = annotation_level_map[warning["confidence"]] + raw_details = warning["link"] + if annotation_level == "failure" + conclusion = "failure" + elsif 'failure' != conclusion && 'warning' == annotation_level + conclusion = "neutral" + end + + annotation = { + title: title, + path: file, + start_line: start_line, + end_line: end_line, + annotation_level: annotation_level, + message: message, + raw_details: raw_details + } + annotations.push(annotation) + end + end + + summary = "Brakeman summary\n - Controllers count: #{@output['scan_info']['number_of_controllers']}\n- Models count: #{@output['scan_info']['number_of_models']}\n- Templates count: #{@output['scan_info']['number_of_templates']}\n- Security Warnings count: #{@output['scan_info']['security_warnings']}" + text = "Brakeman version: #{@output['scan_info']['brakeman_version']}\n" + + url = "https://gitee.com/api/v5/repos/#{@repo}/check-runs/#{@check_run_id}" + data = { + access_token: @access_token, + conclusion: conclusion, + details_url: "http://brakemanscanner.org/", + output: { + title: 'Brakeman安全检测', + summary: summary, + text: text, + annotations: annotations + } + } + reposponse = RestClient.patch url, data + puts "finished: #{reposponse}" + end +end + +inputted_strings = ARGV +if ARGV.empty? + puts "nothing :(" +else + repo, head_sha, bare_sha, access_token_str = inputted_strings + puts "repo: #{repo}, head_sha: #{head_sha}, bare_sha: #{bare_sha}" + BrakemanAnalysis.new(repo, head_sha, bare_sha, access_token_str).exec +end