hackerone-client 0.2.3 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1377da005dc1141183d4f4ea57177a64965bb471
4
- data.tar.gz: fb7c070632d9991ac75bb56e1be490dcc69e5a0e
3
+ metadata.gz: e75818c133624c27e8d5986311b1ee3c77420916
4
+ data.tar.gz: b5e846599a80125cd47137ee42176777c8bf64cb
5
5
  SHA512:
6
- metadata.gz: 10ad6494e05446c28f9cbf8901c9bc88200258679ed364ff8f8cda734fa30b0239f6907e669a4a793a63e68a83b6191479e877da0477d45addf23b59819c9a1a
7
- data.tar.gz: 9d3291ac4094b8737c98fc5404f1246ba5e2b0f1533042d9f832ca8a8d711e2959e206aab93bb18535e18fd64de76aacf83b5dadbc6309784a172f496ef5d4d5
6
+ metadata.gz: 326cfa0c38f8cd35858c386b38b4f399074766c8dc52e15ae6b2950f5222e5a9995002335edc7ef059fd4ee56760e9134828e4475d6b5cda9b913214e3f10859
7
+ data.tar.gz: ff0bd09d8cfc186b67944bfae8f569ce843a495fad3546658a79bef11fba4582969d77b39e15ed4b376823bd841709761e7e7027ce42c038f2b904378f4460f0
@@ -0,0 +1,75 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://api.hackerone.com/v1/reports/500
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Authorization:
11
+ - Basic nope=
12
+ User-Agent:
13
+ - Faraday v0.11.0
14
+ Accept-Encoding:
15
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
16
+ Accept:
17
+ - "*/*"
18
+ response:
19
+ status:
20
+ code: 500
21
+ message: Error
22
+ headers:
23
+ Date:
24
+ - Wed, 15 Feb 2017 00:50:01 GMT
25
+ Content-Type:
26
+ - application/json; charset=utf-8
27
+ Transfer-Encoding:
28
+ - chunked
29
+ Connection:
30
+ - keep-alive
31
+ Set-Cookie:
32
+ - __cfduid=123; expires=Thu, 15-Feb-18
33
+ 00:50:01 GMT; path=/; Domain=api.hackerone.com; HttpOnly
34
+ X-Request-Id:
35
+ - 345
36
+ Etag:
37
+ - W/"8dfc97642d70f82b560e989d44e19eac"
38
+ Cache-Control:
39
+ - max-age=0, private, must-revalidate
40
+ Strict-Transport-Security:
41
+ - max-age=31536000; includeSubDomains; preload
42
+ Content-Security-Policy:
43
+ - default-src 'none'; connect-src 'self' www.google-analytics.com errors.hackerone.net;
44
+ font-src 'self'; img-src 'self' data:; script-src 'self'; style-src 'self'
45
+ 'unsafe-inline'; form-action 'self'; frame-ancestors 'none'; report-uri https://errors.hackerone.net/api/30/csp-report/?sentry_key=123
46
+ X-Content-Type-Options:
47
+ - nosniff
48
+ X-Download-Options:
49
+ - noopen
50
+ X-Frame-Options:
51
+ - DENY
52
+ X-Permitted-Cross-Domain-Policies:
53
+ - none
54
+ X-Xss-Protection:
55
+ - 1; mode=block
56
+ Public-Key-Pins-Report-Only:
57
+ - pin-sha256="WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18="; pin-sha256="r/mIkG3eEpVdm+u/ko/cwxzOMo1bk4TyHIlByibiA5E=";
58
+ pin-sha256="K87oWBWM9UZfyddvDfoxL+8lpNyoUB2ptGtn0fv6G2Q="; pin-sha256="iie1VXtL7HzAMF+/PVPR9xzT80kQxdZeJ+zduCB3uj0=";
59
+ pin-sha256="cGuxAXyFXFkWm61cF4HPWX8S0srS9j0aSqN0k4AP+4A="; pin-sha256="bIlWcjiKq1mftH/xd7Hw1JO77Cr+Gv+XYcGUQWwO+A4=";
60
+ pin-sha256="tXD+dGAP8rGY4PW1be90cOYEwg7pZ4G+yPZmIZWPTSg="; max-age=600; includeSubDomains;
61
+ report-uri="https://hackerone.report-uri.io/r/default/hpkp/reportOnly"
62
+ Server:
63
+ - cloudflare-nginx
64
+ Cf-Ray:
65
+ - 3314c3653e302126-LAX
66
+ body:
67
+ encoding: ASCII-8BIT
68
+ string: '{
69
+ "data": {
70
+ "error": "fail"
71
+ }
72
+ }'
73
+ http_version:
74
+ recorded_at: Wed, 15 Feb 2017 00:50:01 GMT
75
+ recorded_with: VCR 3.0.3
@@ -2,6 +2,7 @@ require "faraday"
2
2
  require 'active_support/time'
