lib/hackerone/client/report.rb in hackerone-client-0.10.0 vs lib/hackerone/client/report.rb in hackerone-client-0.11.0
- old
+ new
@@ -22,10 +22,24 @@
needs-more-info
informative
duplicate
).map(&:to_sym).freeze
+ class << self
+ def add_on_state_change_hook(proc)
+ on_state_change_hooks << proc
+ end
+
+ def clear_on_state_change_hooks
+ @on_state_change_hooks = []
+ end
+
+ def on_state_change_hooks
+ @on_state_change_hooks ||= []
+ end
+ end
+
def initialize(report)
@report = report
end
def id
@@ -46,17 +60,29 @@
def issue_tracker_reference_id
attributes[:issue_tracker_reference_id]
end
+ def state
+ attributes[:state]
+ end
+
def reporter
relationships
.fetch(:reporter, {})
.fetch(:data, {})
.fetch(:attributes, {})
end
+ def assignee
+ if assignee_relationship = relationships[:assignee]
+ HackerOne::Client::User.new(assignee_relationship[:data])
+ else
+ nil
+ end
+ end
+
def payment_total
payments.reduce(0) { |total, payment| total + payment_amount(payment) }
end
def structured_scope
@@ -155,10 +181,11 @@
# returns an HackerOne::Client::Report object or raises an error if
# no report is found.
def state_change(state, message = nil, attributes = {})
raise ArgumentError, "state (#{state}) must be one of #{STATES}" unless STATES.include?(state)
+ old_state = self.state
body = {
type: "state-change",
attributes: {
state: state
}
@@ -174,10 +201,13 @@
# 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.class.on_state_change_hooks.each do |hook|
+ hook.call(self, old_state.to_s, state.to_s)
+ end
self
end
## Idempotent: Add a report reference to a project
#
@@ -279,9 +309,11 @@
req.body = { data: request_body }.to_json
end
unless response.success?
fail("Unable to assign report #{id} to #{assignee_type} with id '#{assignee_id}'. Response status: #{response.status}, body: #{response.body}")
end
+
+ @report = parse_response response
end
end
end
end