lib/hackerone/client/report.rb in hackerone-client-0.8.0 vs lib/hackerone/client/report.rb in hackerone-client-0.9.0

- old
+ new

@@ -5,10 +5,27 @@ module HackerOne module Client class Report include ResourceHelper + STATES = %w( + new + triaged + needs-more-info + resolved + not-applicable + informative + duplicate + spam + ).map(&:to_sym).freeze + + STATES_REQUIRING_STATE_CHANGE_MESSAGE = %w( + needs-more-info + informative + duplicate + ).map(&:to_sym).freeze + def initialize(report) @report = report end def id @@ -25,10 +42,14 @@ def issue_tracker_reference_url attributes[:issue_tracker_reference_url] end + def issue_tracker_reference_id + attributes[:issue_tracker_reference_id] + end + def reporter relationships .fetch(:reporter, {}) .fetch(:data, {}) .fetch(:attributes, {}) @@ -122,9 +143,92 @@ response_body = make_post_request( "reports/#{id}/bounty_suggestions", request_body: request_body ) Activities.build(response_body) + end + + ## Idempotent: change the state of a report. See STATES for valid values. + # + # id: the ID of the report + # state: the state in which the report is to be put in + # + # returns an HackerOne::Client::Report object or raises an error if + # no report is found. + def state_change(state, message = nil) + raise ArgumentError, "state (#{state}) must be one of #{STATES}" unless STATES.include?(state) + + body = { + type: "state-change", + attributes: { + state: state + } + } + + if message + body[:attributes][:message] = message + elsif STATES_REQUIRING_STATE_CHANGE_MESSAGE.include?(state) + fail ArgumentError, "State #{state} requires a message. No message was supplied." + else + # message is in theory optional, but a value appears to be required. + body[:attributes][:message] = "" + end + + response_json = make_post_request("reports/#{id}/state_changes", request_body: body) + @report = response_json + self + end + + ## Idempotent: Add a report reference to a project + # + # id: the ID of the report + # state: value for the reference (e.g. issue number or relative path to cross-repo issue) + # + # returns an HackerOne::Client::Report object or raises an error if + # no report is found. + def add_report_reference(reference) + body = { + type: "issue-tracker-reference-id", + attributes: { + reference: reference + } + } + + response_json = make_post_request("reports/#{id}/issue_tracker_reference_id", request_body: body) + @report = response_json[:relationships][:report][:data] + self + end + + ## Idempotent: add the issue reference and put the report into the "triage" state. + # + # id: the ID of the report + # state: value for the reference (e.g. issue number or relative path to cross-repo issue) + # + # returns an HackerOne::Client::Report object or raises an error if + # no report is found. + def triage(reference) + add_report_reference(reference) + state_change(:triaged) + end + + # Add a comment to a report. By default, internal comments will be added. + # + # id: the ID of the report + # message: the content of the comment that will be created + # internal: "team only" comment (true, default) or "all participants" + def add_comment(message, internal: true) + fail ArgumentError, "message is required" if message.blank? + + body = { + type: "activity-comment", + attributes: { + message: message, + internal: internal + } + } + + response_json = make_post_request("reports/#{id}/activities", request_body: body) + HackerOne::Client::Activities.build(response_json) end def assign_to_user(name) member = program.find_member(name) _assign_to(member.user.id, :user)