3
3
  require_relative "client/version"
4
4
  require_relative "client/report"
5
+ require_relative "client/activity"
5
6
 
6
7
  module HackerOne
7
8
  module Client
@@ -21,7 +22,13 @@ module HackerOne
21
22
  informative
22
23
  duplicate
23
24
  spam
24
- ).map(&:to_sym)
25
+ ).map(&:to_sym).freeze
26
+
27
+ STATES_REQUIRING_STATE_CHANGE_MESSAGE = %w(
28
+ needs-more-info
29
+ informative
30
+ duplicate
31
+ ).map(&:to_sym).freeze
25
32
 
26
33
  class << self
27
34
  ATTRS = [:low_range, :medium_range, :high_range, :critical_range].freeze
@@ -111,18 +118,23 @@ module HackerOne
111
118
  #
112
119
  # returns an HackerOne::Client::Report object or raises an error if
113
120
  # no report is found.
114
- def state_change(id, state)
121
+ def state_change(id, state, message = nil)
115
122
  raise ArgumentError, "state (#{state}) must be one of #{STATES}" unless STATES.include?(state)
116
123
 
117
124
  body = {
118
125
  data: {
119
126
  type: "state-change",
120
127
  attributes: {
121
- message: "This is has been triaged internally.",
122
128
  state: state
123
129
  }
124
130
  }
125
131
  }
132
+
133
+ if message
134
+ body[:message] = message
135
+ elsif STATES_REQUIRING_STATE_CHANGE_MESSAGE.include?(state)
136
+ fail ArgumentError, "State #{state} requires a message. No message was supplied."
137
+ end
126
138
  post("reports/#{id}/state_changes", body)
127
139
  end
128
140
 
@@ -165,7 +177,7 @@ module HackerOne
165
177
  if response.status.to_s.start_with?("4")
166
178
  raise ArgumentError, "API called failed, probably your fault: #{response.body}"
167
179
  elsif response.status.to_s.start_with?("5")
168
- raise Runtime, "API called failed, probobly their fault: #{response.body}"
180
+ raise RuntimeError, "API called failed, probably their fault: #{response.body}"
169
181
  elsif response.success?
170
182
  Report.new(JSON.parse(response.body, :symbolize_names => true)[:data])
171
183
  else
