hackerone-client 0.15.0 → 0.20.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,6 @@
1
- require_relative './resource_helper'
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "./resource_helper"
2
4
 
3
5
  module HackerOne
4
6
  module Client
@@ -71,7 +73,7 @@ module HackerOne
71
73
  "programs/#{id}/swag",
72
74
  params: { page: { number: page_number, size: page_size } }
73
75
  )
74
- response_body.map{|r| Swag.new(r, self) }
76
+ response_body.map { |r| Swag.new(r, self) }
75
77
  end
76
78
 
77
79
  private
@@ -1,6 +1,8 @@
1
- require_relative './resource_helper'
2
- require_relative './weakness'
3
- require_relative './activity'
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "./resource_helper"
4
+ require_relative "./weakness"
5
+ require_relative "./activity"
4
6
 
5
7
  module HackerOne
6
8
  module Client
@@ -24,6 +26,22 @@ module HackerOne
24
26
  duplicate
25
27
  ).map(&:to_sym).freeze
26
28
 
29
+ RESOLVED_STATES = %w(
30
+ resolved
31
+ not-applicable
32
+ informative
33
+ duplicate
34
+ spam
35
+ ).map(&:to_sym).freeze
36
+
37
+ SEVERITY_RATINGS = %w(
38
+ none
39
+ low
40
+ medium
41
+ high
42
+ critical
43
+ ).freeze
44
+
27
45
  class << self
28
46
  def add_on_state_change_hook(proc)
29
47
  on_state_change_hooks << proc
@@ -62,6 +80,10 @@ module HackerOne
62
80
  attributes[:issue_tracker_reference_id]
63
81
  end
64
82
 
83
+ def severity
84
+ attributes[:severity]
85
+ end
86
+
65
87
  def state
66
88
  attributes[:state]
67
89
  end
@@ -118,7 +140,13 @@ module HackerOne
118
140
 
119
141
  # Bounty writeups just use the key, and not the label value.
120
142
  def writeup_classification
121
- classification_label().split("-").first
143
+ classification_label.split("-").first
144
+ end
145
+
146
+ def attachments
147
+ @attachments ||= relationships.fetch(:attachments, {})
148
+ .fetch(:data, [])
149
+ .map { |attachment| HackerOne::Client::Attachment.new(attachment) }
122
150
  end
123
151
 
124
152
  def activities
@@ -159,6 +187,23 @@ module HackerOne
159
187
  Swag.new(response_body, program)
160
188
  end
161
189
 
190
+ def update_severity(rating:)
191
+ raise ArgumentError, "Invalid severity rating" unless SEVERITY_RATINGS.include?(rating.to_s)
192
+
193
+ request_body = {
194
+ type: "severity",
195
+ attributes: {
196
+ rating: rating
197
+ }
198
+ }
199
+ response_body = make_post_request(
200
+ "reports/#{id}/severities",
201
+ request_body: request_body
202
+ )
203
+ @report[:attributes][:severity] = { rating: rating }
204
+ Activities.build(response_body)
205
+ end
206
+
162
207
  def suggest_bounty(message:, amount:, bonus_amount: nil)
163
208
  request_body = {
164
209
  message: message,
@@ -261,6 +306,19 @@ module HackerOne
261
306
  HackerOne::Client::Activities.build(response_json)
262
307
  end
263
308
 
309
+ def lock!
310
+ unless RESOLVED_STATES.include? self.state.to_sym
311
+ raise ArgumentError, "Report must be closed before locking"
312
+ end
313
+
314
+ body = {
315
+ type: "activity-comments-closed"
316
+ }
317
+
318
+ response_json = make_put_request("reports/#{id}/close_comments", request_body: body)
319
+ HackerOne::Client::Activities.build(response_json)
320
+ end
321
+
264
322
  def assign_to_user(name)
265
323
  member = program.find_member(name)
266
324
  _assign_to(member.user.id, :user)
@@ -304,7 +362,7 @@ module HackerOne
304
362
  request_body[:id] = assignee_id if assignee_id
305
363
 
306
364
  response = HackerOne::Client::Api.hackerone_api_connection.put do |req|
307
- req.headers['Content-Type'] = 'application/json'
365
+ req.headers["Content-Type"] = "application/json"
308
366
  req.url "reports/#{id}/assignee"
309
367
  req.body = { data: request_body }.to_json
310
368
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HackerOne
2
4
  module Client
3
5
  class Reporter
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HackerOne
2
4
  module Client
3
5
  module ResourceHelper
@@ -14,7 +16,7 @@ module HackerOne
14
16
 
15
17
  def make_put_request(url, request_body:, extract_data: true)
16
18
  response = HackerOne::Client::Api.hackerone_api_connection.put do |req|
17
- req.headers['Content-Type'] = 'application/json'
19
+ req.headers["Content-Type"] = "application/json"
18
20
  req.url url
19
21
  req.body = { data: request_body }.to_json
20
22
  end
@@ -24,7 +26,7 @@ module HackerOne
24
26
 
25
27
  def make_post_request(url, request_body:, extract_data: true)
26
28
  response = HackerOne::Client::Api.hackerone_api_connection.post do |req|
27
- req.headers['Content-Type'] = 'application/json'
29
+ req.headers["Content-Type"] = "application/json"
28
30
  req.url url
29
31
  req.body = { data: request_body }.to_json
30
32
  end
@@ -34,7 +36,7 @@ module HackerOne
34
36
 
35
37
  def make_get_request(url, params: {}, extract_data: true)
36
38
  response = HackerOne::Client::Api.hackerone_api_connection.get do |req|
37
- req.headers['Content-Type'] = 'application/json'
39
+ req.headers["Content-Type"] = "application/json"
38
40
  req.url url
39
41
  req.params = params
40
42
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HackerOne
2
4
  module Client
3
5
  class StructuredScope
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HackerOne
2
4
  module Client
3
5
  class Swag
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HackerOne
2
4
  module Client
3
5
  class User
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Hackerone
2
4
  module Client
3
- VERSION = "0.15.0"
5
+ VERSION = "0.20.0"
4
6
  end
5
7
  end
@@ -1,17 +1,19 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HackerOne
2
4
  module Client
3
5
  class Weakness
4
6
  class << self
5
7
  def validate_cwe!(cwe)
6
- fail NotAnOwaspWeaknessError if cwe.upcase.start_with?('CAPEC-')
7
- fail StandardError::ArgumentError unless cwe.upcase.start_with?('CWE-')
8
+ fail NotAnOwaspWeaknessError if cwe.upcase.start_with?("CAPEC-")
9
+ fail StandardError::ArgumentError unless cwe.upcase.start_with?("CWE-")
8
10
  end
9
11
 
10
12
  def extract_cwe_number(cwe)
11
13
  return if cwe.nil?
12
14
  validate_cwe!(cwe)
13
15
 
14
- cwe.split('CWE-').last.to_i
16
+ cwe.split("CWE-").last.to_i
15
17
  end
16
18
  end
17
19
 
@@ -39,20 +41,20 @@ module HackerOne
39
41
  }
40
42
 
41
43
  OWASP_TOP_10_2013_TO_CWE = {
42
- 'A1-Injection' => [77, 78, 88, 89, 90, 91, 564],
43
- 'A2-AuthSession' =>
44
+ "A1-Injection" => [77, 78, 88, 89, 90, 91, 564],
45
+ "A2-AuthSession" =>
44
46
  [287, 613, 522, 256, 384, 472, 346, 441, 523, 620, 640, 319, 311],
45
- 'A3-XSS' => [79],
46
- 'A4-DirectObjRef' => [639, 99, 22],
47
- 'A5-Misconfig' => [16, 2, 215, 548, 209],
48
- 'A6-DataExposure' => [312, 319, 310, 326, 320, 311, 325, 328, 327],
49
- 'A7-MissingACL' => [285, 287],
50
- 'A8-CSRF' => [352, 642, 613, 346, 441],
51
- 'A9-KnownVuln' => [],
52
- 'A10-Redirects' => [601],
47
+ "A3-XSS" => [79],
48
+ "A4-DirectObjRef" => [639, 99, 22],
49
+ "A5-Misconfig" => [16, 2, 215, 548, 209],
50
+ "A6-DataExposure" => [312, 319, 310, 326, 320, 311, 325, 328, 327],
51
+ "A7-MissingACL" => [285, 287],
52
+ "A8-CSRF" => [352, 642, 613, 346, 441],
53
+ "A9-KnownVuln" => [],
54
+ "A10-Redirects" => [601],
53
55
  }.freeze
54
56
 
55
- OWASP_DEFAULT = 'A0-Other'.freeze
57
+ OWASP_DEFAULT = "A0-Other".freeze
56
58
 
57
59
  def initialize(weakness)
58
60
  @attributes = weakness
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.15.0
4
+ version: 0.20.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: 2020-03-09 00:00:00.000000000 Z
11
+ date: 2021-01-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -118,6 +118,7 @@ files:
118
118
  - ".github/workflows/build.yml"
119
119
  - ".gitignore"
120
120
  - ".rspec"
121
+ - ".rubocop.yml"
121
122
  - ".travis.yml"
122
123
  - CHANGELOG.md
123
124
  - CODE_OF_CONDUCT.md
@@ -141,12 +142,16 @@ files:
141
142
  - fixtures/vcr_cassettes/award_a_bounty.yml
142
143
  - fixtures/vcr_cassettes/award_swag.yml
143
144
  - fixtures/vcr_cassettes/common_responses.yml
145
+ - fixtures/vcr_cassettes/create_report.yml
146
+ - fixtures/vcr_cassettes/create_report_invalid.yml
144
147
  - fixtures/vcr_cassettes/dup.yml
145
148
  - fixtures/vcr_cassettes/empty_report_list.yml
149
+ - fixtures/vcr_cassettes/lock_report.yml
146
150
  - fixtures/vcr_cassettes/missing_report.yml
147
151
  - fixtures/vcr_cassettes/programs.yml
148
152
  - fixtures/vcr_cassettes/report.yml
149
153
  - fixtures/vcr_cassettes/report_list.yml
154
+ - fixtures/vcr_cassettes/report_list_triaged.yml
150
155
  - fixtures/vcr_cassettes/reporters.yml
151
156
  - fixtures/vcr_cassettes/server_error.yml
152
157
  - fixtures/vcr_cassettes/server_error_when_assigning_report_to_user.yml
@@ -158,11 +163,13 @@ files:
158
163
  - fixtures/vcr_cassettes/traverse_through_all_activities.yml
159
164
  - fixtures/vcr_cassettes/triage_and_hook_assign_report_to_user.yml
160
165
  - fixtures/vcr_cassettes/update_policy.yml
166
+ - fixtures/vcr_cassettes/update_severity.yml
161
167
  - fixtures/vcr_cassettes/user_find_fransrosen.yml
162
168
  - hackerone-client.gemspec
163
169
  - lib/hackerone/client.rb
164
170
  - lib/hackerone/client/activity.rb
165
171
  - lib/hackerone/client/address.rb
172
+ - lib/hackerone/client/attachment.rb
166
173
  - lib/hackerone/client/bounty.rb
167
174
  - lib/hackerone/client/group.rb
168
175
  - lib/hackerone/client/incremental/activities.rb