@@ -0,0 +1,72 @@
1
+ module HackerOne
2
+ module Client
3
+ module Activities
4
+ class Activity
5
+ delegate :message, :created_at, :updated_at, to: :attributes
6
+ delegate :actor, to: :relationships
7
+
8
+ def initialize(activity)
9
+ @activity = OpenStruct.new activity
10
+ end
11
+
12
+ def internal?
13
+ attributes.internal
14
+ end
15
+
16
+ private
17
+
18
+ def relationships
19
+ OpenStruct.new(activity.relationships)
20
+ end
21
+
22
+ def attributes
23
+ OpenStruct.new(activity.attributes)
24
+ end
25
+
26
+ attr_reader :activity
27
+ end
28
+
29
+ class BountyAwarded < Activity
30
+ def bounty_amount
31
+ formatted_bounty_amount = attributes.bounty_amount || "0"
32
+ formatted_bounty_amount.gsub(/[^\d]/, "").to_i
33
+ end
34
+
35
+ def bonus_amount
36
+ formatted_bonus_amount = attributes.bonus_amount || "0"
37
+ formatted_bonus_amount.gsub(/[^\d]/, "").to_i
38
+ end
39
+ end
40
+
41
+ class SwagAwarded < Activity
42
+ delegate :swag, to: :relationships
43
+ end
44
+
45
+ class UserAssignedToBug < Activity
46
+ delegate :assigned_user, to: :relationships
47
+ end
48
+
49
+ class BugTriaged < Activity
50
+ end
51
+
52
+ class ReferenceIdAdded < Activity
53
+ delegate :reference, :reference_url, to: :attributes
54
+ end
55
+
56
+ ACTIVITY_TYPE_CLASS_MAPPING = {
57
+ 'activity-bounty-awarded' => BountyAwarded,
58
+ 'activity-swag-awarded' => SwagAwarded,
59
+ 'activity-user-assigned-to-bug' => UserAssignedToBug,
60
+ 'activity-bug-triaged' => BugTriaged,
61
+ 'activity-reference-id-added' => ReferenceIdAdded
62
+ }.freeze
63
+
64
+ def self.build(activity_data)
65
+ activity_type_class = ACTIVITY_TYPE_CLASS_MAPPING.fetch \
66
+ activity_data[:type], Activity
67
+
68
+ activity_type_class.new activity_data
69
+ end
70
+ end
71
+ end
72
+ end
@@ -1,10 +1,9 @@
1
1
  require_relative './weakness'
2
+ require_relative './activity'
2
3
 
3
4
  module HackerOne
4
5
  module Client
5
6
  class Report
6
- PAYOUT_ACTIVITY_KEY = "activity-bounty-awarded"
7
-
8
7
  def initialize(report)
9
8
  @report = report
10
9
  end
@@ -68,17 +67,20 @@ module HackerOne
68
67
  classification_label().split("-").first
69
68
  end
70
69
 
70
+ def activities
71
+ relationships.dig(:activities, :data)&.map do |activity_data|
72
+ Activities.build(activity_data)
73
+ end
74
+ end
75
+
71
76
  private
77
+
72
78
  def payments
73
- activities.select { |activity| activity[:type] == PAYOUT_ACTIVITY_KEY }
79
+ activities.select { |activity| activity.is_a? Activities::BountyAwarded }
74
80
  end
75
81
 
76
82
  def payment_amount(payment)
77
- payment.fetch(:attributes, {}).fetch(:bounty_amount, "0").gsub(/[^\d]/, "").to_i
78
- end
79
-
80
- def activities
81
- relationships.fetch(:activities, {}).fetch(:data, [])
83
+ payment.bounty_amount
82
84
  end
83
85
 
84
86
  def attributes
@@ -1,5 +1,5 @@
1
1
  module Hackerone
2
2
  module Client
3
- VERSION = "0.2.3"
3
+ VERSION = "0.3.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hackerone-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Neil Matatall
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-03-22 00:00:00.000000000 Z
11
+ date: 2017-03-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -137,9 +137,11 @@ files:
137
137
  - fixtures/vcr_cassettes/missing_report.yml
138
138
  - fixtures/vcr_cassettes/report.yml
139
139
  - fixtures/vcr_cassettes/report_list.yml
140
+ - fixtures/vcr_cassettes/server_error.yml
140
141
  - fixtures/vcr_cassettes/stage_change.yml
141
142
  - hackerone-client.gemspec
142
143
  - lib/hackerone/client.rb
144
+ - lib/hackerone/client/activity.rb
143
145
  - lib/hackerone/client/report.rb
144
146
  - lib/hackerone/client/version.rb
145
147
  - lib/hackerone/client/weakness.rb